Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: dotnet/android-tools
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9f02d77692bca8c6585941de03750d5eaaca5c5a
Choose a base ref
...
head repository: dotnet/android-tools
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 099fd95f5459d9df78af0ad28f46e3016dd7ca1d
Choose a head ref
  • 4 commits
  • 6 files changed
  • 2 contributors

Commits on Jan 11, 2023

  1. 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
    dellis1972 authored Jan 11, 2023
    Configuration menu
    Copy the full SHA
    76c076f View commit details
    Browse the repository at this point in the history
  2. 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.
    jonpryor authored Jan 11, 2023
    Configuration menu
    Copy the full SHA
    47f95ab View commit details
    Browse the repository at this point in the history

Commits on Jan 13, 2023

  1. 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
    jonpryor authored Jan 13, 2023
    Configuration menu
    Copy the full SHA
    ac9ea09 View commit details
    Browse the repository at this point in the history

Commits on Jan 18, 2023

  1. 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
    dellis1972 authored Jan 18, 2023
    Configuration menu
    Copy the full SHA
    099fd95 View commit details
    Browse the repository at this point in the history
Loading