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

Using the wrong class library when a ref/ and lib/ in nuget #3920

Closed
mattleibow opened this issue Nov 16, 2019 · 7 comments · Fixed by #3938
Closed

Using the wrong class library when a ref/ and lib/ in nuget #3920

mattleibow opened this issue Nov 16, 2019 · 7 comments · Fixed by #3938
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects.

Comments

@mattleibow
Copy link
Member

mattleibow commented Nov 16, 2019

Steps to Reproduce

  1. Download sample: https://github.com/mattleibow/NuGetFoldersTest
  2. Run build.ps1
  3. Run android app in NuGetFoldersTest.sln

What is happening is in the NuGet, there are 3 assemblies (netstandard, ios, android). Since the netstandard is only for reference and should always be replaced by the runtime, it is in the ref folder. The android and ios assemblies are in the lib folder.

When building, the shared projects should use the ref, and then the android and ios have their own platform-specific assemblies. What is happening is that on android the ref/netstandard assembly is being added to the apk instead of the lib/monoandroid. ios works fine and uses the lib.xamarinios assembly.

Expected Behavior

The text on the app says Hello from Android.

Actual Behavior

The text says hello from netstandard.

Version Information

Latest preview ;)

Log File

@mattleibow mattleibow added the Area: App+Library Build Issues when building Library projects or Application projects. label Nov 16, 2019
@mattleibow
Copy link
Member Author

I have a workaround for now to include the monoandroid dll in both the ref and lib folders.

@jonathanpeppers
Copy link
Member

@mattleibow is the NetStandard library supposed to be just a "reference assembly" and have no implementation?

It seems like the csproj should have <ProduceReferenceAssembly>True</ProduceReferenceAssembly> and you ship the assembly that is output to bin\Release\netstandard2.0\ref\ in the NuGet? This would cause [assembly: System.Runtime.CompilerServices.ReferenceAssemblyAttribute] to be included?

When @dellis1972 was looking, the absence of this attribute was the issue:

https://xamarinhq.slack.com/archives/C03CEGRUW/p1574072958063200

@mattleibow
Copy link
Member Author

That is true, it should be a reference assembly. But, at the same time, if it is in the ref folder, that implicitly means it is a reference assembly - and should never reach the app package.

@dellis1972
Copy link
Contributor

dellis1972 commented Nov 19, 2019

This diff might help

diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs
index 99068f96..c3a4ee9c 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs
@@ -85,7 +85,8 @@ namespace Xamarin.Android.Tasks
                                foreach (var assembly in Assemblies) {
                                        // Add each user assembly and all referenced assemblies (recursive)
                                        string resolved_assembly = resolver.Resolve (assembly.ItemSpec);
-                                       if (MonoAndroidHelper.IsReferenceAssembly (resolved_assembly)) {
+                                       bool refAssembly = !string.IsNullOrEmpty (assembly.GetMetadata ("NuGetPackageId")) && resolved_assembly.Contains ($"{Path.PathSeparator }ref{Path.PathSeparator}");
+                                       if (refAssembly || MonoAndroidHelper.IsReferenceAssembly (resolved_assembly)) {
                                                // Resolve "runtime" library
                                                if (lockFile != null)
                                                        resolved_assembly = ResolveRuntimeAssemblyForReferenceAssembly (lockFile, assembly.ItemSpec);

jonpryor pushed a commit that referenced this issue Dec 6, 2019
Fixes: #3920

Context: https://github.com/mattleibow/NuGetFoldersTest

What is a [reference assembly][0]?

The short & glib answer is "an assembly with the
[`[assembly:ReferenceAssemblyAttribute]`][1] custom attribute".

Unfortunately, the short & glib answer is incomplete: NuGet also has
a convention in that assemblies within a [`/ref/` directory][2] are
treated as reference assemblies:

> …if you want to provide the corresponding compile time assembly
> as well then have `AnyCPU` assembly in `/ref/{tfm}` folder.
> 
> Please note, NuGet always picks these compile or runtime assets
> from one folder so if there are some compatible assets from `/ref`
> then `/lib` will be ignored to add compile-time assemblies.

Unfortunately, the `<ResolveAssemblies/>` task only treated
assemblies with `[assembly:ReferenceAssembly]` as reference
assemblies, not the "NuGet `/ref/` convention" assemblies.
Consequently, we would never switch out the "reference assembly"
for the `monodroid90`-profile assembly during build time. 

Update `<ResolveAssemblies/>` so that NuGet-style assemblies located
within a `/ref/` directory are treated as reference assemblies, even
if they do *not* have the `[assembly:ReferenceAssembly]` attribute.

[0]: https://docs.microsoft.com/en-us/dotnet/standard/assembly/reference-assemblies
[1]: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.referenceassemblyattribute?view=netframework-4.8
[2]: https://docs.microsoft.com/en-us/nuget/create-packages/supporting-multiple-target-frameworks#architecture-specific-folders
jonpryor pushed a commit that referenced this issue Dec 12, 2019
Fixes: #3920

Context: https://github.com/mattleibow/NuGetFoldersTest

What is a [reference assembly][0]?

The short & glib answer is "an assembly with the
[`[assembly:ReferenceAssemblyAttribute]`][1] custom attribute".

Unfortunately, the short & glib answer is incomplete: NuGet also has
a convention in that assemblies within a [`/ref/` directory][2] are
treated as reference assemblies:

> …if you want to provide the corresponding compile time assembly
> as well then have `AnyCPU` assembly in `/ref/{tfm}` folder.
> 
> Please note, NuGet always picks these compile or runtime assets
> from one folder so if there are some compatible assets from `/ref`
> then `/lib` will be ignored to add compile-time assemblies.

Unfortunately, the `<ResolveAssemblies/>` task only treated
assemblies with `[assembly:ReferenceAssembly]` as reference
assemblies, not the "NuGet `/ref/` convention" assemblies.
Consequently, we would never switch out the "reference assembly"
for the `monodroid90`-profile assembly during build time. 

Update `<ResolveAssemblies/>` so that NuGet-style assemblies located
within a `/ref/` directory are treated as reference assemblies, even
if they do *not* have the `[assembly:ReferenceAssembly]` attribute.

[0]: https://docs.microsoft.com/en-us/dotnet/standard/assembly/reference-assemblies
[1]: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.referenceassemblyattribute?view=netframework-4.8
[2]: https://docs.microsoft.com/en-us/nuget/create-packages/supporting-multiple-target-frameworks#architecture-specific-folders
@brendanzagaeski
Copy link
Contributor

Release status update

A new Preview version has now been published that includes the fix for this item. The fix is not yet included in a Release version. I will update this item again when a Release version is available that includes the fix.

Fix included in Xamarin.Android 10.2.0.84.

Fix included on Windows in Visual Studio 2019 version 16.5 Preview 2. To try the Preview version that includes the fix, check for the latest updates in Visual Studio Preview.

Fix included on macOS in Visual Studio 2019 for Mac version 8.5 Preview 1. To try the Preview version that includes the fix, check for the latest updates on the Preview updater channel.

@brendanzagaeski
Copy link
Contributor

Release status update

A new Release version has now been published on Windows that includes the fix for this item. The fix is not yet published in a Release version on macOS. I will update this item again when a Release version is available on macOS that includes the fix.

Fix included in Xamarin.Android 10.2.0.100.

Fix included on Windows in Visual Studio 2019 version 16.5. To get the new version that includes the fix, check for the latest updates or install the latest version from https://visualstudio.microsoft.com/downloads/.

(Fix also included on macOS in Visual Studio 2019 for Mac version 8.5 Preview 1 and higher. To try the Preview version that includes the fix, check for the latest updates on the Preview updater channel.)

@brendanzagaeski
Copy link
Contributor

Release status update

A new Release version has now been published on macOS that includes the fix for this item.

Fix included in Xamarin.Android 10.2.0.100.

Fix included on macOS in Visual Studio 2019 for Mac version 8.5. To get the new version that includes the fix, check for the latest updates on the Stable updater channel.

(Fix also included on Windows in Visual Studio 2019 version 16.5 and higher. To get the new version that includes the fix, check for the latest updates or install the latest version from https://visualstudio.microsoft.com/downloads/.)

@ghost ghost locked as resolved and limited conversation to collaborators Jun 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants