diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs b/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs index 4115073151c..8edd9df3e2c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs @@ -61,6 +61,9 @@ public class AndroidComputeResPaths : AndroidTask [Output] public ITaskItem [] ResolvedResourceFiles { get; set; } + [Output] + public string FilesHash { get; set; } + public override bool RunTask () { var intermediateFiles = new List (ResourceFiles.Length); @@ -77,6 +80,7 @@ public override bool RunTask () } var nameCaseMap = new Dictionary (ResourceFiles.Length, StringComparer.Ordinal); + var sb = new StringBuilder (); for (int i = 0; i < ResourceFiles.Length; i++) { var item = ResourceFiles [i]; @@ -151,10 +155,13 @@ public override bool RunTask () item.CopyMetadataTo (newItem); intermediateFiles.Add (newItem); resolvedFiles.Add (item); + // write both files so we handle changes in destination also + sb.AppendLine ($"{item.ItemSpec};{newItem.ItemSpec}"); } IntermediateFiles = intermediateFiles.ToArray (); ResolvedResourceFiles = resolvedFiles.ToArray (); + FilesHash = Files.HashString (sb.ToString ()); MonoAndroidHelper.SaveResourceCaseMap (BuildEngine4, nameCaseMap, ProjectSpecificTaskObjectKey); return !Log.HasLoggedErrors; } 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 a06312f2fb3..b54406422bc 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 @@ -902,6 +902,29 @@ ReadLibraryProjectImportsCache ReadCache (string cacheFile) return task; } + [Test] + [NonParallelizable] + public void AddNewAndroidResourceOnSecondBuild () + { + var xml = new AndroidItem.AndroidResource (@"Resources\values\emptyvalues.xml") { + TextContent = () => "" + }; + + var proj = new XamarinAndroidApplicationProject (); + using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) { + var projectFile = Path.Combine (Root, b.ProjectDirectory, proj.ProjectFilePath); + b.ThrowOnBuildFailure = false; + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + b.Output.AssertTargetIsNotSkipped ("_GenerateAndroidResourceDir"); + proj.OtherBuildItems.Add (xml); + b.Save (proj, doNotCleanupOnUpdate: true); + var modified = File.GetLastWriteTimeUtc (Path.Combine (Root, b.ProjectDirectory, "Resources","layout","Main.axml")); + File.SetLastWriteTimeUtc (Path.Combine (Root, b.ProjectDirectory, "Resources","values", "emptyvalues.xml"), modified); + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + b.Output.AssertTargetIsNotSkipped ("_GenerateAndroidResourceDir"); + } + } + [Test] [NonParallelizable] public void InvalidAndroidResource () diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 19a844eab71..74b3b78a750 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -232,6 +232,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. <_AndroidBuildIdFile>$(IntermediateOutputPath)buildid.txt <_AndroidApplicationSharedLibraryPath>$(IntermediateOutputPath)app_shared_libraries\ <_ResolvedUserAssembliesHashFile>$(IntermediateOutputPath)resolvedassemblies.hash + <_AndroidResolvedResourcesHashFile>$(IntermediateOutputPath)_AndroidResolvedResources.hash d8 <_AndroidXA1027 Condition=" '$(EnableProguard)' == 'true' And '$(AndroidEnableProguard)' == '' And '$(AndroidDexTool)' == 'd8' And $(AndroidLinkTool) == '' ">true @@ -1057,13 +1058,24 @@ because xbuild doesn't support framework reference assemblies. > + + + + + +