diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs index 99068f968a1..7d788b22d4f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs @@ -85,7 +85,8 @@ void Execute (MetadataResolver resolver) 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.DirectorySeparatorChar}ref{Path.DirectorySeparatorChar}"); + if (refAssembly || MonoAndroidHelper.IsReferenceAssembly (resolved_assembly)) { // Resolve "runtime" library if (lockFile != null) resolved_assembly = ResolveRuntimeAssemblyForReferenceAssembly (lockFile, assembly.ItemSpec); @@ -176,6 +177,8 @@ string ResolveRuntimeAssemblyForReferenceAssembly (LockFile lockFile, string ass } foreach (var folder in lockFile.PackageFolders) { var path = assemblyPath.Replace (folder.Path, string.Empty); + if (path.StartsWith ($"{Path.DirectorySeparatorChar}")) + path = path.Substring (1); var libraryPath = lockFile.Libraries.FirstOrDefault (x => path.StartsWith (x.Path.Replace('/', Path.DirectorySeparatorChar), StringComparison.OrdinalIgnoreCase)); if (libraryPath == null) continue; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs index eb07118063e..21e60cf8a0b 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using NUnit.Framework; using Xamarin.ProjectTools; @@ -644,5 +644,89 @@ protected override void OnCreate (Bundle bundle) } } } + + [Test] + public void CheckTheCorrectRuntimeAssemblyIsUsedFromNuget () + { + string monoandroidFramework; + using (var builder = new Builder ()) { + monoandroidFramework = builder.LatestMultiTargetFrameworkVersion (); + } + string path = Path.Combine (Root, "temp", TestName); + var ns = new DotNetStandard () { + ProjectName = "Dummy", + Sdk = "MSBuild.Sdk.Extras/2.0.54", + Sources = { + new BuildItem.Source ("Class1.cs") { + TextContent = () => @"public class Class1 { +#if __ANDROID__ + public static string Library => ""Android""; +#else + public static string Library => "".NET Standard""; +#endif +}", + }, + }, + OtherBuildItems = { + new BuildItem.NoActionResource ("$(OutputPath)netstandard2.0\\$(AssemblyName).dll") { + TextContent = null, + BinaryContent = null, + Metadata = { + { "PackagePath", "ref\\netstandard2.0" }, + { "Pack", "True" } + }, + }, + new BuildItem.NoActionResource ($"$(OutputPath){monoandroidFramework}\\$(AssemblyName).dll") { + TextContent = null, + BinaryContent = null, + Metadata = { + { "PackagePath", $"lib\\{monoandroidFramework}" }, + { "Pack", "True" } + }, + }, + }, + }; + ns.SetProperty ("TargetFrameworks", $"netstandard2.0;{monoandroidFramework}"); + ns.SetProperty ("PackageId", "dummy.package.foo"); + ns.SetProperty ("PackageVersion", "1.0.0"); + ns.SetProperty ("GeneratePackageOnBuild", "True"); + ns.SetProperty ("IncludeBuildOutput", "False"); + ns.SetProperty ("Summary", "Test"); + ns.SetProperty ("Description", "Test"); + ns.SetProperty ("PackageOutputPath", path); + + + var xa = new XamarinAndroidApplicationProject () { + ProjectName = "App", + PackageReferences = { + new Package () { + Id = "dummy.package.foo", + Version = "1.0.0", + }, + }, + OtherBuildItems = { + new BuildItem.NoActionResource ("NuGet.config") { + }, + }, + }; + xa.SetProperty ("RestoreNoCache", "true"); + xa.SetProperty ("RestorePackagesPath", "$(MSBuildThisFileDirectory)packages"); + using (var nsb = CreateDllBuilder (Path.Combine (path, ns.ProjectName), cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) + using (var xab = CreateApkBuilder (Path.Combine (path, xa.ProjectName), cleanupAfterSuccessfulBuild: false, cleanupOnDispose: false)) { + nsb.ThrowOnBuildFailure = xab.ThrowOnBuildFailure = false; + Assert.IsTrue (nsb.Build (ns), "Build of NetStandard Library should have succeeded."); + Assert.IsFalse (xab.Build (xa, doNotCleanupOnUpdate: true), "Build of App Library should have failed."); + File.WriteAllText (Path.Combine (Root, xab.ProjectDirectory, "NuGet.config"), @" + + + + + +"); + Assert.IsTrue (xab.Build (xa, doNotCleanupOnUpdate: true), "Build of App Library should have succeeded."); + string expected = Path.Combine ("dummy.package.foo", "1.0.0", "lib", monoandroidFramework, "Dummy.dll"); + Assert.IsTrue (xab.LastBuildOutput.ContainsText (expected), $"Build should be using {expected}"); + } + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs index 84a383e369f..129cd6769cc 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs @@ -167,6 +167,15 @@ public string LatestTargetFrameworkVersion () { return lastFrameworkVersion; } + public string LatestMultiTargetFrameworkVersion () + { + GetTargetFrameworkVersionRange (out string _, out string _, out string _, out string lastFrameworkVersion); + lastFrameworkVersion = lastFrameworkVersion.Replace ("v", string.Empty); + if (lastFrameworkVersion != "10.0") + lastFrameworkVersion = lastFrameworkVersion.Replace (".", string.Empty); + return $"monoandroid{lastFrameworkVersion}"; + } + public string LatestTargetFrameworkVersion (out string apiLevel) { GetTargetFrameworkVersionRange (out string _, out string _, out apiLevel, out string lastFrameworkVersion); return lastFrameworkVersion; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs index 8b39dd8e1e8..fc001fdcb69 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs @@ -71,7 +71,7 @@ public override string SaveProject () if (bi.DependentUpon != null) sb.Append ($"DependentUpon=\"{bi.DependentUpon ()}\" "); if (bi.Version != null) sb.Append ($"Version=\"{bi.Version ()}\" "); if (bi.SubType != null) sb.Append ($"SubType=\"{bi.SubType ()}\" "); - if (bi.Metadata.Any ()) { + if (!bi.Metadata.Any ()) { sb.AppendLine ($"\t\t/>"); } else { sb.AppendLine ($">"); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs index a3e8e6db176..243f36e22b1 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs @@ -56,8 +56,9 @@ public void Save (XamarinProject project, bool doNotCleanupOnUpdate = false, boo // Copy our solution's NuGet.config var nuget_config = Path.Combine (XABuildPaths.TopDirectory, "NuGet.config"); - if (File.Exists (nuget_config)) { - File.Copy (nuget_config, Path.Combine (Root, ProjectDirectory, "NuGet.config"), overwrite: true); + var dest = Path.Combine (Root, ProjectDirectory, "NuGet.config"); + if (File.Exists (nuget_config) && !File.Exists (dest)) { + File.Copy (nuget_config, dest, overwrite: true); } } else diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs index f109ff14e5d..2e452293169 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs @@ -270,7 +270,7 @@ public virtual void UpdateProjectFiles (string directory, IEnumerable