From 9fe854e4d472382217f6a1f1631723c5de3e642c Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Mon, 20 Jan 2020 22:37:04 -0600 Subject: [PATCH] [Xamarin.Android.Build.Tasks] merge two targets to fix AndroidX.Migration Context: https://github.com/xamarin/XamarinAndroidXMigration Fixes: https://github.com/xamarin/xamarin-android/issues/4068 Developers have been reporting an error when using AndroidX.Migration: The "CopyGeneratedJavaResourceClasses" task was not given a value for the required parameter "SourceTopDirectory". It is reported another build fixes the issue, and it "randomly" happens on incremental builds. The error seems to indicate either `$(AaptTemporaryDirectory)` or `$(ResgenTemporaryDirectory)` are blank? But it only happens when using the AndroidX.Migration NuGet package. From a user's build log: Skipping target "_PrepareCreateBaseApk" because all output files are up-to-date with respect to the input files. Which would indicate in the case of AndroidX.Migration: * `_PrepareCreateBaseApk` was skipped. * `_AndroidXJetifyManifest` was injected, it came along and modified `$(IntermediateOutputPath)android\AndroidManifest.xml`. * `_CreateBaseApk` ran (with updated inputs), and `$(AaptTemporaryDirectory)` is blank! I could reproduce the problem in a test: * Build a project with AndroidX.Migration * Change C# code (a non-Java.Lang.Object class) * Build the project again Reviewing the MSBuild targets: `_PrepareCreateBaseApk` and `_CreateBaseApk`. They define a property that is passed between two targets. The following sets of targets have nearly identical `Input`/`Output`: * `_PrepareCreateBaseApk` and `_CreateBaseApk` * `_PrepareUpdateAndroidResgen` and `_UpdateAndroidResgen` This was done to workaround a long-lived bug in MSBuild: https://github.com/Microsoft/msbuild/issues/1006 A fix that doesn't seem break anything is to just run `_PrepareCreateBaseApk` *after* `$(AfterGenerateAndroidManifest)`. So if something triggers `_CreateBaseApk`, `_PrepareCreateBaseApk` will always run as well. I wrote a test for this scenario, and updated the AndroidX NuGets in our tests to use the RC now. --- .../Xamarin.Android.Build.Tests/BuildTest.cs | 1 + .../IncrementalBuildTest.cs | 24 +++++++++++++++++++ .../Android/KnownPackages.cs | 22 ++++++++++++----- .../Xamarin.Android.Common.targets | 3 +-- 4 files changed, 42 insertions(+), 8 deletions(-) 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 b27071bc98b..f2a6fca49b3 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 @@ -242,6 +242,7 @@ public void AndroidXMigration ([Values (true, false)] bool isRelease) proj.PackageReferences.Add (KnownPackages.AndroidXBrowser); proj.PackageReferences.Add (KnownPackages.AndroidXMediaRouter); proj.PackageReferences.Add (KnownPackages.AndroidXLegacySupportV4); + proj.PackageReferences.Add (KnownPackages.AndroidXLifecycleLiveData); proj.PackageReferences.Add (KnownPackages.XamarinGoogleAndroidMaterial); using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { 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 064e8549f91..cc221f64c11 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 @@ -1078,5 +1078,29 @@ public void AndroidResourceChange () } } } + + [Test] + [NonParallelizable] + public void AndroidXMigrationBug () + { + var proj = new XamarinFormsAndroidApplicationProject (); + proj.PackageReferences.Add (KnownPackages.AndroidXMigration); + proj.PackageReferences.Add (KnownPackages.AndroidXAppCompat); + proj.PackageReferences.Add (KnownPackages.AndroidXBrowser); + proj.PackageReferences.Add (KnownPackages.AndroidXMediaRouter); + proj.PackageReferences.Add (KnownPackages.AndroidXLegacySupportV4); + proj.PackageReferences.Add (KnownPackages.AndroidXLifecycleLiveData); + proj.PackageReferences.Add (KnownPackages.XamarinGoogleAndroidMaterial); + + string source = "class Foo { }"; + proj.Sources.Add (new BuildItem.Source ("Foo.cs") { TextContent = () => source }); + + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "first build should have succeeded."); + source = source.Replace ("Foo", "Bar"); + proj.Touch ("Foo.cs"); + Assert.IsTrue (b.Build (proj, doNotCleanupOnUpdate: true), "second build should have succeeded."); + } + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs index 8b760409a53..62896a80460 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs @@ -223,17 +223,17 @@ public static class KnownPackages }; public static Package AndroidXMigration = new Package { Id = "Xamarin.AndroidX.Migration", - Version = "1.0.0-preview04", + Version = "1.0.0-rc1", TargetFramework = "MonoAndroid10", }; public static Package AndroidXAppCompat = new Package { Id = "Xamarin.AndroidX.AppCompat", - Version = "1.0.2-preview02", + Version = "1.1.0-rc1", TargetFramework = "MonoAndroid10", }; public static Package AndroidXBrowser = new Package { Id = "Xamarin.AndroidX.Browser", - Version = "1.0.0-preview02", + Version = "1.0.0-rc1", TargetFramework = "MonoAndroid90", References = { new BuildItem.Reference ("Xamarin.AndroidX.Browser") { @@ -243,7 +243,7 @@ public static class KnownPackages }; public static Package AndroidXMediaRouter = new Package { Id = "Xamarin.AndroidX.MediaRouter", - Version = "1.0.0-preview02", + Version = "1.1.0-rc1", TargetFramework = "MonoAndroid90", References = { new BuildItem.Reference ("Xamarin.AndroidX.MediaRouter") { @@ -253,7 +253,7 @@ public static class KnownPackages }; public static Package AndroidXLegacySupportV4 = new Package { Id = "Xamarin.AndroidX.Legacy.Support.V4", - Version = "1.0.0-preview02", + Version = "1.0.0-rc1", TargetFramework = "MonoAndroid90", References = { new BuildItem.Reference ("Xamarin.AndroidX.Legacy.Support.V4") { @@ -261,9 +261,19 @@ public static class KnownPackages }, } }; + public static Package AndroidXLifecycleLiveData = new Package { + Id = "Xamarin.AndroidX.Lifecycle.LiveData", + Version = "2.1.0-rc1", + TargetFramework = "MonoAndroid90", + References = { + new BuildItem.Reference ("Xamarin.AndroidX.Lifecycle.LiveData") { + MetadataValues = "HintPath=..\\packages\\Xamarin.AndroidX.Lifecycle.LiveData.2.1.0-rc1\\lib\\MonoAndroid90\\Xamarin.AndroidX.Lifecycle.LiveData.dll" + }, + } + }; public static Package XamarinGoogleAndroidMaterial = new Package { Id = "Xamarin.Google.Android.Material", - Version = "1.0.0-preview02", + Version = "1.0.0-rc1", TargetFramework = "MonoAndroid90", References = { new BuildItem.Reference ("Xamarin.Google.Android.Material") { diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 0fbfcd922b7..08d7c169f38 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -2265,7 +2265,6 @@ because xbuild doesn't support framework reference assemblies. _CheckDuplicateJavaLibraries; UpdateAndroidAssets; $(_AfterCreateBaseApkDependsOnTargets); - _PrepareCreateBaseApk; <_CreateBaseApkInputs> $(MSBuildAllProjects) @@ -2279,7 +2278,7 @@ because xbuild doesn't support framework reference assemblies.