-
Notifications
You must be signed in to change notification settings - Fork 31
Comparing changes
Open a pull request
base repository: dotnet/android-tools
base: 9f02d77692bca8c6585941de03750d5eaaca5c5a
head repository: dotnet/android-tools
compare: 099fd95f5459d9df78af0ad28f46e3016dd7ca1d
- 4 commits
- 6 files changed
- 2 contributors
Commits on Jan 11, 2023
-
Add support for Project Specific RegisterTaskObject. (#199)
Context: dotnet/maui#11605 Context: dotnet/maui#11387 (comment) Context: http://github.com/xamarin/xamarin-android/commit/8bc7a3e84f95e70fe12790ac31ecd97957771cb2 In dotnet/maui#11605, when `$(AndroidEnableMarshalMethods)`=True (dotnet/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 [`<GeneratePackageManagerJava/>`][1]: var marshalMethodsState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<MarshalMethodsState> (".:!MarshalMethods!:.", RegisteredTaskObjectLifetime.Build); Further consider a `.sln` with two "App" projects, as the "App" project build hits `<GeneratePackageManagerJava/>`. The lifetime of `.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 `<GeneratePackageManagerJava/>`. 4. `App2.csproj` is later built as part in the process, and *also* calls `<GeneratePackageManagerJava/>`. In particular note the key within `<GeneratePackageManagerJava/>`: `".:!MarshalMethods!:."`. This value is unchanged, 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 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. Update the `MSBuildExtensions` extension methods to include an additional `RegisterTaskObjectKeyFlags` parameter: [Flags] public enum RegisterTaskObjectKeyFlags { None = 0, IncludeProjectFile = 1 << 0, } Allowing: var marshalMethodsState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<MarshalMethodsState> ( ".:!MarshalMethods!:.", RegisteredTaskObjectLifetime.Build, RegisterTaskObjectKeyFlags.IncludeProjectFile ); When `RegisterTaskObjectKeyFlags.IncludeProjectFile` is specified, then [`IBuildEngine.ProjectFileOfTaskNode`][2] is used as part of the key with `RegisterTaskObject()`. This helps ensure that builds in different `.csproj` files will result in different keys. The previous `MSBuildExtensions.GetRegisteredTaskObjectAssemblyLocal()` and related overloads have been updated so that `RegisterTaskObjectKeyFlags.IncludeProjectFile` is used by default. [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://learn.microsoft.com/en-us/dotnet/api/microsoft.build.framework.ibuildengine.projectfileoftasknode?view=msbuild-17-netcore
Configuration menu - View commit details
-
Copy full SHA for 76c076f - Browse repository at this point
Copy the full SHA 76c076fView commit details -
Fix CS0121 ambiguity errors. (#200)
Context: 76c076f When attempting to update xamarin/xamarin-android to use 4ea2d5ad, lots of CS0121 errors appeared: …/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs(80,18): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs(87,18): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs(94,18): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/FilterAssemblies.cs(98,17): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/GenerateCompressedAssembliesNativeSourceFiles.cs(72,17): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJniRemappingNativeCode.cs(95,17): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/WriteLockFile.cs(35,19): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs(524,18): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs(578,17): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs(393,11): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs(440,11): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' …/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs(501,11): error CS0121: The call is ambiguous between the following methods or properties: 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool)' and 'MSBuildExtensions.RegisterTaskObjectAssemblyLocal(IBuildEngine4, object, object, RegisteredTaskObjectLifetime, bool, RegisterTaskObjectKeyFlags)' This is because when given e.g.: partial class MSBuildExtensions { public static void RegisterTaskObjectAssemblyLocal (this IBuildEngine4 engine, object key, object value, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection = false); public static void RegisterTaskObjectAssemblyLocal (this IBuildEngine4 engine, object key, object value, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection = false, RegisterTaskObjectKeyFlags flags = RegisterTaskObjectKeyFlags.IncludeProjectFile); } then this expression: engine.RegisterTaskObjectAssemblyLocal(key, value, lifetime); has two possible matches, due to the default parameters. Fix this by *removing* the default `RegisteredTaskObjectLifetime` parameter value, and (when appropriate) adding an overload: partial class MSBuildExtensions { public static void RegisterTaskObjectAssemblyLocal (this IBuildEngine4 engine, object key, object value, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection = false); public static void RegisterTaskObjectAssemblyLocal (this IBuildEngine4 engine, object key, object value, RegisteredTaskObjectLifetime lifetime, RegisterTaskObjectKeyFlags flagse); public static void RegisterTaskObjectAssemblyLocal (this IBuildEngine4 engine, object key, object value, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection, RegisterTaskObjectKeyFlags flags); } Additionally, *remove* the `[Obsolete]` attributes. With `RegisterTaskObjectKeyFlags.IncludeProjectFile` part of the default behavior, there is no need to mark the original methods `[Obsolete]`. This allows existing code such as: var value = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal (key, Lifetime); to remain unchanged.
Configuration menu - View commit details
-
Copy full SHA for 47f95ab - Browse repository at this point
Copy the full SHA 47f95abView commit details
Commits on Jan 13, 2023
-
Revert IBuildEngine.ProjectFileOfTaskNode use. (#201)
Reverts: 47f95ab Reverts: 76c076f Context: dotnet/android#7685 (comment) The problem is that we misunderstood [`IBuildEngine.ProjectFileOfTaskNode`][0]: we *thought* (hoped?) that it would return `$(MSBuildProjectFullPath)`, the path to the `.csproj` being built. In actuality it returns `$(MSBuildThisFileFullPath)` for the file containing the Task invocation. Meaning if e.g. `Xamarin.Android.Common.targets` contains the Task invocation, then IBuildEngine.ProjectFileOfTaskNode` would be the path to `Xamarin.Android.Common.targets`, *not* the path of the `.csproj`. This in turn means it doesn't actually solve the problem we had. We will instead need to audit all use of `IBuildEngine4.RegisterTaskObject()` & related to ensure that the keys provided *also* contain paths to project-specific files, if necessary. Revert 47f95ab and 76c076f, as the changes are not needed. [0]: https://learn.microsoft.com/en-us/dotnet/api/microsoft.build.framework.ibuildengine.projectfileoftasknode?view=msbuild-17-netcore
Configuration menu - View commit details
-
Copy full SHA for ac9ea09 - Browse repository at this point
Copy the full SHA ac9ea09View commit details
Commits on Jan 18, 2023
-
Add *Task.ProjectSpecificTaskObjectKey() for RegisterTaskObject() use (…
…#202) Context: dotnet/maui#11605 Context: dotnet/maui#11387 (comment) Context: http://github.com/xamarin/xamarin-android/commit/8bc7a3e84f95e70fe12790ac31ecd97957771cb2 In dotnet/maui#11605, when `$(AndroidEnableMarshalMethods)`=True (dotnet/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 [`<GeneratePackageManagerJava/>`][1]: var marshalMethodsState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<MarshalMethodsState> (".:!MarshalMethods!:.", RegisteredTaskObjectLifetime.Build); Further consider a `.sln` with two "App" projects, as the "App" project build hits `<GeneratePackageManagerJava/>`. The lifetime of `.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 `<GeneratePackageManagerJava/>`. 4. `App2.csproj` is later built as part of the process, and *also* calls `<GeneratePackageManagerJava/>`. In particular note the key within `<GeneratePackageManagerJava/>`: `".:!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. Update `AndroidTask` and `AndroidToolTask` to capture the current directory in a `WorkingDirectory` property like [`AsyncTask`][2] does. Introduce new `ProjectSpecificTaskObjectKey()` instance methods into `AndroidTask`, `AndroidAsyncTask`, and `AndroidToolTask` which can be used to generate a key which includes `WorkingDirectory`. This allows: var marshalMethodsState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<MarshalMethodsState> ( ProjectSpecificTaskObjectKey (".:!MarshalMethods!:."), RegisteredTaskObjectLifetime.Build ); When `ProjectSpecificTaskObjectKey()` is used the `WorkingDirectory` is included in the key with `RegisterTaskObject()`. This helps ensure that builds in different `.csproj` files will result in different keys. [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
Configuration menu - View commit details
-
Copy full SHA for 099fd95 - Browse repository at this point
Copy the full SHA 099fd95View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 9f02d77692bca8c6585941de03750d5eaaca5c5a...099fd95f5459d9df78af0ad28f46e3016dd7ca1d