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

[Xamarin.Android.Build.Tasks] Deploy changes to transitive reference assembly dependencies #4887

Merged
merged 1 commit into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Documentation/release-notes/transitive-refasm.md
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this use lib1.OtherBuildItems and not lib1.References?

Copy link
Contributor Author

@brendanzagaeski brendanzagaeski Jul 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a little tricky thing I learned when setting up this test. What happens is that XmlUtils.ToXml() adds only OtherBuildItems in projects that have $(EnableDefaultItems)=true:

https://github.com/xamarin/xamarin-android/blob/99ec9f231bc52b4e9c451b955f2493517afc1fc2/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/XmlUtils.cs#L32-L51

And DotNetStandard has $(EnableDefaultItems)=true:

https://github.com/xamarin/xamarin-android/blob/99ec9f231bc52b4e9c451b955f2493517afc1fc2/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetStandard.cs#L42

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 ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,18 @@ 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)') "
/>
<FilteredAssemblies
Include="@(_ReferenceDependencyPaths)"
Condition="'%(_ReferenceDependencyPaths.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades' And Exists('%(_ReferenceDependencyPaths.Identity)') "
/>
<FilteredAssemblies
Include="@(_ReferencePath)"
Condition="'%(ReferencePath.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades' And Exists('%(_ReferencePath.Identity)') "
jonpryor marked this conversation as resolved.
Show resolved Hide resolved
/>
</ItemGroup>
<!-- Find all the assemblies this app requires -->
<ResolveAssemblies
Assemblies="@(FilteredAssemblies)"
Assemblies="@(FilteredAssemblies->Distinct())"
I18nAssemblies="$(MandroidI18n)"
LinkMode="$(AndroidLinkMode)"
ProjectFile="$(MSBuildProjectFullPath)"
Expand Down