gluck / il-repack

Open-source alternative to ILMerge
Apache License 2.0
1.16k stars 214 forks source link

Issue with 2.0.22: Failed to resolve assembly 'Microsoft.Build.Framework' #342

Closed bradwilson closed 8 months ago

bradwilson commented 8 months ago

After updating to 2.0.22 (and switching from mono to dotnet for invocation), my Linux builds are now failing to find Microsoft.Build.Framework.

Repro steps:

  1. git clone https://github.com/xunit/xunit
  2. git switch -d c0730016289d6418cc8d28c61f7c2f96b1a8336f (this is where main is as of the writing of this bug)
  3. dotnet build src/xunit.v3.runner.msbuild

Results:

MSBuild version 17.8.3+195e7f5a3 for .NET
  Determining projects to restore...
  Restored /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/xunit.v3.runner.msbuild.csproj (in 195 ms).
  Restored /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.common/xunit.v3.runner.common.csproj (in 197 ms).
  Restored /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.utility/xunit.v3.runner.utility.csproj (in 202 ms).
  Restored /home/bradwilson/dev/xunit/xunit/src/xunit.v3.common/xunit.v3.common.csproj (in 195 ms).
  xunit.v3.common -> /home/bradwilson/dev/xunit/xunit/src/xunit.v3.common/bin/Debug/netstandard2.0/xunit.v3.common.dll
  xunit.v3.runner.common -> /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.common/bin/Debug/netstandard2.0/xunit.v3.runner.common.dll
  xunit.v3.runner.utility -> /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.utility/bin/Debug/net472/xunit.v3.runner.utility.net472.dll
  xunit.v3.runner.msbuild -> /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/xunit.v3.runner.msbuild.dll
  xunit.v3.runner.msbuild -> /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/merged/xunit.v3.runner.msbuild.dll
  Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
     at Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters) in C:\projects\il-repack\cecil\Mono.Cecil\BaseAssemblyResolver.cs:line 172
     at Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name) in C:\projects\il-repack\cecil\Mono.Cecil\BaseAssemblyResolver.cs:line 117
     at Mono.Cecil.DefaultAssemblyResolver.Resolve(AssemblyNameReference name) in C:\projects\il-repack\cecil\Mono.Cecil\DefaultAssemblyResolver.cs:line 33
     at Mono.Cecil.MetadataResolver.Resolve(TypeReference type) in C:\projects\il-repack\cecil\Mono.Cecil\MetadataResolver.cs:line 110
     at Mono.Cecil.ModuleDefinition.Resolve(TypeReference type) in C:\projects\il-repack\cecil\Mono.Cecil\ModuleDefinition.cs:line 748
     at Mono.Cecil.TypeReference.Resolve() in C:\projects\il-repack\cecil\Mono.Cecil\TypeReference.cs:line 278
     at ILRepacking.ReferenceFixator.FixReferences(Collection`1 attributes) in C:\projects\il-repack\ILRepack\ReferenceFixator.cs:line 334
     at ILRepacking.ReferenceFixator.FixReferences(PropertyDefinition definition) in C:\projects\il-repack\ILRepack\ReferenceFixator.cs:line 400
     at ILRepacking.ReferenceFixator.FixReferences(TypeDefinition type) in C:\projects\il-repack\ILRepack\ReferenceFixator.cs:line 146
     at ILRepacking.Steps.ReferencesFixStep.Perform() in C:\projects\il-repack\ILRepack\Steps\ReferencesFixStep.cs:line 57
     at ILRepacking.ILRepack.Repack() in C:\projects\il-repack\ILRepack\ILRepack.cs:line 371
     at ILRepacking.Application.Main(String[] args) in C:\projects\il-repack\ILRepack\Application.cs:line 29
/home/bradwilson/dev/xunit/xunit/src/Directory.Build.targets(69,5): error MSB3073: The command "dotnet "/home/bradwilson/.nuget/packages/ilrepack/2.0.22/tools/ILRepack.exe" -internalize -ndebug -lib:/home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/ -out:/home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/merged/xunit.v3.runner.msbuild.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/xunit.v3.runner.msbuild.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/Microsoft.Bcl.AsyncInterfaces.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/Mono.Cecil.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/Mono.Cecil.Mdb.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/Mono.Cecil.Pdb.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/Mono.Cecil.Rocks.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.Buffers.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.IO.Pipelines.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.Memory.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.Numerics.Vectors.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.Runtime.CompilerServices.Unsafe.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.Text.Encodings.Web.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.Text.Json.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.Threading.Tasks.Extensions.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/System.ValueTuple.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/xunit.v3.common.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/xunit.v3.runner.common.dll /home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/bin/Debug/net472/xunit.v3.runner.utility.net472.dll" exited with code 1. [/home/bradwilson/dev/xunit/xunit/src/xunit.v3.runner.msbuild/xunit.v3.runner.msbuild.csproj]

Build FAILED.

dotnet --info:

.NET SDK:
 Version:           8.0.100
 Commit:            57efcf1350
 Workload version:  8.0.100-manifests.6c33ef20

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  22.04
 OS Platform: Linux
 RID:         linux-x64
 Base Path:   /usr/share/dotnet/sdk/8.0.100/

.NET workloads installed:
 Workload version: 8.0.100-manifests.6c33ef20
There are no installed workloads to display.

Host:
  Version:      8.0.0
  Architecture: x64
  Commit:       5535e31a71

.NET SDKs installed:
  6.0.417 [/usr/share/dotnet/sdk]
  8.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.25 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.25 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found
bradwilson commented 8 months ago

Note: 2.0.22 does not fail on Windows. 2.0.21 does not fail anywhere.

KirillOsenkov commented 8 months ago

I notice that xunit.v3.runner.msbuild.dll depends on Microsoft.Build.Framework.dll:

image image image

During the build, this .dll is being picked up from Microsoft.NETFramework.ReferenceAssemblies:

image

Here's what I think we should do: copy Microsoft.Build.Framework.dll to output and exclude it from merging (such that when MSBuild uses it it has the same types):

Here's a PR: https://github.com/xunit/xunit/pull/2858

KirillOsenkov commented 8 months ago

Alternatively, you could pass the path to $(PkgMicrosoft_NETFramework_ReferenceAssemblies)1.0.3/build/.NETFramework/v4.7.2/Microsoft.Build.Framework.dll as a /lib: argument to ILRepack.exe so that it can resolve the dll from there.

KirillOsenkov commented 8 months ago

I actually have no idea why 2.0.21 works. Somehow ILRepack is able to grovel through all the assemblies without needing to resolve Microsoft.Build.Framework.dll. But something changed in 2.0.22 so now ILRepack hits something which requires it to go look up Microsoft.Build.Framework.dll. Since it's a legitimate request to want to inspect a reference to be able to analyze an assembly, I don't think there's anything wrong with 2.0.22. 2.0.21 had the privilege but didn't use it? 2.0.22 decided to be pickier somehow?

KirillOsenkov commented 8 months ago

I did change the resolve for 2.0.22 to be able to look up .NET Core assemblies, before it didn't have that capability.

KirillOsenkov commented 8 months ago

OH! I know. 2.0.21 uses mono, and Mono contains Microsoft.Build.Framework.dll in the GAC, so ILRepack resolves it from the GAC.

When using .NET, it has no GAC, so it can't resolve it any more.

bradwilson commented 8 months ago

I like the lib strategy, I can key it off $(TargetFrameworkRootPath) and then I don't have to worry about making private copies and adding exclusions if this ever surfaces again. I tried this on Linux and it works, then tried it on Windows so I could use ILSpy to verify that the MSBuild assemblies weren't part of the merge:

image

Looks good. 👍🏼 I'm going to amend your xunit/xunit PR with this and merge it. Thanks!