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.21k stars 1.35k forks source link

Discrepancy between build.cmd and IDE build #5999

Open KirillOsenkov opened 3 years ago

KirillOsenkov commented 3 years ago

When I type build.cmd to build the MSBuild repo on Windows it ends up with this command line:

/m /nologo /clp:Summary /v:minimal /nr:True /p:ContinuousIntegrationBuild=False /warnaserror /p:TreatWarningsAsErrors=true "C:\Users\kirill\.nuget\packages\microsoft.dotnet.arcade.sdk\1.0.0-beta.20580.3\tools\Build.proj" "/bl:C:\msbuild\artifacts\log\Debug\Build.binlog" "/p:Configuration=Debug" "/p:RepoRoot=C:\msbuild" "/p:Restore=True" "/p:DeployDeps=False" "/p:Build=True" "/p:Rebuild=False" "/p:Deploy=False" "/p:Test=False" "/p:Pack=False" "/p:IntegrationTest=False" "/p:PerformanceTest=False" "/p:Sign=False" "/p:Publish=False""

When I open MSBuild.Dev.sln in Visual Studio, some of these properties are not set, so the in-IDE behavior is slightly different. Specifically, projects always rebuild even if nothing has changed: this file: C:\msbuild\artifacts\obj\Microsoft.Build.Framework\Debug\net472\Microsoft.Build.Framework.AssemblyInfo.cs has an extra attribute ([assembly: System.Reflection.AssemblyMetadataAttribute("RepositoryUrl", "https://github.com/microsoft/msbuild")]) compared to the command-line build. It gets added because of a different default (GenerateRepositoryUrlAttribute = true in the IDE builds).

I think the default behavior for build.cmd should match as closely as possible the defaults picked by the build if you just do msbuild /r /m /bl with no extra properties. This way opening the solution in the IDE will result in the same builds instead of flip-flopping and competing with the command-line build and breaking incrementality.

KirillOsenkov commented 3 years ago

Actually I think this is because the difference is resolved SDK (3.1 in command-line case vs. 5.0 in the IDE case). 5.0 added a new attribute, so depending on which SDK you're using to build you'll get a different set of generated attributes in the AssemblyInfo.cs.

I think we can close this one then (it is expected that if you use different SDKs you might get slight discrepancies between builds like this).

KirillOsenkov commented 3 years ago

Turns out I had to set these environment variables to replicate the behavior of resolving 3.1.100:

PATH=C:\msbuild\.dotnet;%PATH%
DOTNET_INSTALL_DIR=C:\msbuild\.dotnet
DOTNET_MULTILEVEL_LOOKUP=0

Is there a file equivalent of setting these (such as an .rsp file?) so that the behavior we get in VS is identical to the build.cmd behavior?

The workaround is to set the two environment variables and open VS from that prompt to inherit that environment. Otherwise you'll keep getting little discrepancies as a result of vanilla VS choosing a different SDK.

KirillOsenkov commented 3 years ago

I've also filed https://github.com/dotnet/sdk/issues/15149 because I literally spent whole day on this issue.

rainersigwald commented 3 years ago

I think the ideal solution would be https://github.com/dotnet/sdk/issues/8254.

FYI @KathleenDollard -- here's another global.json-adjacent thing that would be made worse by ignoring it.

KirillOsenkov commented 1 year ago

Sigh, I keep wasting time on this, doing the same investigation over and over. After a few months I forget about this and start the whole investigation from scratch, and always come back to this issue.