diff --git a/Documentation/release-notes/transitive-refasm.md b/Documentation/release-notes/transitive-refasm.md
new file mode 100644
index 00000000000..225c8ea0e4b
--- /dev/null
+++ b/Documentation/release-notes/transitive-refasm.md
@@ -0,0 +1,8 @@
+#### Application and library build and deployment
+
+- [Developer Community 1086457](https://developercommunity.visualstudio.com/content/problem/1086457/index.html):
+ Changes to libraries referenced by the .NET Standard library in a default
+ Xamarin.Forms project were not reflected in the running app without a clean
+ rebuild. More generally, this issue affected any library referenced
+ indirectly via a .NET Standard library that had the
+ `ProduceReferenceAssembly` MSBuild property set to `true`.
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
index 3a5ca58a8e9..59a6ab1952a 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
@@ -2692,7 +2692,7 @@ public void BuildWithResolveAssembliesFailure ([Values (true, false)] bool usePa
Assert.IsTrue (appBuilder.LastBuildOutput.ContainsText ($"{error} `Microsoft.Azure.EventHubs`, referenced by `MyLibrary`. Please add a NuGet package or assembly reference for `Microsoft.Azure.EventHubs`, or remove the reference to `MyLibrary`."),
$"Should recieve '{error}' regarding `Microsoft.Azure.EventHubs`!");
} else {
- Assert.IsTrue (appBuilder.LastBuildOutput.ContainsText ($"{error} `Microsoft.Azure.Amqp`, referenced by `MyLibrary` > `Microsoft.Azure.EventHubs`. Please add a NuGet package or assembly reference for `Microsoft.Azure.Amqp`, or remove the reference to `MyLibrary`."),
+ Assert.IsTrue (appBuilder.LastBuildOutput.ContainsText ($"{error} `Microsoft.Azure.Amqp`, referenced by `Microsoft.Azure.EventHubs`. Please add a NuGet package or assembly reference for `Microsoft.Azure.Amqp`, or remove the reference to `Microsoft.Azure.EventHubs`"),
$"Should recieve '{error}' regarding `Microsoft.Azure.Amqp`!");
}
//Now add the PackageReference to the app to see a different error message
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
index 349a5374bbd..40fd6dc0017 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/IncrementalBuildTest.cs
@@ -516,6 +516,68 @@ public void ProduceReferenceAssembly ()
}
}
+ [Test]
+ public void TransitiveDependencyProduceReferenceAssembly ()
+ {
+ var path = Path.Combine (Root, "temp", TestName);
+ var app = new XamarinAndroidApplicationProject {
+ ProjectName = "App",
+ Sources = {
+ new BuildItem.Source ("Class1.cs") {
+ TextContent = () => "public class Class1 : Library1.Class1 { }"
+ },
+ }
+ };
+ var lib1 = new DotNetStandard {
+ ProjectName = "Library1",
+ Sdk = "Microsoft.NET.Sdk",
+ TargetFramework = "netstandard2.0",
+ Sources = {
+ new BuildItem.Source ("Class1.cs") {
+ TextContent = () => "namespace Library1 { public class Class1 { } }"
+ },
+ new BuildItem.Source ("Class2.cs") {
+ TextContent = () => "namespace Library1 { public class Class2 : Library2.Class1 { } }"
+ }
+ }
+ };
+ lib1.SetProperty ("ProduceReferenceAssembly", "True");
+ var lib2 = new DotNetStandard {
+ ProjectName = "Library2",
+ Sdk = "Microsoft.NET.Sdk",
+ TargetFramework = "netstandard2.0",
+ Sources = {
+ new BuildItem.Source ("Class1.cs") {
+ TextContent = () => "namespace Library2 { public class Class1 { } }"
+ },
+ }
+ };
+ lib2.SetProperty ("ProduceReferenceAssembly", "True");
+ lib1.OtherBuildItems.Add (new BuildItem.ProjectReference ($"..\\{lib2.ProjectName}\\{lib2.ProjectName}.csproj", lib2.ProjectName, lib2.ProjectGuid));
+ app.References.Add (new BuildItem.ProjectReference ($"..\\{lib1.ProjectName}\\{lib1.ProjectName}.csproj", lib1.ProjectName, lib1.ProjectGuid));
+
+ using (var lib2Builder = CreateDllBuilder (Path.Combine (path, lib2.ProjectName), cleanupAfterSuccessfulBuild: false))
+ using (var lib1Builder = CreateDllBuilder (Path.Combine (path, lib1.ProjectName), cleanupAfterSuccessfulBuild: false))
+ using (var appBuilder = CreateApkBuilder (Path.Combine (path, app.ProjectName))) {
+ Assert.IsTrue (lib2Builder.Build (lib2), "first Library2 build should have succeeded.");
+ Assert.IsTrue (lib1Builder.Build (lib1), "first Library1 build should have succeeded.");
+ Assert.IsTrue (appBuilder.Build (app), "first app build should have succeeded.");
+
+ lib2.Sources.Add (new BuildItem.Source ("Class2.cs") {
+ TextContent = () => "namespace Library2 { public class Class2 { } }"
+ });
+
+ Assert.IsTrue (lib2Builder.Build (lib2, doNotCleanupOnUpdate: true), "second Library2 build should have succeeded.");
+ Assert.IsTrue (lib1Builder.Build (lib1, doNotCleanupOnUpdate: true, saveProject: false), "second Library1 build should have succeeded.");
+ appBuilder.Target = "SignAndroidPackage";
+ Assert.IsTrue (appBuilder.Build (app, doNotCleanupOnUpdate: true, saveProject: false), "app SignAndroidPackage build should have succeeded.");
+
+ var lib2Output = Path.Combine (path, lib2.ProjectName, "bin", "Debug", "netstandard2.0", $"{lib2.ProjectName}.dll");
+ var lib2InAppOutput = Path.Combine (path, app.ProjectName, app.IntermediateOutputPath, "android", "assets", $"{lib2.ProjectName}.dll");
+ FileAssert.AreEqual (lib2Output, lib2InAppOutput, "new Library2 should have been copied to app output directory");
+ }
+ }
+
[Test]
[Category ("dotnet")]
public void LinkAssembliesNoShrink ()
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Legacy.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Legacy.targets
index 5cce13cbd7c..1cefd0b1c98 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Legacy.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Legacy.targets
@@ -258,6 +258,10 @@ projects. .NET 5 projects will not import this file.
Include="@(ReferenceCopyLocalPaths)"
Condition="'%(ReferenceCopyLocalPaths.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades' And '%(ReferenceCopyLocalPaths.Extension)' == '.dll' And '%(ReferenceCopyLocalPaths.RelativeDir)' == '' And Exists('%(ReferenceCopyLocalPaths.Identity)') "
/>
+