From 9a416973360218f534201d6845cb2840f1aa392f Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Fri, 31 Aug 2018 14:29:37 -0500 Subject: [PATCH] [Xamarin.Android.Build.Tasks] prevent _BuildLibraryProjectImportsCache always running When testing a build with no changes, I started noticing: Building target "_BuildLibraryImportsCache" completely. Input file "App7\bin\Debug\netstandard2.0\App7.dll" is newer than output file "obj\Debug\90\libraryimports.cache". What was weird, is that earlier in the build log: Did not copy from file "bin\Debug\netstandard2.0\App7.dll" to file "bin\Debug\App7.dll" because the "SkipUnchangedFiles" parameter was set to "true" in the project and the files' sizes and timestamps match. So the NetStandard assembly didn't change. When I looked at these files: 8/31/2018 11:02 AM App7.dll 8/31/2018 10:09 AM resourcepaths.cache Weird? It looks like `resourcepaths.cache`'s timestamp needs to be updated? Then I looked and noticed that the timestamp of `resourcepaths.cache` would only be updated if the XML changed. My *first* attempt to fix this: - I made `XDocumentExtensions.SaveIfChanged` return a `bool` indicating if the file changed. - I changed the `GetImportedLibraries` task so that it would update the timestamp in cases where the file didn't change. Unfortunately, that made `_UpdateAndroidResgen` run all the time, which would be even worse! So my *second* attempt was much better: - Add a `$(_AndroidLibraryImportsCache).stamp` file, to use as the `Outputs` of `_BuildLibraryImportsCache`. - This file's timestamp can operate independently of `$(_AndroidLibraryImportsCache)` `_BuildLibraryImportsCache` now builds incrementally and gets skipped properly: Skipping target "_BuildLibraryImportsCache" because all output files are up-to-date with respect to the input files. It seems to me this problem was always occurring on builds with no changes. So this will likely help any incremental build. Before this change: 146 ms _BuildLibraryImportsCache 1 calls Total time: 2.824s After this change: 4 ms _BuildLibraryImportsCache 1 calls Total time: 2.698s I also updated an existing test to make sure the `_BuildLibraryImportsCache` target isn't running all the time. --- .../Tests/Xamarin.Android.Build.Tests/BuildTest.cs | 1 + .../Xamarin.Android.Common.targets | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) 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 437a3a67f49..5c488d16840 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 @@ -318,6 +318,7 @@ public void CheckTimestamps ([Values (true, false)] bool isRelease) var targetsToBeSkipped = new [] { isRelease ? "_LinkAssembliesShrink" : "_LinkAssembliesNoShrink", "_UpdateAndroidResgen", + "_BuildLibraryImportsCache", }; foreach (var targetName in targetsToBeSkipped) { Assert.IsTrue (b.Output.IsTargetSkipped (targetName), $"`{targetName}` should be skipped!"); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index c435aca888a..956676d84fa 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -1447,10 +1447,14 @@ because xbuild doesn't support framework reference assemblies. + Outputs="$(_AndroidLibraryImportsCache).stamp"> + + + + @@ -3071,6 +3075,7 @@ because xbuild doesn't support framework reference assemblies. +