From f249070643499d0bb3ac61abc44a278ce2ded5a1 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 25 Oct 2023 13:18:32 +0100 Subject: [PATCH 1/8] Initial Commit --- .../Microsoft.Android.Sdk/Sdk/AutoImport.props | 5 +++++ .../Xamarin.Android.Common.targets | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props index 7bde84e8ee2..553f3f20d8c 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props @@ -61,4 +61,9 @@ https://github.com/dotnet/designs/blob/4703666296f5e59964961464c25807c727282cae/ + + + + + diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 330b30f9a7e..98d2b91d304 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -358,11 +358,6 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. - - - - - $(IntermediateOutputPath)assets\ From 575cd4113d16e92ffac7014e675166fb5ccea844 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 25 Oct 2023 15:24:24 +0100 Subject: [PATCH 2/8] Add Tests --- .../Sdk/AutoImport.props | 3 +- .../Tasks/BuildApk.cs | 24 ++++++++-- .../PackagingTest.cs | 45 +++++++++++++++++++ .../Android/KnownPackages.cs | 4 ++ .../Xamarin.Android.Common.targets | 2 + 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props index 553f3f20d8c..24e3ed08a61 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props @@ -63,7 +63,8 @@ https://github.com/dotnet/designs/blob/4703666296f5e59964961464c25807c727282cae/ - + + diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs index fbcaa1e0944..0a15a2b8a26 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs @@ -76,6 +76,8 @@ public class BuildApk : AndroidTask public string [] ExcludeFiles { get; set; } + public string [] IncludeFiles { get; set; } + public string Debug { get; set; } public string AndroidSequencePointsMode { get; set; } @@ -130,6 +132,8 @@ protected virtual void FixupArchive (ZipArchiveEx zip) { } List excludePatterns = new List (); + List includePatterns = new List (); + void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOutputPath, bool debug, bool compress, IDictionary compressedAssembliesInfo, string assemblyStoreApkName) { ArchiveFileList files = new ArchiveFileList (); @@ -258,13 +262,22 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut } // check for ignored items bool exclude = false; - foreach (var pattern in excludePatterns) { - if(pattern.IsMatch (path)) { - Log.LogDebugMessage ($"Ignoring jar entry '{name}' from '{Path.GetFileName (jarFile)}'. Filename matched the exclude pattern '{pattern}'."); - exclude = true; + bool forceInclude = false; + foreach (var include in includePatterns) { + if (include.IsMatch (path)) { + forceInclude = true; break; } } + if (!forceInclude) { + foreach (var pattern in excludePatterns) { + if(pattern.IsMatch (path)) { + Log.LogDebugMessage ($"Ignoring jar entry '{name}' from '{Path.GetFileName (jarFile)}'. Filename matched the exclude pattern '{pattern}'."); + exclude = true; + break; + } + } + } if (exclude) continue; if (string.Compare (Path.GetFileName (name), "AndroidManifest.xml", StringComparison.OrdinalIgnoreCase) == 0) { @@ -310,6 +323,9 @@ public override bool RunTask () foreach (var pattern in ExcludeFiles ?? Array.Empty ()) { excludePatterns.Add (FileGlobToRegEx (pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled)); } + foreach (var pattern in IncludeFiles ?? Array.Empty ()) { + includePatterns.Add (FileGlobToRegEx (pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled)); + } bool debug = _Debug; bool compress = !debug && EnableCompression; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs index 9e7facc32e7..7e51d2cdacb 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs @@ -610,6 +610,51 @@ public void CheckExcludedFilesAreMissing () } } + [Test] + public void CheckExcludedFilesCanBeModified () + { + + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + }; + proj.PackageReferences.Add (KnownPackages.Xamarin_Kotlin_StdLib_Common); + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + var apk = Path.Combine (Root, b.ProjectDirectory, + proj.OutputPath, $"{proj.PackageName}-Signed.apk"); + string expected = $"Ignoring jar entry 'kotlin/Error.kotlin_metadata'"; + Assert.IsTrue (b.LastBuildOutput.ContainsText (expected), $"Error.kotlin_metadata should have been ignored."); + using (var zip = ZipHelper.OpenZip (apk)) { + Assert.IsFalse (zip.ContainsEntry ("kotlin/Error.kotlin_metadata"), "Error.kotlin_metadata should have been ignored."); + } + proj.OtherBuildItems.Add (new BuildItem ("AndroidPackagingOptionsExclude") { + Remove = () => "$([MSBuild]::Escape('*.kotlin*'))", + }); + Assert.IsTrue (b.Clean (proj), "Clean should have succeeded."); + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + using (var zip = ZipHelper.OpenZip (apk)) { + Assert.IsTrue (zip.ContainsEntry ("kotlin/Error.kotlin_metadata"), "Error.kotlin_metadata should have been included."); + } + } + } + + [Test] + public void CheckIncludedFilesArePresent () + { + var proj = new XamarinAndroidApplicationProject () { + IsRelease = true, + }; + proj.PackageReferences.Add (KnownPackages.Xamarin_Kotlin_Reflect); + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + var apk = Path.Combine (Root, b.ProjectDirectory, + proj.OutputPath, $"{proj.PackageName}-Signed.apk"); + using (var zip = ZipHelper.OpenZip (apk)) { + Assert.IsTrue (zip.ContainsEntry ("kotlin/reflect/reflect.kotlin_builtins"), "reflect.kotlin_builtins should have been ignored."); + } + } + } + [Test] [TestCase (1, -1)] [TestCase (5, -1)] diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs index baac0375292..c71c3788615 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownPackages.cs @@ -523,6 +523,10 @@ public static class KnownPackages Id = "Xamarin.Kotlin.Stdlib.Common", Version = "1.6.20.1" }; + public static Package Xamarin_Kotlin_Reflect = new Package { + Id = "Xamarin.Kotlin.Reflect", + Version = "1.9.10.2" + }; public static Package Acr_UserDialogs = new Package { Id = "Acr.UserDialogs", Version = "8.0.1", diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 98d2b91d304..ad337416ebb 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -2131,6 +2131,7 @@ because xbuild doesn't support framework reference assemblies. CheckedBuild="$(_AndroidCheckedBuild)" RuntimeConfigBinFilePath="$(_BinaryRuntimeConfigPath)" ExcludeFiles="@(AndroidPackagingOptionsExclude)" + IncludeFiles="@(AndroidPackagingOptionsInclude)" ZipFlushFilesLimit="$(_ZipFlushFilesLimit)" ZipFlushSizeLimit="$(_ZipFlushSizeLimit)" UseAssemblyStore="$(AndroidUseAssemblyStore)"> @@ -2166,6 +2167,7 @@ because xbuild doesn't support framework reference assemblies. CheckedBuild="$(_AndroidCheckedBuild)" RuntimeConfigBinFilePath="$(_BinaryRuntimeConfigPath)" ExcludeFiles="@(AndroidPackagingOptionsExclude)" + IncludeFiles="@(AndroidPackagingOptionsInclude)" ZipFlushFilesLimit="$(_ZipFlushFilesLimit)" ZipFlushSizeLimit="$(_ZipFlushSizeLimit)" UseAssemblyStore="$(AndroidUseAssemblyStore)"> From bee8e2d9aaa823c7dfc2ee1c43673a55a1e2dce7 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 25 Oct 2023 20:40:58 +0100 Subject: [PATCH 3/8] Updated test --- .../Tests/Xamarin.Android.Build.Tests/PackagingTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs index 7e51d2cdacb..ba85fa6a001 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs @@ -650,7 +650,7 @@ public void CheckIncludedFilesArePresent () var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, $"{proj.PackageName}-Signed.apk"); using (var zip = ZipHelper.OpenZip (apk)) { - Assert.IsTrue (zip.ContainsEntry ("kotlin/reflect/reflect.kotlin_builtins"), "reflect.kotlin_builtins should have been ignored."); + Assert.IsTrue (zip.ContainsEntry ("kotlin/reflect/reflect.kotlin_builtins"), "reflect.kotlin_builtins should have been included."); } } } From ca5887729eaabd6fe8e6ca2c58afb01176c5b78f Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Thu, 26 Oct 2023 10:47:56 +0100 Subject: [PATCH 4/8] Add Docs --- .../guides/building-apps/build-items.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 6da648100fe..863b9a83080 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -222,8 +222,36 @@ This is so MSBuild does not try to interpret them as actual file wildcards. NOTE: `*`, `?` and `.` will be replaced in the `BuildApk` task with the appropriate RegEx expressions. +If the default file glob is too restrictive you can remove it by adding the +following to your csproj + +``` + + + +``` + Added in Xamarin.Android 13.1 and .NET 7. +## AndroidPackagingOptionsInclude + +A set of file glob compatible items which will allow for items to be +included from the final package. The default values are as follows + +``` + + + +``` +Items can use file blob characters for wildcards such as `*` and `?`. +However these Items MUST use URL encoding or '$([MSBuild]::Escape(''))'. +This is so MSBuild does not try to interpret them as actual file wildcards. + +NOTE: `*`, `?` and `.` will be replaced in the `BuildApk` task with the +appropriate RegEx expressions. + +Added in .NET 9. + ## AndroidResource All files with an *AndroidResource* build action are compiled into From 055f1556a5edddc831c85c567fd9b52ed26e3a17 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 1 Nov 2023 10:00:31 +0000 Subject: [PATCH 5/8] Change docs --- Documentation/guides/building-apps/build-items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 863b9a83080..84e14149d5f 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -220,7 +220,7 @@ However these Items MUST use URL encoding or '$([MSBuild]::Escape(''))'. This is so MSBuild does not try to interpret them as actual file wildcards. NOTE: `*`, `?` and `.` will be replaced in the `BuildApk` task with the -appropriate RegEx expressions. +appropriate file globs. If the default file glob is too restrictive you can remove it by adding the following to your csproj From 221dbea13851dcfaca567f940bff1f9cab04c2e2 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Thu, 2 Nov 2023 14:15:04 +0000 Subject: [PATCH 6/8] update docs --- Documentation/guides/building-apps/build-items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 84e14149d5f..e4df21c97aa 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -248,7 +248,7 @@ However these Items MUST use URL encoding or '$([MSBuild]::Escape(''))'. This is so MSBuild does not try to interpret them as actual file wildcards. NOTE: `*`, `?` and `.` will be replaced in the `BuildApk` task with the -appropriate RegEx expressions. +appropriate file globs. Added in .NET 9. From a93b22001eea0a2348c2b7b76ae43b2cc74296a5 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Thu, 2 Nov 2023 14:22:15 +0000 Subject: [PATCH 7/8] update docs --- Documentation/guides/building-apps/build-items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index e4df21c97aa..037bcd062ad 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -240,7 +240,7 @@ included from the final package. The default values are as follows ``` - + ``` Items can use file blob characters for wildcards such as `*` and `?`. From faf297e6340f360598c7f599e3a086d2db05b876 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 3 Nov 2023 09:51:43 +0000 Subject: [PATCH 8/8] update docs --- .../guides/building-apps/build-items.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 037bcd062ad..3994a28910f 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -215,10 +215,20 @@ excluded from the final package. The default values are as follows ``` + Items can use file blob characters for wildcards such as `*` and `?`. However these Items MUST use URL encoding or '$([MSBuild]::Escape(''))'. This is so MSBuild does not try to interpret them as actual file wildcards. +For example + +``` + + + + +``` + NOTE: `*`, `?` and `.` will be replaced in the `BuildApk` task with the appropriate file globs. @@ -243,9 +253,18 @@ included from the final package. The default values are as follows ``` + Items can use file blob characters for wildcards such as `*` and `?`. However these Items MUST use URL encoding or '$([MSBuild]::Escape(''))'. This is so MSBuild does not try to interpret them as actual file wildcards. +For example + +``` + + + + +``` NOTE: `*`, `?` and `.` will be replaced in the `BuildApk` task with the appropriate file globs.