Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Build.Tasks] <ResolveAssemblies/> and ref assemblies (…
…#3053) (#3062) Fixes: #3045 In VS 2019 16.1 Preview, a project using `Microsoft.Extensions.Http` fails to build with: C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2146,5): error MSB4018: The "LinkAssemblies" task failed unexpectedly. System.IO.FileNotFoundException: Could not load assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Perhaps it doesn't exist in the Mono for Android profile? File name: 'System.Runtime.dll' at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters) at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference) at Mono.Cecil.MetadataResolver.Resolve(TypeReference type) at Mono.Cecil.ModuleDefinition.Resolve(TypeReference type) at Mono.Cecil.TypeReference.Resolve() at Java.Interop.Tools.Cecil.TypeDefinitionRocks.<GetTypeAndBaseTypes>d__1.MoveNext() at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate) at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName) at MonoDroid.Tuner.FixAbstractMethodsStep.ProcessAssembly(AssemblyDefinition assembly) at Mono.Linker.Steps.BaseStep.Process(LinkContext context) at Mono.Linker.Pipeline.Process(LinkContext context) at MonoDroid.Tuner.Linker.Process(LinkerOptions options, ILogger logger, LinkContext& context) at Xamarin.Android.Tasks.LinkAssemblies.Execute(DirectoryAssemblyResolver res) at Xamarin.Android.Tasks.LinkAssemblies.Execute() at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() [C:\Temp\ResolveAssembliesSystemRuntime\AndroidApp1\AndroidApp1.csproj] The problem being that the `<ResolveAssemblies/>` MSBuild task didn't return `System.Runtime.dll` in `@(ResolvedAssemblies)`. What further complicated matters, was that the same project was working with latest xamarin-android/master (16.2)? I was only able to reproduce the problem in a test after some work to create a project that only has a `<PackageReference/>` to `Microsoft.Extensions.Http` with no other references *at all*. I had to do some MSBuild trickery to remove `Java.Interop` and `System.Runtime` references. Looking at the dependency tree in the failing test, `System.Runtime.CompilerServices.Unsafe.dll` should be reporting a reference to `System.Runtime.dll`. Through debugging, I saw it only had a reference to `netstandard.dll`? Then I realized there were two assemblies: ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll ~\.nuget\packages\system.runtime.compilerservices.unsafe\4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll The "ref" assembly, references `netstandard.dll` and the "lib" assembly (that we should be using) references `System.Runtime.dll`. Through further debugging, I found two bugs here: * We shouldn't call `resolver.AddSearchDirectory()` until *after* we've checked if the top-level assembly is a reference assembly. We don't want a reference assembly in the search paths! * `MetadataResolver` should key its cache on the resolved path to the assembly. This allows `<ResolveAssemblies/>` to open two *different* instances of `System.Runtime.CompilerServices.Unsafe`.
- Loading branch information