Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The ResolveAssemblies task hits "error XA2002: Can not resolve reference" if a NuGet <dependency/> from a .nuspec file uses exclude="Compile" #2674

Open
brendanzagaeski opened this issue Jan 31, 2019 · 1 comment
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended.

Comments

@brendanzagaeski
Copy link
Contributor

The original motivation for this investigation was #2534. That exact example of the problem was resolved another way in the Xamarin.Android version included with Visual Studio 2019 Preview 2. (The problematic System.Memory NuGet package was already scheduled to be imported into the Mono base class libraries, so the latest Xamarin.Android now provides its own System.Memory.dll facade assembly, circumventing the NuGet package problem. On top of that, the latest System.Memory NuGet package version 4.5.2 switched away from using the problematic exclude="Compile" attribute in the .nuspec file.)

But the general problem remains, and it could affect other NuGet packages in the future if the usage of reference assemblies in NuGet packages becomes more common.

Steps to Reproduce

  1. Unzip the attached test case.

  2. Change directory in a Developer Command Prompt into the NugetExcludeCompile\AndroidApp1 directory.

  3. Attempt to build the project, restoring the custom NuGet packages along the way:

    msbuild -restore -p:RestoreSources=..\packages

Expected Behavior

The project builds successfully. Also, building the SignAndroidPackage target should produce an APK that includes the full (not the reference assembly) version of NetStandardLibrary1.dll. That way, when the app runs on device or emulator, the new NetStandardLibrary2.Class1 () statement will complete without error.

The included NetCoreConsoleApp1 and NetFrameworkConsoleApp1 projects demonstrate the expected behavior.

Actual Behavior

The build fails during the ResolveAssemblies task:

"C:\Temp\NugetExcludeCompile\AndroidApp1\AndroidApp1.csproj" (default target) (1:7) ->
(_ResolveAssemblies target) ->
  C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1925,2): error XA2002: Can not resolve reference: `NetStandardLibrary1`, referenced by `NetStandardLibrary2`. Please add a NuGet package or assembly reference for `NetStandardLibrary1`, or remove the reference to `NetStandardLibrary2`.

Investigation

The problem is that ResolveAssemblies does not look up the NetStandardLibrary1.dll dependency of NetStandardLibrary2.dll using the runtime entry from the obj\project.assets.json file. This isn't a problem for most NuGet packages because the compile entry in obj\project.assets.json causes the assembly dependency to be included directly in the FilteredAssemblies item. But with this test case, the NuGet restore process has correctly set the compile entry to the _._ placeholder value:

"Contoso.Test.NetStandardLibrary1/0.1.1": {
  "type": "package",
  "compile": {
    "ref/netstandard2.0/_._": {}
  },
  "runtime": {
    "lib/netstandard2.0/NetStandardLibrary1.dll": {}
  }
},

Why is the _._ placeholder value correct?

It is correct because NetStandardLibrary2\Contoso.Test.NetStandardLibrary2.nuspec file uses the exclude="Compile" attribute to specify that Contoso.Test.NetStandardLibrary1 is not a compile dependency for projects consuming Contoso.Test.NetStandardLibrary2:

<dependencies>
    <dependency id="Contoso.Test.NetStandardLibrary1" version="0.1.1" exclude="Compile" />
</dependencies>

Is it valid for the .nuspec file to use exclude="Compile" for Contoso.Test.NetStandardLibrary1?

I believe so, yes. The Csc task does not require NetStandardLibrary1.dll to build AndroidApp1 successfully. (The Csc task completes successfully during step 3 of the steps to reproduce.) It therefore seems acceptable or even appropriate for the .nuspec file from NetStandardLibrary2 to specify that the NetStandardLibrary1.dll assembly is not required for compilation.

Potential Fixes

Based on the story up to this point, it seems that the special handling of reference assemblies in ResolveAssemblies might need to be extended so that it not only looks up and adds the runtime assembly for each reference assembly, but also looks up any corresponding dependencies entries in the obj\project.assets.json lock file and adds the runtime assemblies for each of those dependencies too.

Another question to consider might be how .NET Framework console projects determine which assemblies to copy into the output bin directory for PackageReference items. That mechanism successfully copies NetStandardLibrary1.dll to the bin directory. Could that mechanism be re-used for Xamarin.Android, or does the ResolveAssemblies task do some other special things that are unique to Xamarin.Android? (From a quick look at ResolveAssemblies, I see that one thing that might require special handling is .mdb files.)

Version Information

Visual Studio 2019 Preview
Xamarin.Android SDK 9.1.103.8 (HEAD/9a258c43)

Log File

msbuild.binlog

Steps to Modify the Custom NuGet Packages

Modifying the custom NuGet packages is slightly unusual compared to normal app and library builds, so here are the steps for that in case they might come in handy.

  1. Delete the *.nuget.* and project.assets.json files from the obj directory of the AndroidApp1 project (or delete the whole obj directory).

  2. Delete any cached copies of the NuGet packages from %USERPROFILE%\.nuget\packages. Otherwise, the NuGet restore process will use the cached copies.

  3. In a Developer Command Prompt, change directory into NetStandardLibrary2 (for example).

  4. Build the Pack target, supplying the .nuspec file in the NuspecFile property:

    msbuild -restore -t:Pack -p:NuspecFile=Contoso.Test.NetStandardLibrary2.nuspec -p:Configuration=Release
  5. Repeat step 3 of the steps to reproduce to restore the NuGet packages into the AndroidApp1 project and build it.

@Filipowicz251
Copy link

Filipowicz251 commented May 14, 2020

How is that possible, that totally legit bug report (with repro steps and pointing out where the issue is) is not being handled?:) It is over 1,5 year.

Do you know any workaround?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended.
Projects
None yet
Development

No branches or pull requests

2 participants