diff --git a/Documentation/guides/messages/README.md b/Documentation/guides/messages/README.md index af06e1bd243..6a4feb91b2e 100644 --- a/Documentation/guides/messages/README.md +++ b/Documentation/guides/messages/README.md @@ -222,6 +222,10 @@ Exceptions that have not been gracefully handled yet. Ideally these will be fix These take the form of `XACCC7NNN`, where `CCC` is a 3 character code denoting the MSBuild Task that is throwing the exception, and `NNN` is a 3 digit number indicating the type of the unhandled `Exception`. +## XA8xxx: Linker Step Errors + ++ [XA8000/IL8000](xa8000.md): Could not find Android Resource '@anim/enterfromright'. Please update @(AndroidResource) to add the missing resource. + **Tasks:** * `A2C` - `Aapt2Compile` * `A2L` - `Aapt2Link` diff --git a/Documentation/guides/messages/xa8000.md b/Documentation/guides/messages/xa8000.md new file mode 100644 index 00000000000..5b09ba1251f --- /dev/null +++ b/Documentation/guides/messages/xa8000.md @@ -0,0 +1,21 @@ +--- +title: Xamarin.Android warning XA8000/IL8000 +description: XA8000/IL8000 error code +ms.date: 06/01/2023 +--- +# Xamarin.Android error XA8000/IL8000 + +## Issue + +``` +Could not find Android Resource '@anim/enterfromright'. Please update @(AndroidResource) to add the missing resource. +``` + +## Solution + +When trying to upgrade older nuget package references to use the +more recent Resource Designer Assembly, the system might encounter +fields which cannot be upgraded because the resource is missing +from either the dependency or the app. + +To fix this issue the missing `AndroidResource` needs to be added to the application. Or the Nuget should be upgraded to use .net 8 or later. \ No newline at end of file diff --git a/build-tools/scripts/UpdateApkSizeReference.sh b/build-tools/scripts/UpdateApkSizeReference.sh index 55bc755de94..6bfd1f05278 100755 --- a/build-tools/scripts/UpdateApkSizeReference.sh +++ b/build-tools/scripts/UpdateApkSizeReference.sh @@ -1,4 +1,3 @@ #!/bin/bash -./build-tools/scripts/nunit3-console bin/TestRelease/net472/Xamarin.Android.Build.Tests.dll --test=Xamarin.Android.Build.Tests.BuildTest2.BuildReleaseArm64 ./dotnet-local.sh test bin/TestRelease/net7.0/Xamarin.Android.Build.Tests.dll --filter=Name~BuildReleaseArm64 cp bin/TestRelease/BuildReleaseArm64*.apkdesc src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/ \ No newline at end of file diff --git a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs index 6a5d84b56eb..e9883a88c78 100644 --- a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs +++ b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.Designer.cs @@ -10,8 +10,8 @@ namespace Microsoft.Android.Sdk.ILLink.Properties { using System; - - + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -23,15 +23,15 @@ namespace Microsoft.Android.Sdk.ILLink.Properties { [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { - + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// @@ -45,7 +45,7 @@ internal Resources() { return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. @@ -59,7 +59,7 @@ internal Resources() { resourceCulture = value; } } - + /// /// Looks up a localized string similar to Use of AppDomain.CreateDomain() detected in assembly: {0}. .NET 6 and higher will only support a single AppDomain, so this API will no longer be available in Xamarin.Android once .NET 6 is released.. /// @@ -68,5 +68,14 @@ public static string XA2000 { return ResourceManager.GetString("XA2000", resourceCulture); } } + + /// + /// Looks up a localized string similar to Could not find an 'AndroidResource' for 'anim'. + /// + public static string XA8000 { + get { + return ResourceManager.GetString("XA8000", resourceCulture); + } + } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx index 6d76ecca22f..0e3f8e775d4 100644 --- a/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx +++ b/src/Microsoft.Android.Sdk.ILLink/Properties/Resources.resx @@ -122,4 +122,10 @@ The following are literal names and should not be translated: AppDomain.CreateDomain(), AppDomain {0} - The name of the assembly + + Could not find Android Resource '{0}'. Please update @(AndroidResource) to add the missing resource. + +{0} - An Android Resource Identifier. + + \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs index d5ca2e4c65c..2f8569f515a 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using Mono.Cecil; @@ -13,6 +14,9 @@ using Mono.Tuner; #if ILLINK using Microsoft.Android.Sdk.ILLink; +using Resources = Microsoft.Android.Sdk.ILLink.Properties.Resources; +#else // !ILLINK +using Resources = Xamarin.Android.Tasks.Properties.Resources; #endif // ILLINK namespace MonoDroid.Tuner @@ -120,6 +124,17 @@ Dictionary BuildResourceDesignerPropertyLookup (TypeDe return output; } + string GetNativeTypeNameFromManagedTypeName (string name) + { + switch (name) { + case "Animation": return "anim"; + case "Attribute": return "attr"; + case "Boolean": return "bool"; + case "Dimension": return "dimen"; + default: return name.ToLower (); + } + } + protected override void FixBody (MethodBody body, TypeDefinition designer) { // replace @@ -144,6 +159,14 @@ protected override void FixBody (MethodBody body, TypeDefinition designer) instructions.Add (i, newIn); } else { LogMessage ($"DEBUG! Failed to find {key}!"); + // The 'key' in this case will be something like Layout::Toolbar. + // We want format this into @layout/Toolbar so its easier to understand + // for the user. + var index = key.IndexOf ("::"); + var typeName = GetNativeTypeNameFromManagedTypeName (key.Substring (0, index)); + var identifier = key.Substring (index + 2); + var msg = string.Format (CultureInfo.CurrentCulture, Resources.XA8000, $"@{typeName}/{identifier}"); + LogError (8000, msg); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs index 2c30e4ba228..d8c65f1b573 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs @@ -21,6 +21,15 @@ public virtual void LogMessage (string message) Context.LogMessage (message); } + public virtual void LogError (int code, string error) + { +#if ILLINK + Context.LogMessage (MessageContainer.CreateCustomErrorMessage (error, code, origin: new MessageOrigin ())); +#else // !ILLINK + Console.Error.WriteLine ($"error XA{code}: {error}"); +#endif // !ILLINK + } + public virtual AssemblyDefinition Resolve (AssemblyNameReference name) { return Context.Resolve (name); diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs index a5f6eb2399f..7fe1bf1c1ae 100644 --- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs +++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs @@ -116,6 +116,15 @@ public static string XA_Directory_Is_From { } } + /// + /// Looks up a localized string similar to Could not find an 'AndroidResource' for 'anim'. + /// + public static string XA8000 { + get { + return ResourceManager.GetString("XA8000", resourceCulture); + } + } + /// /// Looks up a localized string similar to /// This code was generated by a tool. diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx index 768256ab6e6..dfb964b4851 100644 --- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx +++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx @@ -933,4 +933,10 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS {1} - A Filename. + + Could not find Android Resource '{0}'. Please update @(AndroidResource) to add the missing resource. + +{0} - An Android Resource Identifier. + + diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs index 78804fcf315..2d42039fce2 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs @@ -142,6 +142,11 @@ public override void LogMessage (string message) logger.LogDebugMessage ("{0}", message); } + public override void LogError (int code, string message) + { + logger.LogCodedError ($"XA{code}", message); + } + public override AssemblyDefinition Resolve (AssemblyNameReference name) { return resolver.Resolve (name); 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 007ff8d4172..c4dca5c2b42 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 @@ -593,6 +593,14 @@ public static class KnownPackages Id = "Mono.AotProfiler.Android", Version = "7.0.0-preview1", }; + public static Package SkiaSharp = new Package () { + Id = "SkiaSharp", + Version = "2.88.3", + }; + public static Package SkiaSharp_Views = new Package () { + Id = "SkiaSharp.Views", + Version = "2.88.3", + }; } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index dc72d5e2ad3..74cdceacd9e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -8,58 +8,58 @@ "Size": 1024 }, "assemblies/Java.Interop.dll": { - "Size": 58913 + "Size": 58703 }, "assemblies/Mono.Android.dll": { - "Size": 87163 + "Size": 86588 }, "assemblies/Mono.Android.Runtime.dll": { - "Size": 5895 + "Size": 5798 }, "assemblies/rc.bin": { - "Size": 1182 + "Size": 1235 }, "assemblies/System.Console.dll": { - "Size": 6438 + "Size": 6442 }, "assemblies/System.Linq.dll": { - "Size": 9122 + "Size": 9123 }, "assemblies/System.Private.CoreLib.dll": { - "Size": 516811 + "Size": 536436 }, "assemblies/System.Runtime.dll": { - "Size": 2620 + "Size": 2623 }, "assemblies/System.Runtime.InteropServices.dll": { - "Size": 3753 + "Size": 3752 }, "assemblies/UnnamedProject.dll": { - "Size": 3219 + "Size": 3349 }, "classes.dex": { - "Size": 19020 + "Size": 19748 }, "lib/arm64-v8a/libmono-component-marshal-ilgen.so": { "Size": 93552 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 379320 + "Size": 380832 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3090760 + "Size": 3160360 }, "lib/arm64-v8a/libSystem.IO.Compression.Native.so": { - "Size": 723840 + "Size": 723560 }, "lib/arm64-v8a/libSystem.Native.so": { - "Size": 94328 + "Size": 94392 }, "lib/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so": { - "Size": 155056 + "Size": 154904 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 16720 + "Size": 16624 }, "META-INF/BNDLTOOL.RSA": { "Size": 1213 @@ -95,5 +95,5 @@ "Size": 1904 } }, - "PackageSize": 2632010 + "PackageSize": 2685258 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc index 415590216dc..26e5420ad28 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc @@ -5,136 +5,136 @@ "Size": 3568 }, "assemblies/_Microsoft.Android.Resource.Designer.dll": { - "Size": 1940 + "Size": 2102 }, "assemblies/FormsViewGroup.dll": { "Size": 7313 }, "assemblies/Java.Interop.dll": { - "Size": 66903 + "Size": 66576 }, "assemblies/Mono.Android.dll": { - "Size": 468307 + "Size": 446254 }, "assemblies/Mono.Android.Runtime.dll": { - "Size": 5894 + "Size": 5798 }, "assemblies/mscorlib.dll": { "Size": 3860 }, "assemblies/netstandard.dll": { - "Size": 5579 + "Size": 5573 }, "assemblies/rc.bin": { "Size": 1235 }, "assemblies/System.Collections.Concurrent.dll": { - "Size": 11557 + "Size": 11553 }, "assemblies/System.Collections.dll": { - "Size": 15441 + "Size": 15400 }, "assemblies/System.Collections.NonGeneric.dll": { - "Size": 7500 + "Size": 7494 }, "assemblies/System.ComponentModel.dll": { - "Size": 1968 + "Size": 1967 }, "assemblies/System.ComponentModel.Primitives.dll": { - "Size": 2593 + "Size": 2588 }, "assemblies/System.ComponentModel.TypeConverter.dll": { "Size": 6076 }, "assemblies/System.Console.dll": { - "Size": 6610 + "Size": 6609 }, "assemblies/System.Core.dll": { - "Size": 1990 + "Size": 1986 }, "assemblies/System.Diagnostics.TraceSource.dll": { - "Size": 6588 + "Size": 6584 }, "assemblies/System.dll": { - "Size": 2342 + "Size": 2341 }, "assemblies/System.Drawing.dll": { - "Size": 1935 + "Size": 1932 }, "assemblies/System.Drawing.Primitives.dll": { - "Size": 12009 + "Size": 12005 }, "assemblies/System.IO.Compression.Brotli.dll": { - "Size": 11221 + "Size": 11217 }, "assemblies/System.IO.Compression.dll": { - "Size": 15894 + "Size": 15897 }, "assemblies/System.IO.IsolatedStorage.dll": { - "Size": 9907 + "Size": 10006 }, "assemblies/System.Linq.dll": { - "Size": 19490 + "Size": 19433 }, "assemblies/System.Linq.Expressions.dll": { - "Size": 164338 + "Size": 164136 }, "assemblies/System.Net.Http.dll": { - "Size": 65558 + "Size": 65503 }, "assemblies/System.Net.Primitives.dll": { - "Size": 22469 + "Size": 22470 }, "assemblies/System.Net.Requests.dll": { - "Size": 3627 + "Size": 3624 }, "assemblies/System.ObjectModel.dll": { - "Size": 8156 + "Size": 8155 }, "assemblies/System.Private.CoreLib.dll": { - "Size": 834087 + "Size": 832191 }, "assemblies/System.Private.DataContractSerialization.dll": { - "Size": 192362 + "Size": 191999 }, "assemblies/System.Private.Uri.dll": { - "Size": 42946 + "Size": 42894 }, "assemblies/System.Private.Xml.dll": { - "Size": 215916 + "Size": 215865 }, "assemblies/System.Private.Xml.Linq.dll": { - "Size": 16683 + "Size": 16669 }, "assemblies/System.Runtime.dll": { - "Size": 2773 + "Size": 2769 }, "assemblies/System.Runtime.InteropServices.dll": { - "Size": 3756 + "Size": 3752 }, "assemblies/System.Runtime.Serialization.dll": { - "Size": 1861 + "Size": 1860 }, "assemblies/System.Runtime.Serialization.Formatters.dll": { - "Size": 2514 + "Size": 2512 }, "assemblies/System.Runtime.Serialization.Primitives.dll": { - "Size": 3801 + "Size": 3797 }, "assemblies/System.Security.Cryptography.dll": { - "Size": 7841 + "Size": 7839 }, "assemblies/System.Text.RegularExpressions.dll": { - "Size": 159003 + "Size": 158406 }, "assemblies/System.Xml.dll": { - "Size": 1755 + "Size": 1753 }, "assemblies/System.Xml.Linq.dll": { - "Size": 1776 + "Size": 1770 }, "assemblies/UnnamedProject.dll": { - "Size": 5294 + "Size": 5423 }, "assemblies/Xamarin.AndroidX.Activity.dll": { "Size": 5942 @@ -191,7 +191,7 @@ "Size": 528450 }, "assemblies/Xamarin.Forms.Platform.Android.dll": { - "Size": 337831 + "Size": 337925 }, "assemblies/Xamarin.Forms.Platform.dll": { "Size": 11080 @@ -209,10 +209,10 @@ "Size": 93552 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 380736 + "Size": 380832 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3166048 + "Size": 3160360 }, "lib/arm64-v8a/libSystem.IO.Compression.Native.so": { "Size": 723560 @@ -224,7 +224,7 @@ "Size": 154904 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 333784 + "Size": 333736 }, "META-INF/android.support.design_material.version": { "Size": 12 @@ -1979,5 +1979,5 @@ "Size": 341228 } }, - "PackageSize": 7930717 + "PackageSize": 7877469 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs b/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs index ed7aa317780..d2d1f6aa42b 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/RtxtParser.cs @@ -119,7 +119,7 @@ void ProcessRtxtFile (string file, IList result) continue; } int value = items [1] != "styleable" ? Convert.ToInt32 (items [3].Trim (), 16) : -1; - string itemName = ResourceIdentifier.GetResourceName(items [1], items [2], map, log); + string itemName = ResourceIdentifier.GetResourceName(ResourceParser.GetNestedTypeName (items [1]), items [2], map, log); if (knownTypes.Contains (items [1])) { if (items [1] != "styleable") { result.Add (new R () { diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs index 8e8c6b1b360..0ece2f8f233 100644 --- a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs @@ -914,6 +914,122 @@ public void CheckXamarinFormsAppDeploysAndAButtonWorks () }, Path.Combine (Root, builder.ProjectDirectory, "button-logcat.log")), "Button Should have been Clicked."); } + [Test] + public void SkiaSharpCanvasBasedAppRuns ([Values (true, false)] bool isRelease, [Values (true, false)] bool addResource) + { + var app = new XamarinAndroidApplicationProject () { + IsRelease = isRelease, + PackageName = "Xamarin.SkiaSharpCanvasTest", + PackageReferences = { + KnownPackages.SkiaSharp, + KnownPackages.SkiaSharp_Views, + KnownPackages.AndroidXAppCompat, + KnownPackages.AndroidXAppCompatResources, + }, + }; + app.AndroidResources.Add (new AndroidItem.AndroidResource ("Resources\\values\\styles.xml") { + TextContent = () => @"