From 8aee88b22edeeeffb194981dbb1ebcd6bd732d4d Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 5 Apr 2017 21:50:46 -0400 Subject: [PATCH] [Xamarin.Android.Build.Tasks] Reduce rebuild cascades Context: https://github.com/xamarin/xamarin-android/commit/518e57ca540fe3a1d4a7228ef19468d674238cf9 The scenario: rebuild `Xamarin.Android.Build.Tasks.csproj`: $ xbuild src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj *If nothing has changed*, the expectation is that this should be reasonably quick, because *nothing has changed*. Unfortunately, that's not the case; a rebuild could take upwards of 30sec on my local machine, becaues of rebuild cascades: Target CoreCompile needs to be built as input file 'Xamarin.Android.Tools.BootstrapTasks/GenerateProfile.cs' is newer than output file 'obj/Debug/Xamarin.Android.Tools.BootstrapTasks.dll' Target _BuildJNIEnv needs to be built as input file '../../bin/BuildDebug/jnienv-gen.exe' is newer than output file 'Android.Runtime/JNIEnv.g.cs' Target CoreCompile needs to be built as input file 'Android.Runtime/JNIEnv.g.cs' is newer than output file 'obj/Debug/android-25/Mono.Android.dll' Target _GenerateMonoAndroidDex18 needs to be built as input file '../../bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.1/mono.android.jar' is newer than output file '../../bin/Debug/lib/xbuild-frameworks/MonoAndroid/v7.1/mono.android.dex' Target _CopyExtractedMultiDexJar needs to be built as input file '$HOME/android-toolchain/sdk/extras/android/m2repository/com/android/support/multidex/1.0.1/multidex-1.0.1.aar' is newer than output file '../../bin/Debug/lib/xbuild/Xamarin/Android/../../../mandroid/android-support-multidex.jar' ...and if I'm *really* unlucky: Target _BuildUnlessCached needs to be built as input file '.../xamarin-android/external/mono/autogen.sh' is newer than output file '../../bin/Debug//lib/xbuild-frameworks/MonoAndroid/v1.0/FSharp.Core.dll' ...as that means an `external/mono` rebuild (!). Most of these are due to missing `` task use, to ensure that a created/generated file is newer than the `Inputs` of the associated target. The `` task is slightly more complicated: in that case, we only want the file timestamp to change if the file contents have changed. Alter the `GenerateProfile.Execute()` logic to perform a content diff before writing to the file, resulting in a new timestamp. Finally, fix `GenerateJavaCallableWrappers` target use from `Mono.Android.csproj` by providing a "real" value for `$(JavaCallableWrapperAbsAssembly)` so that the `GenerateJavaCallableWrappers` target's `Inputs` and `Outputs` reference valid (existing) files. The previous value used a `$(JavaCallableWrapperOutputPathAbs)` property, which doesn't appear to have been defined anywhere, and thus was `""`. Performing these changes reduces my typical "no change" `Xamarin.Android.Build.Tasks.csproj` rebuild time from ~30sec down to a more reasonable ~10sec, which is much better (though more than I'd personally like). --- build-tools/mono-runtimes/mono-runtimes.targets | 5 ++++- src/Mono.Android/Mono.Android.csproj | 2 +- src/Mono.Android/Mono.Android.targets | 2 ++ .../Xamarin.Android.Build.Tasks.targets | 2 ++ .../GenerateProfile.cs | 9 ++++++++- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/build-tools/mono-runtimes/mono-runtimes.targets b/build-tools/mono-runtimes/mono-runtimes.targets index 5350aa04a36..c2f006ce6e4 100644 --- a/build-tools/mono-runtimes/mono-runtimes.targets +++ b/build-tools/mono-runtimes/mono-runtimes.targets @@ -295,7 +295,7 @@ WorkingDirectory="$(IntermediateOutputPath)\%(_MonoRuntime.Identity)" /> + diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 044d062871c..11c32affcf7 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -315,7 +315,7 @@ - $(JavaCallableWrapperOutputPathAbs)$(AssemblyName).dll + $([System.IO.Path]::GetFullPath ('$(OutputPath)$(AssemblyName).dll')) CoreBuild diff --git a/src/Mono.Android/Mono.Android.targets b/src/Mono.Android/Mono.Android.targets index 61e9d947461..a4d5ed660bb 100644 --- a/src/Mono.Android/Mono.Android.targets +++ b/src/Mono.Android/Mono.Android.targets @@ -40,6 +40,7 @@ + <_AndroidProfile Include="Profiles\api-*.xml.in" /> @@ -128,6 +129,7 @@ SourceFiles="$(IntermediateOutputPath)__dex\classes.dex" DestinationFiles="$(OutputPath)mono.android.dex" /> + diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets index 58b558d8c66..22b3dcecf6c 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.targets @@ -143,9 +143,11 @@ + + diff --git a/src/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateProfile.cs b/src/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateProfile.cs index c7c9fdda82a..d5c4b31693b 100644 --- a/src/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateProfile.cs +++ b/src/Xamarin.Android.Tools.BootstrapTasks/Xamarin.Android.Tools.BootstrapTasks/GenerateProfile.cs @@ -38,7 +38,14 @@ public override bool Execute () sb.AppendLine ("\t}"); sb.AppendLine ("}"); - File.WriteAllText (OutputFile.ItemSpec, sb.ToString ()); + var newContents = sb.ToString (); + var curContents = ""; + if (File.Exists (OutputFile.ItemSpec)) { + curContents = File.ReadAllText (OutputFile.ItemSpec); + } + if (newContents != curContents) { + File.WriteAllText (OutputFile.ItemSpec, sb.ToString ()); + } return !Log.HasLoggedErrors; }