diff --git a/msbuild/Xamarin.Mac.Tasks/Xamarin.Mac.Common.targets b/msbuild/Xamarin.Mac.Tasks/Xamarin.Mac.Common.targets
index 86229f5e0b..1ce80d8708 100644
--- a/msbuild/Xamarin.Mac.Tasks/Xamarin.Mac.Common.targets
+++ b/msbuild/Xamarin.Mac.Tasks/Xamarin.Mac.Common.targets
@@ -27,8 +27,10 @@ Copyright (C) 2014 Xamarin. All rights reserved.
+
+
@@ -73,6 +75,12 @@ Copyright (C) 2014 Xamarin. All rights reserved.
<_PreparedResourceRules>
<_AppBundleName>$(AssemblyName)
+
+
+
+ <_ACTool_PartialAppManifestCache>$(IntermediateOutputPath)actool\_PartialAppManifest.items
+ <_ACTool_BundleResourceCache>$(IntermediateOutputPath)actool\_BundleResourceWithLogicalName.items
+
@@ -558,12 +566,40 @@ Copyright (C) 2014 Xamarin. All rights reserved.
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png
new file mode 100644
index 0000000000..d0b5a8098e
Binary files /dev/null and b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png differ
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png
new file mode 100644
index 0000000000..f4c8d29047
Binary files /dev/null and b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png differ
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png
new file mode 100644
index 0000000000..ebb5a0fe4e
Binary files /dev/null and b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png differ
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png
new file mode 100644
index 0000000000..0986d31beb
Binary files /dev/null and b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png differ
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png
new file mode 100644
index 0000000000..a142c83fb1
Binary files /dev/null and b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png differ
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png
new file mode 100644
index 0000000000..0986d31beb
Binary files /dev/null and b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png differ
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png
new file mode 100644
index 0000000000..412d6ca9b4
Binary files /dev/null and b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png differ
diff --git a/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/Contents.json b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..deda2078f0
--- /dev/null
+++ b/tests/common/mac/Icons/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,238 @@
+{
+ "images": [
+ {
+ "size": "20x20",
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "20x20",
+ "scale": "3x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "29x29",
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "29x29",
+ "scale": "3x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "40x40",
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "40x40",
+ "scale": "3x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "60x60",
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "60x60",
+ "scale": "3x",
+ "idiom": "iphone"
+ },
+ {
+ "size": "20x20",
+ "scale": "1x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "20x20",
+ "scale": "2x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "29x29",
+ "scale": "1x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "29x29",
+ "scale": "2x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "40x40",
+ "scale": "1x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "40x40",
+ "scale": "2x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "83.5x83.5",
+ "scale": "2x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "76x76",
+ "scale": "1x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "76x76",
+ "scale": "2x",
+ "idiom": "ipad"
+ },
+ {
+ "size": "1024x1024",
+ "scale": "1x",
+ "idiom": "ios-marketing"
+ },
+ {
+ "size": "60x60",
+ "scale": "2x",
+ "idiom": "car"
+ },
+ {
+ "size": "60x60",
+ "scale": "3x",
+ "idiom": "car"
+ },
+ {
+ "role": "notificationCenter",
+ "size": "24x24",
+ "subtype": "38mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "notificationCenter",
+ "size": "27.5x27.5",
+ "subtype": "42mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "companionSettings",
+ "size": "29x29",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "companionSettings",
+ "size": "29x29",
+ "scale": "3x",
+ "idiom": "watch"
+ },
+ {
+ "role": "appLauncher",
+ "size": "40x40",
+ "subtype": "38mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "appLauncher",
+ "size": "44x44",
+ "subtype": "40mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "appLauncher",
+ "size": "50x50",
+ "subtype": "44mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "quickLook",
+ "size": "86x86",
+ "subtype": "38mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "quickLook",
+ "size": "98x98",
+ "subtype": "42mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "role": "quickLook",
+ "size": "108x108",
+ "subtype": "44mm",
+ "scale": "2x",
+ "idiom": "watch"
+ },
+ {
+ "size": "1024x1024",
+ "scale": "1x",
+ "idiom": "watch-marketing"
+ },
+ {
+ "filename": "AppIcon-16.png",
+ "size": "16x16",
+ "scale": "1x",
+ "idiom": "mac"
+ },
+ {
+ "filename": "AppIcon-16@2x.png",
+ "size": "16x16",
+ "scale": "2x",
+ "idiom": "mac"
+ },
+ {
+ "filename": "AppIcon-32.png",
+ "size": "32x32",
+ "scale": "1x",
+ "idiom": "mac"
+ },
+ {
+ "filename": "AppIcon-32@2x.png",
+ "size": "32x32",
+ "scale": "2x",
+ "idiom": "mac"
+ },
+ {
+ "filename": "AppIcon-128.png",
+ "size": "128x128",
+ "scale": "1x",
+ "idiom": "mac"
+ },
+ {
+ "filename": "AppIcon-128@2x.png",
+ "size": "128x128",
+ "scale": "2x",
+ "idiom": "mac"
+ },
+ {
+ "size": "256x256",
+ "scale": "1x",
+ "idiom": "mac"
+ },
+ {
+ "filename": "AppIcon-256@2x.png",
+ "size": "256x256",
+ "scale": "2x",
+ "idiom": "mac"
+ },
+ {
+ "size": "512x512",
+ "scale": "1x",
+ "idiom": "mac"
+ },
+ {
+ "size": "512x512",
+ "scale": "2x",
+ "idiom": "mac"
+ }
+ ],
+ "info": {
+ "version": 1,
+ "author": "xcode"
+ }
+}
\ No newline at end of file
diff --git a/tests/common/mac/Icons/Assets.xcassets/Contents.json b/tests/common/mac/Icons/Assets.xcassets/Contents.json
new file mode 100644
index 0000000000..4caf392f92
--- /dev/null
+++ b/tests/common/mac/Icons/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/tests/common/mac/ProjectTestHelpers.cs b/tests/common/mac/ProjectTestHelpers.cs
index 92bf8d7e25..0911433013 100644
--- a/tests/common/mac/ProjectTestHelpers.cs
+++ b/tests/common/mac/ProjectTestHelpers.cs
@@ -161,6 +161,9 @@ namespace Xamarin.MMP.Tests
public string APIDefinitionConfig { get; set; }
public string StructsAndEnumsConfig { get; set; }
+ // Unified Executable Specific
+ public bool AssetIcons { get; set; }
+
// Generated by TestUnifiedExecutable/TestSystemMonoExecutable and added to TestCode
public Guid guid { get; set; }
@@ -306,6 +309,24 @@ namespace Xamarin.MMP.Tests
string sourceDir = FindSourceDirectory ();
+ if (config.AssetIcons)
+ {
+ RunAndAssert ("/bin/cp", $"-R {Path.Combine (sourceDir, "Icons/Assets.xcassets")} {config.TmpDir}", "Copy Asset Icons");
+ config.ItemGroup += @"
+
+
+
+
+
+
+
+
+
+ ";
+ // HACK - Should process using CopyFileWithSubstitutions
+ config.PlistReplaceStrings.Add ("", @"XSAppIconAssetsAssets.xcassets/AppIcon.appiconset");
+ }
+
CopyFileWithSubstitutions (Path.Combine (sourceDir, "Info-Unified.plist"), Path.Combine (config.TmpDir, "Info.plist"), text => {
foreach (var key in config.PlistReplaceStrings.Keys)
text = text.Replace (key, config.PlistReplaceStrings [key]);
diff --git a/tests/mmptest/src/MMPTest.cs b/tests/mmptest/src/MMPTest.cs
index 2784fa1457..f88af1830b 100644
--- a/tests/mmptest/src/MMPTest.cs
+++ b/tests/mmptest/src/MMPTest.cs
@@ -674,5 +674,28 @@ namespace Xamarin.MMP.Tests
rv.Messages.AssertWarningCount (0);
});
}
+
+ // [Test] - https://github.com/xamarin/xamarin-macios/issues/4110
+ public void BuildingSameSolutionTwice_ShouldNotRunACToolTwice ()
+ {
+ RunMMPTest (tmpDir => {
+ TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) {
+ AssetIcons = true
+ };
+
+ string project = TI.GenerateUnifiedExecutableProject (test);
+
+ string buildOutput = TI.BuildProject (project, true, diagnosticMSBuild: true, useMSBuild: true);
+ Assert.True (buildOutput.Contains ("actool execution started with arguments"), $"Initial build should run actool");
+
+ buildOutput = TI.BuildProject (project, true, diagnosticMSBuild: true, useMSBuild: true);
+ Assert.False (buildOutput.Contains ("actool execution started with arguments"), $"Second build should not run actool");
+
+ TI.RunAndAssert ("touch", Path.Combine (tmpDir, "Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png"), "touch icon");
+
+ buildOutput = TI.BuildProject (project, true, diagnosticMSBuild: true, useMSBuild: true);
+ Assert.True (buildOutput.Contains ("actool execution started with arguments"), $"Build after touching icon must run actool");
+ });
+ }
}
}