From 22f10b2edec9e40a139c04564f96d8c1b3c17526 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Thu, 19 Jan 2023 15:24:25 +0000 Subject: [PATCH] Bump to xamarin/xamarin-android-tools/main@099fd95 (#7709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: https://github.com/dotnet/maui/issues/11605 Context: https://github.com/dotnet/maui/pull/11387#issuecomment-1318738792 Context: http://github.com/xamarin/xamarin-android/commit/8bc7a3e84f95e70fe12790ac31ecd97957771cb2 Changes: https://github.com/xamarin/xamarin-android-tools/compare/9f02d77692bca8c6585941de03750d5eaaca5c5a...099fd95f5459d9df78af0ad28f46e3016dd7ca1d * xamarin/xamarin-android-tools@099fd95: Add *Task.ProjectSpecificTaskObjectKey() for RegisterTaskObject() use (xamarin/xamarin-android-tools#202) * xamarin/xamarin-android-tools@ac9ea09: Revert IBuildEngine.ProjectFileOfTaskNode use. (xamarin/xamarin-android-tools#201) * xamarin/xamarin-android-tools@47f95ab: Fix CS0121 ambiguity errors. (xamarin/xamarin-android-tools#200) * xamarin/xamarin-android-tools@76c076f: Add support for Project Specific RegisterTaskObject. (xamarin/xamarin-android-tools#199) In dotnet/maui#11605, when `$(AndroidEnableMarshalMethods)`=True (xamarin/xamarin-android@8bc7a3e8), the build may fail if the `.sln` contains more than one Android "App" project. We tracked this down to "undesired sharing" between project builds; the `obj` provided to [`IBuildEngine4.RegisterTaskObject()`][0] can be visible across project builds. Consider [``][1]: var marshalMethodsState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (".:!MarshalMethods!:.", RegisteredTaskObjectLifetime.Build); Further consider a `.sln` with two "App" projects, as the "App" project build hits ``, e.g. the new `IncrementalBuildTest.BuildSolutionWithMultipleProjectsInParallel()` unit test. The lifetime of `RegisteredTaskObjectLifetime.Build` is *not* tied to the the `Build` target of a given `.csproj`; rather, it's for the *build process*. This can result in: 1. `dotnet build Project.sln` is run; `Project.sln` references `App1.csproj` and `App2.csproj`. 2. `App1.csproj` is built. 3. `App1.csproj` calls ``. 4. `App2.csproj` is later built as part of the process, and *also* calls ``. In particular note the key within ``: `".:!MarshalMethods!:."`. This value is identical in all projects, and means that that when `App2.csproj` is built, it will be using the same key as was used with `App1.csproj`, and thus could be inadvertently using data intended for `App1.csproj`! This would result build errors: …\Xamarin.Android.Common.targets(1717,3): error XAGPM7009: System.InvalidOperationException: Unable to translate assembly name 'Xamarin.AndroidX.Activity' to its index …\Xamarin.Android.Common.targets(1717,3): error XAGPM7009: at Xamarin.Android.Tasks.MarshalMethodsNativeAssemblyGenerator.WriteNativeMethods(LlvmIrGenerator generator, Dictionary`2 asmNameToIndex, LlvmIrVariableReference get_function_pointer_ref) …\Xamarin.Android.Common.targets(1717,3): error XAGPM7009: at Xamarin.Android.Tasks.MarshalMethodsNativeAssemblyGenerator.Write(LlvmIrGenerator generator) …\Xamarin.Android.Common.targets(1717,3): error XAGPM7009: at Xamarin.Android.Tasks.LLVMIR.LlvmIrComposer.Write(AndroidTargetArch arch, StreamWriter output, String fileName) …\Xamarin.Android.Common.targets(1717,3): error XAGPM7009: at Xamarin.Android.Tasks.GeneratePackageManagerJava.AddEnvironment() …\Xamarin.Android.Common.targets(1717,3): error XAGPM7009: at Xamarin.Android.Tasks.GeneratePackageManagerJava.RunTask() The sharing of `RegisterTaskObject()` data across project builds is rarely desirable. There are a few instances where it is safe to share the registered objects between projects, e.g. `java -version` version information (keyed on `java` path). However, most of the time it is specific to the project that is being built. Historically we have probably got away with this because "most" users only have one project. xamarin/xamarin-android-tools@099fd95 added the methods `AndroidTask.ProjectSpecificTaskObjectKey(object)`, `AndroidAsyncTask.ProjectSpecificTaskObjectKey(object)`, and `AndroidToolTask.ProjectSpecificTaskObjectKey(object)` which returns an `object` for use as the key to `RegisteredTaskObject()`, and the value is a tuple which includes the input `object` *and* the `Directory.GetCurrentDirectory()` value present when the task was created. (Background note: when MSBuild builds a project, it calls `Directory.SetCurrentDirectory()` to the directory of the current project, which is why relative file paths to work in `.csproj` files.) Review use of the `MSBuildExtensions.RegisterTaskObjectAssemblyLocal()` extension method and audit the key value. If the registered value is project specific, update the callsite to use `ProjectSpecificTaskObjectKey(object)`, ensuring that project-specific data is not accidentally reused in a different project. [0]: https://learn.microsoft.com/en-us/dotnet/api/microsoft.build.framework.ibuildengine4.registertaskobject?view=msbuild-17-netcore [1]: https://github.com/xamarin/xamarin-android/blob/c92ae5eb9fdcb3a2fd7c20f5b42dddf8b3ea781a/src/Xamarin.Android.Build.Tasks/Tasks/GeneratePackageManagerJava.cs#L407 [2]: https://github.com/xamarin/Xamarin.Build.AsyncTask/blob/8b5fc6c4d13a3dfd1d17a2007e2143b6da3447d7/Xamarin.Build.AsyncTask/AsyncTask.cs#L59 --- external/xamarin-android-tools | 2 +- src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs | 2 +- .../Tasks/Aapt2.cs | 2 +- .../Tasks/AndroidComputeResPaths.cs | 22 ++++++++--------- .../Tasks/CalculateLayoutCodeBehind.cs | 2 +- .../Tasks/ConvertCustomView.cs | 4 ++-- .../Tasks/ConvertResourcesCases.cs | 4 ++-- .../Tasks/GenerateJavaStubs.cs | 4 ++-- .../Tasks/GenerateJniRemappingNativeCode.cs | 2 +- .../Tasks/GenerateLayoutBindings.cs | 2 +- .../Tasks/GeneratePackageManagerJava.cs | 6 ++--- .../Tasks/GenerateResourceDesigner.cs | 2 +- .../Tasks/GenerateResourceDesignerAssembly.cs | 2 +- .../Tasks/GenerateRtxt.cs | 2 +- src/Xamarin.Android.Build.Tasks/Tasks/Lint.cs | 2 +- .../IncrementalBuildTest.cs | 24 +++++++++++++++++++ .../Tasks/Aapt2Tests.cs | 2 +- .../Tasks/ManagedResourceParserTests.cs | 4 ++++ .../Utilities/MonoAndroidHelper.cs | 8 +++---- 19 files changed, 63 insertions(+), 35 deletions(-) diff --git a/external/xamarin-android-tools b/external/xamarin-android-tools index 9f02d77692b..099fd95f545 160000 --- a/external/xamarin-android-tools +++ b/external/xamarin-android-tools @@ -1 +1 @@ -Subproject commit 9f02d77692bca8c6585941de03750d5eaaca5c5a +Subproject commit 099fd95f5459d9df78af0ad28f46e3016dd7ca1d diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs index e8b09e8cf33..28041f54c1e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs @@ -94,7 +94,7 @@ public class Aapt : AndroidAsyncTask AssemblyIdentityMap assemblyMap = new AssemblyIdentityMap (); string resourceDirectory; - Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4); + Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4, ProjectSpecificTaskObjectKey); bool ManifestIsUpToDate (string manifestFile) { diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs index c970b5b706d..084fd24d9ec 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt2.cs @@ -25,7 +25,7 @@ public abstract class Aapt2 : AndroidAsyncTask { private static readonly int DefaultMaxAapt2Daemons = 6; protected Dictionary _resource_name_case_map; - Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4); + Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4, ProjectSpecificTaskObjectKey); protected virtual int ProcessorCount => Environment.ProcessorCount; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs b/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs index e272340accf..96a3ccadbe9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/AndroidComputeResPaths.cs @@ -1,21 +1,21 @@ -// +// // AndroidUpdateResDir.cs -// +// // Author: // Michael Hutchinson -// +// // Copyright (c) 2010 Novell, Inc. (http://www.novell.com) -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -41,10 +41,10 @@ public class AndroidComputeResPaths : AndroidTask [Required] public ITaskItem[] ResourceFiles { get; set; } - + [Required] public string IntermediateDir { get; set; } - + public string Prefixes { get; set; } public bool LowercaseFilenames { get; set; } @@ -52,7 +52,7 @@ public class AndroidComputeResPaths : AndroidTask public string ProjectDir { get; set; } public string AndroidLibraryFlatFilesDirectory { get; set; } - + [Output] public ITaskItem[] IntermediateFiles { get; set; } @@ -63,7 +63,7 @@ public override bool RunTask () { var intermediateFiles = new List (ResourceFiles.Length); var resolvedFiles = new List (ResourceFiles.Length); - + string[] prefixes = Prefixes != null ? Prefixes.Split (';') : null; if (prefixes != null) { for (int i = 0; i < prefixes.Length; i++) { @@ -145,7 +145,7 @@ public override bool RunTask () IntermediateFiles = intermediateFiles.ToArray (); ResolvedResourceFiles = resolvedFiles.ToArray (); - MonoAndroidHelper.SaveResourceCaseMap (BuildEngine4, nameCaseMap); + MonoAndroidHelper.SaveResourceCaseMap (BuildEngine4, nameCaseMap, ProjectSpecificTaskObjectKey); return !Log.HasLoggedErrors; } } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CalculateLayoutCodeBehind.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CalculateLayoutCodeBehind.cs index fc32f3a743f..5759809c338 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CalculateLayoutCodeBehind.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CalculateLayoutCodeBehind.cs @@ -527,7 +527,7 @@ string RegisterGroupWidgets (ICollection widgets) { string key = Guid.NewGuid ().ToString (); LogDebugMessage ($"Registering {widgets?.Count} widgets for key {key}"); - BuildEngine4.RegisterTaskObjectAssemblyLocal (key, widgets, RegisteredTaskObjectLifetime.Build, allowEarlyCollection: false); + BuildEngine4.RegisterTaskObjectAssemblyLocal (ProjectSpecificTaskObjectKey (key), widgets, RegisteredTaskObjectLifetime.Build, allowEarlyCollection: false); return key; } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs index 9e88ff78d2f..89204b9fc05 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertCustomView.cs @@ -27,11 +27,11 @@ public class ConvertCustomView : AndroidTask { public ITaskItem [] Processed { get; set; } Dictionary _resource_name_case_map; - Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4); + Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4, ProjectSpecificTaskObjectKey); public override bool RunTask () { - var acw_map = MonoAndroidHelper.LoadMapFile (BuildEngine4, AcwMapFile, StringComparer.Ordinal); + var acw_map = MonoAndroidHelper.LoadMapFile (BuildEngine4, Path.GetFullPath (AcwMapFile), StringComparer.Ordinal); var customViewMap = MonoAndroidHelper.LoadCustomViewMapFile (BuildEngine4, CustomViewMapFile); var processed = new HashSet (); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs index e9655833993..2c9508c00aa 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs @@ -27,7 +27,7 @@ public class ConvertResourcesCases : AndroidTask Dictionary _resource_name_case_map; Dictionary> customViewMap; - Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4); + Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4, ProjectSpecificTaskObjectKey); public override bool RunTask () { @@ -73,7 +73,7 @@ void FixupResources (ITaskItem item) lastUpdate = File.GetLastWriteTimeUtc (AndroidConversionFlagFile); } Log.LogDebugMessage (" AndroidConversionFlagFile modified: {0}", lastUpdate); - + var resourcedirectories = new List (); foreach (var dir in ResourceDirectories) { if (dir == item) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs index c6896962d1d..e1c36a308d8 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs @@ -521,7 +521,7 @@ bool CreateJavaSources (IEnumerable javaTypes, TypeDefinitionCac } if (useMarshalMethods) { - BuildEngine4.RegisterTaskObjectAssemblyLocal (MarshalMethodsRegisterTaskKey, new MarshalMethodsState (classifier.MarshalMethods), RegisteredTaskObjectLifetime.Build); + BuildEngine4.RegisterTaskObjectAssemblyLocal (ProjectSpecificTaskObjectKey (MarshalMethodsRegisterTaskKey), new MarshalMethodsState (classifier.MarshalMethods), RegisteredTaskObjectLifetime.Build); } return ok; @@ -575,7 +575,7 @@ void WriteTypeMappings (List types, TypeDefinitionCache cache) if (!tmg.Generate (Debug, SkipJniAddNativeMethodRegistrationAttributeScan, types, cache, TypemapOutputDirectory, GenerateNativeAssembly, out ApplicationConfigTaskState appConfState)) throw new XamarinAndroidException (4308, Properties.Resources.XA4308); GeneratedBinaryTypeMaps = tmg.GeneratedBinaryTypeMaps.ToArray (); - BuildEngine4.RegisterTaskObjectAssemblyLocal (ApplicationConfigTaskState.RegisterTaskObjectKey, appConfState, RegisteredTaskObjectLifetime.Build); + BuildEngine4.RegisterTaskObjectAssemblyLocal (ProjectSpecificTaskObjectKey (ApplicationConfigTaskState.RegisterTaskObjectKey), appConfState, RegisteredTaskObjectLifetime.Build); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJniRemappingNativeCode.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJniRemappingNativeCode.cs index 2c22150f41e..7bd5824012a 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJniRemappingNativeCode.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJniRemappingNativeCode.cs @@ -93,7 +93,7 @@ void Generate (JniRemappingAssemblyGenerator jniRemappingGenerator, int typeRepl } BuildEngine4.RegisterTaskObjectAssemblyLocal ( - JniRemappingNativeCodeInfoKey, + ProjectSpecificTaskObjectKey (JniRemappingNativeCodeInfoKey), new JniRemappingNativeCodeInfo (typeReplacementsCount, jniRemappingGenerator.ReplacementMethodIndexEntryCount), RegisteredTaskObjectLifetime.Build ); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.cs index 1fb2ceffb0b..161fc7e374c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateLayoutBindings.cs @@ -209,7 +209,7 @@ void GenerateSourceForLayoutGroup (BindingGenerator generator, LayoutGroup group if (!GetRequiredMetadata (item, CalculateLayoutCodeBehind.WidgetCollectionKeyMetadata, out collectionKey)) return; - ICollection widgets = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal> (collectionKey, RegisteredTaskObjectLifetime.Build); + ICollection widgets = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal> (ProjectSpecificTaskObjectKey (collectionKey), RegisteredTaskObjectLifetime.Build); if ((widgets?.Count ?? 0) == 0) { string inputPaths = String.Join ("; ", resourceItems.Select (i => i.ItemSpec)); LogCodedWarning ("XA4222", Properties.Resources.XA4222, inputPaths); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GeneratePackageManagerJava.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GeneratePackageManagerJava.cs index a87f24a5832..f9616ef190d 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GeneratePackageManagerJava.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GeneratePackageManagerJava.cs @@ -370,8 +370,8 @@ void AddEnvironment () } bool haveRuntimeConfigBlob = !String.IsNullOrEmpty (RuntimeConfigBinFilePath) && File.Exists (RuntimeConfigBinFilePath); - var appConfState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (ApplicationConfigTaskState.RegisterTaskObjectKey, RegisteredTaskObjectLifetime.Build); - var jniRemappingNativeCodeInfo = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (GenerateJniRemappingNativeCode.JniRemappingNativeCodeInfoKey, RegisteredTaskObjectLifetime.Build); + var appConfState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (ProjectSpecificTaskObjectKey (ApplicationConfigTaskState.RegisterTaskObjectKey), RegisteredTaskObjectLifetime.Build); + var jniRemappingNativeCodeInfo = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (ProjectSpecificTaskObjectKey (GenerateJniRemappingNativeCode.JniRemappingNativeCodeInfoKey), RegisteredTaskObjectLifetime.Build); var appConfigAsmGen = new ApplicationConfigNativeAssemblyGenerator (environmentVariables, systemProperties, Log) { IsBundledApp = IsBundledApplication, UsesMonoAOT = usesMonoAOT, @@ -404,7 +404,7 @@ void AddEnvironment () }; appConfigAsmGen.Init (); - var marshalMethodsState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (GenerateJavaStubs.MarshalMethodsRegisterTaskKey, RegisteredTaskObjectLifetime.Build); + var marshalMethodsState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (ProjectSpecificTaskObjectKey (GenerateJavaStubs.MarshalMethodsRegisterTaskKey), RegisteredTaskObjectLifetime.Build); MarshalMethodsNativeAssemblyGenerator marshalMethodsAsmGen; if (enableMarshalMethods) { diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs index efb8fa465f5..35474f678ac 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs @@ -75,7 +75,7 @@ public override bool RunTask () var javaPlatformDirectory = Path.GetDirectoryName (JavaPlatformJarPath); - resource_fixup = MonoAndroidHelper.LoadMapFile (BuildEngine4, CaseMapFile, StringComparer.OrdinalIgnoreCase); + resource_fixup = MonoAndroidHelper.LoadMapFile (BuildEngine4, Path.GetFullPath (CaseMapFile), StringComparer.OrdinalIgnoreCase); // Parse out the resources from the R.java file CodeTypeDeclaration resources; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs index 3675c1a90bb..ff2b113044d 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs @@ -79,7 +79,7 @@ bool Run(DirectoryAssemblyResolver res) string assemblyName = Path.GetFileNameWithoutExtension (OutputFile.ItemSpec); - resource_fixup = MonoAndroidHelper.LoadMapFile (BuildEngine4, CaseMapFile, StringComparer.OrdinalIgnoreCase); + resource_fixup = MonoAndroidHelper.LoadMapFile (BuildEngine4, Path.GetFullPath (CaseMapFile), StringComparer.OrdinalIgnoreCase); // Generate an assembly which contains all the values in the provided // R.txt file. var mp = new ModuleParameters (); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateRtxt.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateRtxt.cs index a9927347626..59803eb9ed8 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateRtxt.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateRtxt.cs @@ -33,7 +33,7 @@ public override bool RunTask () // Parse the Resource files and then generate an R.txt file var writer = new RtxtWriter (); - var resource_fixup = MonoAndroidHelper.LoadMapFile (BuildEngine4, CaseMapFile, StringComparer.OrdinalIgnoreCase); + var resource_fixup = MonoAndroidHelper.LoadMapFile (BuildEngine4, Path.GetFullPath (CaseMapFile), StringComparer.OrdinalIgnoreCase); var javaPlatformDirectory = Path.GetDirectoryName (JavaPlatformJarPath); var parser = new FileResourceParser () { Log = Log, JavaPlatformDirectory = javaPlatformDirectory, ResourceFlagFile = ResourceFlagFile}; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Lint.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Lint.cs index b1faff2c2ae..c275f67ff12 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Lint.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Lint.cs @@ -49,7 +49,7 @@ public class Lint : AndroidToolTask string text; string type; - Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4); + Dictionary resource_name_case_map => _resource_name_case_map ??= MonoAndroidHelper.LoadResourceCaseMap (BuildEngine4, ProjectSpecificTaskObjectKey); [Required] public string TargetDirectory { get; set; } 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 24fe06606b7..1c16ce4feb2 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 @@ -247,6 +247,30 @@ public void AllProjectsHaveSameOutputDirectory() sb.Dispose (); } + [Test] + public void BuildSolutionWithMultipleProjectsInParallel () + { + var testPath = Path.Combine ("temp", "BuildSolutionWithMultipleProjects"); + var sb = new SolutionBuilder("BuildSolutionWithMultipleProjects.sln") { + SolutionPath = Path.Combine (Root, testPath), + MaxCpuCount = 4, + }; + for (int i=1; i <= 4; i++) { + var app1 = new XamarinAndroidApplicationProject () { + ProjectName = $"App{i}", + PackageName = $"com.companyname.App{i}", + AotAssemblies = true, + IsRelease = true, + }; + app1.SetProperty ("AndroidEnableMarshalMethods", "True"); + sb.Projects.Add (app1); + } + sb.BuildingInsideVisualStudio = false; + Assert.IsTrue (sb.Build (), "Build of solution should have succeeded"); + Assert.IsTrue (sb.ReBuild (), "ReBuild of solution should have succeeded"); + sb.Dispose (); + } + [Test] public void JavacTaskDoesNotRunOnSecondBuild () { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/Aapt2Tests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/Aapt2Tests.cs index 8ee83fc9876..7c9dee61401 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/Aapt2Tests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/Aapt2Tests.cs @@ -412,7 +412,7 @@ public void Aapt2CompileFixesUpErrors () MonoAndroidHelper.SaveResourceCaseMap (engine, new Dictionary { { $"layout{directorySeperator}main.axml", $"Layout{directorySeperator}Main.xml" }, { $"values{directorySeperator}strings.xml", $"Values{directorySeperator}Strings.xml" }, - }); + }, (o) => { return (o, path);} ); var task = new Aapt2Compile { BuildEngine = engine, ToolPath = GetPathToAapt2 (), diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ManagedResourceParserTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ManagedResourceParserTests.cs index 7a6f89c90b2..fcaeb662611 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ManagedResourceParserTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ManagedResourceParserTests.cs @@ -530,6 +530,7 @@ public void RtxtGeneratorOutput () BuildEngine = engine, RTxtFile = rTxt, ResourceDirectory = resPath, + CaseMapFile = Path.Combine (Root, path, "case_map.txt"), JavaPlatformJarPath = Path.Combine (AndroidSdkDirectory, "platforms", $"android-{platform}", "android.jar"), ResourceFlagFile = Path.Combine (Root, path, "res.flag"), AdditionalResourceDirectories = new string[] { @@ -600,6 +601,7 @@ public void CompareAapt2AndManagedParserOutput () task.Namespace = "MonoAndroidApplication4.MonoAndroidApplication4"; task.NetResgenOutputFile = Path.Combine (Root, path, "Resource.designer.aapt2.cs"); task.ProjectDir = Path.Combine (Root, path); + task.CaseMapFile = Path.Combine (Root, path, "case_map.txt"); task.ResourceDirectory = Path.Combine (Root, path, "res") + Path.DirectorySeparatorChar; task.Resources = new TaskItem [] { new TaskItem (Path.Combine (Root, path, "res", "values", "strings.xml"), new Dictionary () { @@ -667,6 +669,7 @@ public void CompareAaptAndManagedParserOutputWithCustomIds () task.Namespace = "MonoAndroidApplication4.MonoAndroidApplication4"; task.NetResgenOutputFile = Path.Combine (Root, path, "Resource.designer.aapt.cs"); task.ProjectDir = Path.Combine (Root, path); + task.CaseMapFile = Path.Combine (Root, path, "case_map.txt"); task.ResourceDirectory = Path.Combine (Root, path, "res") + Path.DirectorySeparatorChar; task.Resources = new TaskItem [] { new TaskItem (Path.Combine (Root, path, "res", "values", "strings.xml"), new Dictionary () { @@ -806,6 +809,7 @@ int styleable ElevenAttributes_attr09 9 task.Namespace = "Foo.Foo"; task.NetResgenOutputFile = Path.Combine (Root, path, "Resource.designer.cs"); task.ProjectDir = Path.Combine (Root, path); + task.CaseMapFile = Path.Combine (Root, path, "case_map.txt"); task.ResourceDirectory = Path.Combine (Root, path, "res"); task.Resources = new TaskItem [] {}; task.IsApplication = true; diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs index acd5230b39b..179c78cb6b4 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs @@ -497,11 +497,11 @@ public static string TryGetAndroidJarPath (TaskLoggingHelper log, string platfor static readonly string ResourceCaseMapKey = $"{nameof (MonoAndroidHelper)}_ResourceCaseMap"; - public static void SaveResourceCaseMap (IBuildEngine4 engine, Dictionary map) => - engine.RegisterTaskObjectAssemblyLocal (ResourceCaseMapKey, map, RegisteredTaskObjectLifetime.Build); + public static void SaveResourceCaseMap (IBuildEngine4 engine, Dictionary map, Func keyCallback) => + engine.RegisterTaskObjectAssemblyLocal (keyCallback (ResourceCaseMapKey), map, RegisteredTaskObjectLifetime.Build); - public static Dictionary LoadResourceCaseMap (IBuildEngine4 engine) => - engine.GetRegisteredTaskObjectAssemblyLocal> (ResourceCaseMapKey, RegisteredTaskObjectLifetime.Build) ?? new Dictionary (0); + public static Dictionary LoadResourceCaseMap (IBuildEngine4 engine, Func keyCallback) => + engine.GetRegisteredTaskObjectAssemblyLocal> (keyCallback (ResourceCaseMapKey), RegisteredTaskObjectLifetime.Build) ?? new Dictionary (0); public static string FixUpAndroidResourcePath (string file, string resourceDirectory, string resourceDirectoryFullPath, Dictionary resource_name_case_map) {