From 6fa4a616fae192be61bfb7cf6395f52c3c5cea1a Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Thu, 12 Jul 2018 15:16:38 -0500 Subject: [PATCH] [Xamarin.Android.Build.Tasks] use designtimebuild.props Fixes: https://github.com/xamarin/xamarin-android/issues/1958 Context: https://github.com/xamarin/xamarin-android/issues/1933 Context: https://github.com/xamarin/xamarin-android/pull/1943 One of the issues I noticed while debugging the issue with #1933 is that `$(IntermediateOutputPath)build.props` gets invalidated if `$(DesignTimeBuild)` changes. `build.props` triggers alot of targets to build completely again, so this is pretty bad for our build times in an IDE... Design-Time Builds can run quite frequently in VS Windows, and we don't want to rebuild a bunch of things unnecessarily when the user switches back to a regular build. So a solution, is to use a `obj/Debug/designtime/build.props` that works independantly of `build.props`. This prevents some slower targets from running when they shouldn't, such as `_UpdateAndroidResgen`. I added a test to validate these changes, which also verify that `IncrementalClean` isn't deleting these files. It also is important to point out that any files in the `designtime` directory are not deleted during a `Clean`. Context on this here: https://github.com/xamarin/xamarin-android/commit/34a377456872b957b3e3a573075f88b7d4a7e1b8 Other changes: - Updated `.gitignore` for `*.binlog` - Renamed `_AndroidDesignTimeResDirIntermediate` to `_AndroidIntermediateDesignTimeBuildDirectory` and declared it earlier in `Xamarin.Android.Common.targets` --- .gitignore | 1 + .../Xamarin.Android.Build.Tests/BuildTest.cs | 37 +++++++++++++++++++ .../Xamarin.Android.Common.targets | 18 +++++---- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 26eeca75a65..22b42ec9a97 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ Resource.designer.cs logcat-*.txt apk-sizes-*.txt *.rawproto +*.binlog src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props 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 3f24b141706..11e173102a8 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 @@ -120,6 +120,43 @@ public void FooMethod () { } } + [Test] + public void SwitchBetweenDesignTimeBuild () + { + var proj = new XamarinAndroidApplicationProject (); + + using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { + Assert.IsTrue (b.Build (proj), "first *regular* build should have succeeded."); + var build_props = b.Output.GetIntermediaryPath ("build.props"); + var designtime_build_props = b.Output.GetIntermediaryPath (Path.Combine ("designtime", "build.props")); + FileAssert.Exists (build_props, "build.props should exist after a first `Build`."); + FileAssert.DoesNotExist (designtime_build_props, "designtime/build.props should *not* exist after a first `Build`."); + + b.Target = "Compile"; + Assert.IsTrue (b.Build (proj, parameters: new [] { "DesignTimeBuild=True" }), "first design-time build should have succeeded."); + FileAssert.Exists (build_props, "build.props should exist after a design-time build."); + FileAssert.Exists (designtime_build_props, "designtime/build.props should exist after a design-time build."); + + b.Target = "Build"; + Assert.IsTrue (b.Build (proj), "second *regular* build should have succeeded."); + FileAssert.Exists (build_props, "build.props should exist after the second `Build`."); + FileAssert.Exists (designtime_build_props, "designtime/build.props should exist after the second `Build`."); + + //NOTE: none of these targets should run, since we have not actually changed anything! + Assert.IsTrue (b.Output.IsTargetSkipped ("_UpdateAndroidResgen"), "`_UpdateAndroidResgen` should be skipped!"); + //TODO: We would like for this assertion to work, but the item group changes between DTB and regular builds + // $(IntermediateOutputPath)designtime\Resource.designer.cs -> Resources\Resource.designer.cs + // And so the built assembly changes between DTB and regular build, triggering `_LinkAssembliesNoShrink` + //Assert.IsTrue (b.Output.IsTargetSkipped ("_LinkAssembliesNoShrink"), "`_LinkAssembliesNoShrink` should be skipped!"); + + b.Target = "Clean"; + Assert.IsTrue (b.Build (proj), "clean should have succeeded."); + + FileAssert.DoesNotExist (build_props, "build.props should *not* exist after `Clean`."); + FileAssert.Exists (designtime_build_props, "designtime/build.props should exist after `Clean`."); + } + } + [Test] public void BuildPropsBreaksConvertResourcesCases () { diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index f0f619b900e..73718fda1e8 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -274,6 +274,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. <_AndroidProguardInputJarFilter>(!META-INF/MANIFEST.MF) <_AndroidAapt2VersionFile>$(IntermediateOutputPath)aapt2.version <_AndroidNuGetStampFile>$(IntermediateOutputPath)$(MSBuildProjectName).nuget.stamp + <_AndroidIntermediateDesignTimeBuildDirectory>$(IntermediateOutputPath)designtime\ $(EnableProguard) @@ -305,6 +306,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. <_AndroidSequencePointsMode Condition=" '$(_AndroidSequencePointsMode)' == ''">None <_InstantRunEnabled Condition=" '$(_InstantRunEnabled)' == '' ">False <_AndroidBuildPropertiesCache>$(IntermediateOutputPath)build.props + <_AndroidDesignTimeBuildPropertiesCache>$(_AndroidIntermediateDesignTimeBuildDirectory)build.props False @@ -426,8 +428,9 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. <_AndroidResourcePathsCache Condition=" '$(DesignTimeBuild)' == 'true' And !Exists ('$(_AndroidResourcePathsCache)') ">$(_AndroidResourcePathsDesignTimeCache) <_AndroidLibraryImportsCache Condition=" '$(DesignTimeBuild)' == 'true' And !Exists ('$(_AndroidLibraryImportsCache)') ">$(_AndroidLibraryImportsDesignTimeCache) <_AndroidLibraryProjectImportsCache Condition=" '$(DesignTimeBuild)' == 'true' And !Exists ('$(_AndroidLibraryProjectImportsCache)') ">$(_AndroidLibraryProjectImportsDesignTimeCache) + <_AndroidBuildPropertiesCache Condition=" '$(DesignTimeBuild)' == 'true' ">$(_AndroidDesignTimeBuildPropertiesCache) - + @@ -1147,11 +1150,10 @@ because xbuild doesn't support framework reference assemblies. <_AndroidStaticResourcesFlag>$(IntermediateOutputPath)static.flag <_AndroidResourcesCacheFile>$(IntermediateOutputPath)mergeresources.cache True - <_AndroidDesignTimeResDirIntermediate>$(IntermediateOutputPath)designtime\ - <_AndroidResourcePathsDesignTimeCache>$(_AndroidDesignTimeResDirIntermediate)resourcepaths.cache - <_AndroidLibraryImportsDesignTimeCache>$(_AndroidDesignTimeResDirIntermediate)libraryimports.cache - <_AndroidLibraryProjectImportsDesignTimeCache>$(_AndroidDesignTimeResDirIntermediate)libraryprojectimports.cache - <_AndroidManagedResourceDesignerFile>$(_AndroidDesignTimeResDirIntermediate)$(_AndroidResourceDesigner) + <_AndroidResourcePathsDesignTimeCache>$(_AndroidIntermediateDesignTimeBuildDirectory)resourcepaths.cache + <_AndroidLibraryImportsDesignTimeCache>$(_AndroidIntermediateDesignTimeBuildDirectory)libraryimports.cache + <_AndroidLibraryProjectImportsDesignTimeCache>$(_AndroidIntermediateDesignTimeBuildDirectory)libraryprojectimports.cache + <_AndroidManagedResourceDesignerFile>$(_AndroidIntermediateDesignTimeBuildDirectory)$(_AndroidResourceDesigner) @@ -1216,7 +1218,7 @@ because xbuild doesn't support framework reference assemblies. Inputs="$(_ManagedUpdateAndroidResgenInputs);$(_AndroidResourcePathsCache);$(_AndroidLibraryProjectImportsCache);$(_AndroidLibraryImportsCache);" Outputs="$(_AndroidManagedResourceDesignerFile)" DependsOnTargets="_CreatePropertiesCache;_ExtractLibraryProjectImports;_CreateAdditionalResourceCache"> - + - +