Sdk: Satellite assemblies omit assembly version attributes, only under `dotnet build`

Created on 1 Jun 2017  路  11Comments  路  Source: dotnet/sdk

Repro steps

git clone https://github.com/microsoft/vs-validation
cd vs-validation\src\Microsoft.VisualStudio.Validation
dotnet restore
dotnet build -f net45

Expected

The built satellite assemblies have an assembly version that matches the one in the primary output assembly.

Actual

The built satellite assemblies lack any version attributes, leaving the assemblies claiming a version of 0.0.0.0.

The detailed build log from dotnet build includes this relevant portion:

     1>Target "CoreGenerateSatelliteAssemblies" in file "C:\Program Files\dotnet\sdk\2.0.0-preview1-005842\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.targets" from project "C:\git\validation\src\Microsoft.VisualStudio.Validation\Microsoft.VisualStudio.Validation.csproj" (target "CreateSatelliteAssemblies" depends on it):
       Building target "CoreGenerateSatelliteAssemblies" completely.
       Output file "C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\cs\Microsoft.VisualStudio.Validation.resources.dll" does not exist.
       Task "MakeDir"
       Done executing task "MakeDir".
       Task "WriteCodeFragment"
         Emitted specified code into "C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\cs\Microsoft.VisualStudio.Validation.resources.cs".
       Done executing task "WriteCodeFragment".
       Task "Csc"
         C:\Program Files\dotnet\sdk\2.0.0-preview1-005842\Roslyn\RunCsc.cmd /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Drawing.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.IO.Compression.FileSystem.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Numerics.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Runtime.Serialization.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.Linq.dll" /keyfile:C:\Users\andarno\.nuget\packages\microbuild.visualstudio\2.0.40\build\FinalPublicKey.snk /out:C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\cs\Microsoft.VisualStudio.Validation.resources.dll /resource:C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\Microsoft.Strings.cs.resources /target:library /deterministic+ /publicsign+ C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\cs\Microsoft.VisualStudio.Validation.resources.cs
         Microsoft (R) Visual C# Compiler version 2.0.0.61325
         Copyright (C) Microsoft Corporation. All rights reserved.

       Done executing task "Csc".

When using msbuild.exe instead of dotnet build, I get the expected behavior:

msbuild /t:rebuild /p:targetframework=net45 

This produces properly versioned satellite assemblies. We see in the detailed build logs this time that instead of using csc.exe to generate them, the targets use AL.exe, which uses the version from the primary assembly explicitly as a template:

     1>Target "GenerateSatelliteAssemblies" in file "C:\Program Files (x86)\Microsoft Visual Studio\2017\vsuvscore\MSBuild\15.0\bin\Microsoft.Common.CurrentVersion.targets" from project "C:\git\validation\src\Microsoft.VisualStudio.Validation\Microsoft.VisualStudio.Validation.csproj" (target "CreateSatelliteAssemblies" depends on it):
       Building target "GenerateSatelliteAssemblies" completely.
       Output file "C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\cs\Microsoft.VisualStudio.Validation.resources.dll" does not exist.
       Task "MakeDir"
       Done executing task "MakeDir".
       Using "AL" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
       Task "AL"
         C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\al.exe /culture:cs /delaysign+ /keyfile:C:\Users\andarno\.nuget\packages\microbuild.visualstudio\2.0.40\build\FinalPublicKey.snk /out:C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\cs\Microsoft.VisualStudio.Validation.resources.dll /template:C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\Microsoft.VisualStudio.Validation.dll /embed:C:\git\validation\src\..\obj\Microsoft.VisualStudio.Validation\Debug\net45\Microsoft.Strings.cs.resources
         Microsoft (R) Assembly Linker version 14.0.1055.0
         Copyright (C) Microsoft Corporation. All rights reserved.

       Done executing task "AL".

This was originally reported https://github.com/AArnott/Nerdbank.GitVersioning/issues/131, discovered by @onovotny.

Most helpful comment

Ok, let's first fix this in sdk, then push to have our targets moved to msbuild in vnext.

All 11 comments

IMO the dotnet build .targets should go back to using AL.exe.

A possible workaround for this might be to let the .NET SDK .targets generate these version attributes in the primary assembly and thus it would know to generate them in the resource assemblies as well. However there is a concern with that approach. And really before Nerdbank.GitVersioning can stop generating these attributes, it needs to be able to be sure the attributes will be generated by the .NET SDK itself. But until https://github.com/dotnet/sdk/issues/534 is fixed (and broadly used) there may not be a way for NB.GV to be able to detect this.

Here's another repro:

  1. Clone humanizer dev branch from https://github.com/humanizr/Humanizer (commit d1933496083b9f354e79eaf875cc9f19fd8ee512) currently
  2. Got to src\Humanizer.Tests
  3. Run msbuild /t:restore
  4. Run msbuild /t:build
  5. Run dotnet test --no-build
  6. Tests run successfully from build created by msbuild.exe
  7. Go back to ..\src
  8. Run git clean -xdf to clean repo
  9. Go to Humanizer.Tests
  10. Run dotnet restore
  11. Run dotnet test
  12. Many failures, I assume do to resource loading issues

@AArnott does the build log indicate that the CoreGenerateAssemblyInfo was skipped?

This target both generated the @(AssemblyAttribute) items that CoreGenerateSatelliteAssemblies reuses and the generated assembly attributes file for the main assembly. If that target is skipped due to inputs being unchanged and the file already existing, than CoreGenerateSatelliteAssemblies will not find any assembly attribute items.

For https://github.com/dotnet/sdk/pull/1255 i split this target and the attributes are generated by GetAssemblyAttributes which is always executed so this might have accidentally fixed this problem.

This isn't a matter of a target skipping. The primary output assembly got the version info correctly. The issue is related to the fact that I disable the default version attribute generating targets using the supported msbuild property for that purpose and I generate my own attributes. But while that works with full msbuild, with msbuild core (which may be lacking AL.exe?) my attributes aren't picked up and used for the satellite assembly.

@AArnott it is not clear to me what is the "special" sauce in your repo that causes this to happen? Can you help us reach a more straight forward repro for this? Other than clone and repo and try it?

Sure: install the Nerdbank.GitVersioning nuget package to a brand new project. Then of course add a strings.es.resx file to your project so that it actually has a satellite assembly to build. That should be all you need.

@livarcocc The key point is that CoreGenerateSatelliteAssemblies relies on @(AssemblyAttribute) but doesn't work for projects with disabled assembly info generation (or just disabled version attributes) that use a custom AssemblyInfo.cs.

There is no AL.exe for .NET Core.

The better fix would be to retrieve the version info from the main assembly and send that on to Csc. We need to push in the opposite direct IMHO: get rid of AL.exe in desktop msbuild as well, and use Csc everywhere. I think that should be done in the common resource targets and we should delete the overriding of satellite assembly generation from this repo.

This approach would close https://github.com/Microsoft/msbuild/issues/1490 It would also allow satellite assemblies to be /deterministic on all platforms, etc. .

The better fix would be to retrieve the version info from the main assembly and send that on to Csc.

That would suit me fine.

Bump? Can either this or Microsoft/msbuild#1490 be repriorized as required for 2.0? This scenario is broken for the CLI with only msbuild.exe as a workaround.

Ok, let's first fix this in sdk, then push to have our targets moved to msbuild in vnext.

Was this page helpful?
0 / 5 - 0 ratings