dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.24k stars 1.35k forks source link

Solution-Level Project Dependencies require framework compatibility between projects in metaproj #1915

Closed jkoritzinsky closed 6 years ago

jkoritzinsky commented 7 years ago

If you build a VS solution that has project dependencies outside of project references from the command line with MSBuild, the metaproj requires that the two projects have compatible frameworks. Sometimes this is not desirable (i.e. building a tool used to codegen before building projects that use the generated code). I have an example that has a .NET Core project that has a Project Dependency on a .NET 4.5 project. It builds successfully in VS, but command line MSBuild fails with the following:

"C:\Users\jkori\OneDrive\Documents\Visual Studio 2017\Projects\MetaProjectSolutionDependencies\MetaProjectSolutionDepen
dencies.sln" (default target) (1) ->
"C:\Users\jkori\OneDrive\Documents\Visual Studio 2017\Projects\MetaProjectSolutionDependencies\NetCore\NetCore.csproj.m
etaproj" (default target) (2) ->
"C:\Users\jkori\OneDrive\Documents\Visual Studio 2017\Projects\MetaProjectSolutionDependencies\NetCore\NetCore.csproj"
(default target) (4) ->
"C:\Users\jkori\OneDrive\Documents\Visual Studio 2017\Projects\MetaProjectSolutionDependencies\NetFramework\NetFramewor
k.csproj" (GetTargetFrameworkProperties target) (3:2) ->
(GetTargetFrameworkProperties target) ->
  C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.
Common.targets(73,5): error : Project 'C:\Users\jkori\OneDrive\Documents\Visual Studio 2017\Projects\MetaProjectSolutio
nDependencies\NetFramework\NetFramework.csproj' targets '.NETFramework,Version=v4.5'. It cannot be referenced by a proj
ect that targets '.NETCoreApp,Version=v1.1'. [C:\Users\jkori\OneDrive\Documents\Visual Studio 2017\Projects\MetaProject
SolutionDependencies\NetFramework\NetFramework.csproj]

    0 Warning(s)
    1 Error(s)
elbertcastaneda commented 7 years ago

I have the same error

rainersigwald commented 7 years ago

From @onovotny

This is with 15.3p2 and the .NET Core 2 preview 1 tooling.

I have a solution where one project, that targets netstandard1.1 and net45 needs the binary output of a project that has a netcoreapp2.0 and net46 exe (for including in a package).

There is no project reference dependency in the csproj. In the solution file, I have a build dependency set instead. The build works fine in VS but fails on the command line if I try to build the solution file:

C:\Program Files\dotnet\sdk\2.0.0-preview1-005977\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.Common.targets(77,5): e
rror : Project 'C:\dev\refit\InterfaceStubGenerator\InterfaceStubGenerator.csproj' targets '.NETFramework,Version=v4.6;
.NETCoreApp,Version=v2.0'. It cannot be referenced by a project that targets '.NETStandard,Version=v1.4'. [C:\dev\refit\
InterfaceStubGenerator\InterfaceStubGenerator.csproj]
C:\Program Files\dotnet\sdk\2.0.0-preview1-005977\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.Common.targets(77,5): e
rror : Project 'C:\dev\refit\InterfaceStubGenerator\InterfaceStubGenerator.csproj' targets '.NETFramework,Version=v4.6;
.NETCoreApp,Version=v2.0'. It cannot be referenced by a project that targets '.NETFramework,Version=v4.5'. [C:\dev\refit
\InterfaceStubGenerator\InterfaceStubGenerator.csproj]
C:\Program Files\dotnet\sdk\2.0.0-preview1-005977\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.targets(94,5): error :
Cannot find project info for 'C:\dev\refit\InterfaceStubGenerator\InterfaceStubGenerator.csproj'. This can indicate a mi
ssing project reference. [C:\dev\refit\Refit.Tests\Refit.Tests.csproj]
    116 Warning(s)
    3 Error(s)

If I build the csproj files directly, it works. The build system should not be evaluating project TFM compatibility based on solution file build dependencies.

Repro: Clone https://github.com/paulcbetts/ checkout branch netcore2 (commit 9a3ef09bf710eb736ec3c924ec00ba8f569577c0)

From cmd line:

  1. msbuild /t:restore .\Refit.sln
  2. msbuild /t:build .\Refit.sln (fails)
  3. git clean -xdf
  4. msbuild /t:restore .\Refit.sln
  5. msbuild /t:build .\Refit\Refit.csproj (succeeds)

Copied from original issue: https://github.com/dotnet/sdk/issues/1343

mdekrey commented 6 years ago

Added a simple repro repository https://github.com/mdekrey/MsbuildProjectDependencyIssue.

dasMulli commented 6 years ago

@rainersigwald I suppose this should be fixed with https://github.com/Microsoft/msbuild/pull/2867 ?

rainersigwald commented 6 years ago

Yes, it should be fixed with #2867. Confirmed with @mdekrey's repro.

mdekrey commented 6 years ago

Since #2867 was reverted, should this be reopened? I'm still blocked with my use-case (dependencies such as JSON API files, etc.), but maybe I don't see how to use the workaround mentioned.

rainersigwald commented 6 years ago

Yeah, we can fix this separately from the general fix for #2661.

@mdekrey Have you tried this workaround? That should work today (and hopefully not cause trouble when a real fix comes in). In your example repro it would go in MsbuildFrameworkProject.csproj.

mdekrey commented 6 years ago

Thanks @rainersigwald - I hadn't seen that specific workaround! It looks like it works like a charm.

Edit: Actually, no, unfortunately it doesn't fix my situation. Specifically, as part of some of those projects, I generate additional outputs (JSON API files) that are used, though the ultimate C# DLLs are not directly used by the "synthetic" dependencies. This workaround prevents the reference... but it also ignores the build order. I'll either need this one fixed, or continue using msbuild in a few stages.

rainersigwald commented 6 years ago

@mdekrey I don't think I understand what went wrong when you tried AddSyntheticProjectReferencesForSolutionDependencies.

This workaround prevents the reference... but it also ignores the build order.

That shouldn't be the case. Can you elaborate, or update your example solution to replicate the problem?