Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NativeAOT] add sample that runs successfully #9636

Merged
merged 21 commits into from
Jan 22, 2025

Conversation

jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Dec 19, 2024

This is an Android NativeAOT sample that runs successfully.

It currently relies on [InternalsVisibleTo("NativeAOT")] in Mono.Android.dll for things like:

  • Java.Interop.TypeManagerMapDictionaries.JniToManaged

  • Java.Interop.TypeManagerMapDictionaries.ManagedToJni

  • Java.Interop.Tools.TypeNameMappings.JavaNativeTypeManager.ToToJniName()

  • Android.Runtime.JNIEnvInit.InitializeNativeAot()

There are a couple MSBuild changes still left:

  • $(_ExtraTrimmerArgs) needs to be specified for trimmer warnings to not be displayed 2x. This is the same thing done in xamarin/xamarin-macios.

  • @(TrimmerRootAssembly) needs to be set for illink's "already trimmed" output for ILC. We exclude System.Private.CoreLib.dll from this list.

This is an Android NativeAOT sample that runs successfully.

It currently relies on `[InternalsVisibleTo("NativeAOT")]` in
`Mono.Android.dll` for things like:

* `Java.Interop.TypeManagerMapDictionaries.JniToManaged`

* `Java.Interop.TypeManagerMapDictionaries.ManagedToJni`

* `Java.Interop.Tools.TypeNameMappings.JavaNativeTypeManager.ToToJniName()`

* `Android.Runtime.JNIEnvInit.InitializeNativeAot()`

There are a couple MSBuild changes still left:

* `$(_ExtraTrimmerArgs)` needs to be specified for trimmer warnings to
  show. This is the same thing done in xamarin/xamarin-macios.

* `@(TrimmerRootAssembly)` needs to be set for illink's "already
  trimmed" output for ILC. We exclude `System.Private.CoreLib.dll`
  from this list.
@@ -49,6 +49,8 @@ This file contains the NativeAOT-specific MSBuild logic for .NET for Android.
-->
<_OriginalSuppressTrimAnalysisWarnings>$(SuppressTrimAnalysisWarnings)</_OriginalSuppressTrimAnalysisWarnings>
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
<!-- Ensure ILLink respects the value of SuppressTrimAnalysisWarnings -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This suggests that <ILLink/> doesn't currently respect $(SuppressTrimAnalysisWarnings). Is there a bug for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is happening because we are running both ILLink and ILC. We want SuppressTrimAnalysisWarnings=false by default so we get warnings from ILC.

But we don't want 2x trimmer warnings, so we have to turn it off and back on for ILC. Unfortunately, $(_ExtraTrimmerArgs) is already set.

Same approach here:

@samhouts samhouts requested a review from Copilot December 19, 2024 18:33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 20 out of 31 changed files in this pull request and generated no comments.

Files not reviewed (11)
  • samples/NativeAOT/AndroidManifest.xml: Language not supported
  • samples/NativeAOT/NativeAOT.csproj: Language not supported
  • samples/NativeAOT/Resources/layout/activity_main.xml: Language not supported
  • samples/NativeAOT/Resources/mipmap-anydpi-v26/appicon.xml: Language not supported
  • samples/NativeAOT/Resources/mipmap-anydpi-v26/appicon_round.xml: Language not supported
  • samples/NativeAOT/Resources/values/ic_launcher_background.xml: Language not supported
  • samples/NativeAOT/Resources/values/strings.xml: Language not supported
  • src/Mono.Android/Properties/AssemblyInfo.cs.in: Language not supported
  • src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets: Language not supported
  • src/Mono.Android/Android.Runtime/JNIEnvInit.cs: Evaluated as low risk
  • samples/NativeAOT/NativeAotTypeManager.cs: Evaluated as low risk
Comments suppressed due to low confidence (1)

samples/NativeAOT/JavaInteropRuntime.cs:34

  • The init method initializes the JreRuntimeOptions and calls JNIEnvInit.InitializeNativeAot(runtime), but there are no tests covering this behavior.
static void init (IntPtr jnienv, IntPtr klass)
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 19, 2024
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 19, 2024
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 19, 2024
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 19, 2024
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 20, 2024
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 20, 2024
jonpryor added a commit that referenced this pull request Dec 20, 2024
Context: xamarin/monodroid@e318861
Context: 130905e
Context: de04316
Context: #9636

In the beginning there was Mono for Android, which had a set of
`Mono.Android.dll` assemblies (one per supported API level), each of
which contained "duplicated" binding logic: each API level had its
own `Java.Lang.Object`, `Android.Runtime.JNIEnv`, etc.

dotnet/java-interop started, in part, as a way to "split out" the
core integration logic, so that it *wouldn't* need to be duplicated
across every assembly.  As part of this, it introduced its own core
abstractions, notably `Java.Interop.IJavaPeerable` and
`Java.Interop.JavaObject`.

When dotnet/java-interop was first introduced into Xamarin.Android,
with xamarin/monodroid@e318861e, the integration was incomplete.
Integration continued with 130905e, allowing unit tests within
`Java.Interop-Tests.dll` to run within Xamarin.Android and
construction of instances of e.g. `JavaInt32Array`, but one large
piece of integration remained:

Moving GC bridge code *out* of `Java.Lang.Object`, and instead
relying on `Java.Interop.JavaObject`, turning this:

	namespace Java.Lang {
	    public partial class Object : System.Object, IJavaPeerable /* … */ {
	    }
	}

into this:

	namespace Java.Lang {
	    public partial class Object : Java.Interop.JavaObject, IJavaPeerable /* … */ {
	    }
	}

*Why*?  In part because @jonpryor has wanted to do this for literal
years at this point, but also in part because of #9636
and related efforts to use Native AOT, which involves avoiding /
bypassing `DllImportAttribute` invocations (for now, everything
touched by Native AOT becomes a single `.so` binary, which we don't
know the name of).  Avoiding P/Invoke means *embracing* and extending
existing Java.Interop constructs (e.g. de04316).

In addition to altering the base types of `Java.Lang.Object` and
`Java.Lang.Throwable`:

  * Remove `handle` and related fields from `Java.Lang.Object` and
    `Java.Lang.Throwable`.

  * Update `PreserveLists/Mono.Android.xml` so that the removed
    fields are note preserved.

  * Rename `JNIenvInit.AndroidValueManager` to
    `JNIEnvInit.ValueManager`, and change its type to
    `JniRuntime.JniValueManager`.  This is to help "force" usage of
    `JnIRuntime.JniValueManager` in more places, as we can't
    currently use `AndroidValueManager` in Native AOT (P/Invokes!).

  * Cleanup: Remove `JNIEnv.Exit()` and related code.  These were
    used by the Android Designer, which is no longer supported.

  * Update (`internal`) interface `IJavaObjectEx` to remove
    constructs present on `IJavaPeerable.`

Known issues:

  * `Java.Lang.Throwable(IntPtr, JniHandleOwnership)` invocation
    will result in construction of an "extra" `java.lang.Throwable`
    instance on the Java side, which will be immediately discarded.
    This is because it uses the `JavaException(string, Exception)`
    constructor, which implicitly creates a Java peer.

    We may need dotnet/java-interop changes to better address this.
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 20, 2024
@jonathanpeppers

This comment was marked as outdated.

This comment was marked as outdated.

jonpryor added a commit that referenced this pull request Jan 15, 2025
Context: xamarin/monodroid@e318861
Context: 130905e
Context: de04316
Context: #9636
Context: dotnet/java-interop#1293

In the beginning there was Mono for Android, which had a set of
`Mono.Android.dll` assemblies (one per supported API level), each of
which contained "duplicated" binding logic: each API level had its
own `Java.Lang.Object`, `Android.Runtime.JNIEnv`, etc.

dotnet/java-interop started, in part, as a way to "split out" the
core integration logic, so that it *wouldn't* need to be duplicated
across every assembly.  As part of this, it introduced its own core
abstractions, notably `Java.Interop.IJavaPeerable` and
`Java.Interop.JavaObject`.

When dotnet/java-interop was first introduced into Xamarin.Android,
with xamarin/monodroid@e318861e, the integration was incomplete.
Integration continued with 130905e, allowing unit tests within
`Java.Interop-Tests.dll` to run within Xamarin.Android and
construction of instances of e.g. `JavaInt32Array`, but one large
piece of integration remained:

Moving GC bridge code *out* of `Java.Lang.Object`, and instead
relying on `Java.Interop.JavaObject`, turning this:

	namespace Java.Lang {
	    public partial class Object : System.Object, IJavaPeerable /* … */ {
	    }
	}

into this:

	namespace Java.Lang {
	    public partial class Object : Java.Interop.JavaObject, IJavaPeerable /* … */ {
	    }
	}

*Why*?  In part because @jonpryor has wanted to do this for literal
years at this point, but also in part because of #9636
and related efforts to use Native AOT, which involves avoiding /
bypassing `DllImportAttribute` invocations (for now, everything
touched by Native AOT becomes a single `.so` binary, which we don't
know the name of).  Avoiding P/Invoke means *embracing* and extending
existing Java.Interop constructs (e.g. de04316).

In addition to altering the base types of `Java.Lang.Object` and
`Java.Lang.Throwable`:

  * Remove `handle` and related fields from `Java.Lang.Object` and
    `Java.Lang.Throwable`.

  * Update `PreserveLists/Mono.Android.xml` so that the removed
    fields are note preserved.

  * Rename `JNIenvInit.AndroidValueManager` to
    `JNIEnvInit.ValueManager`, and change its type to
    `JniRuntime.JniValueManager`.  This is to help "force" usage of
    `JnIRuntime.JniValueManager` in more places, as we can't
    currently use `AndroidValueManager` in Native AOT (P/Invokes!).

  * Cleanup: Remove `JNIEnv.Exit()` and related code.  These were
    used by the Android Designer, which is no longer supported.

  * Update (`internal`) interface `IJavaObjectEx` to remove
    constructs present on `IJavaPeerable.`

  * Update `ExceptionTest.CompareStackTraces()` to use
    `System.Diagnostics.StackTrace(ex, fNeedFileInfo:true)`
    so that when the `debug.mono.debug` system property is set, the
    `ExceptionTest.InnerExceptionIsSet()` unit test doesn't fail.
    Also, increase assertion message verbosity.
jonpryor added a commit that referenced this pull request Jan 15, 2025
Context: xamarin/monodroid@e318861
Context: 130905e
Context: de04316
Context: #9636
Context: dotnet/java-interop#1293

In the beginning there was Mono for Android, which had a set of
`Mono.Android.dll` assemblies (one per supported API level), each of
which contained "duplicated" binding logic: each API level had its
own `Java.Lang.Object`, `Android.Runtime.JNIEnv`, etc.

dotnet/java-interop started, in part, as a way to "split out" the
core integration logic, so that it *wouldn't* need to be duplicated
across every assembly.  As part of this, it introduced its own core
abstractions, notably `Java.Interop.IJavaPeerable` and
`Java.Interop.JavaObject`.

When dotnet/java-interop was first introduced into Xamarin.Android,
with xamarin/monodroid@e318861e, the integration was incomplete.
Integration continued with 130905e, allowing unit tests within
`Java.Interop-Tests.dll` to run within Xamarin.Android and
construction of instances of e.g. `JavaInt32Array`, but one large
piece of integration remained:

Moving GC bridge code *out* of `Java.Lang.Object`, and instead
relying on `Java.Interop.JavaObject`, turning this:

	namespace Java.Lang {
	    public partial class Object : System.Object, IJavaPeerable /* … */ {
	    }
	}

into this:

	namespace Java.Lang {
	    public partial class Object : Java.Interop.JavaObject, IJavaPeerable /* … */ {
	    }
	}

*Why*?  In part because @jonpryor has wanted to do this for literal
years at this point, but also in part because of #9636
and related efforts to use Native AOT, which involves avoiding /
bypassing `DllImportAttribute` invocations (for now, everything
touched by Native AOT becomes a single `.so` binary, which we don't
know the name of).  Avoiding P/Invoke means *embracing* and extending
existing Java.Interop constructs (e.g. de04316).

In addition to altering the base types of `Java.Lang.Object` and
`Java.Lang.Throwable`:

  * Remove `handle` and related fields from `Java.Lang.Object` and
    `Java.Lang.Throwable`.

  * Update `PreserveLists/Mono.Android.xml` so that the removed
    fields are note preserved.

  * Rename `JNIenvInit.AndroidValueManager` to
    `JNIEnvInit.ValueManager`, and change its type to
    `JniRuntime.JniValueManager`.  This is to help "force" usage of
    `JnIRuntime.JniValueManager` in more places, as we can't
    currently use `AndroidValueManager` in Native AOT (P/Invokes!).

  * Cleanup: Remove `JNIEnv.Exit()` and related code.  These were
    used by the Android Designer, which is no longer supported.

  * Update (`internal`) interface `IJavaObjectEx` to remove
    constructs present on `IJavaPeerable.`

  * Update `ExceptionTest.CompareStackTraces()` to use
    `System.Diagnostics.StackTrace(ex, fNeedFileInfo:true)`
    so that when the `debug.mono.debug` system property is set, the
    `ExceptionTest.InnerExceptionIsSet()` unit test doesn't fail.
    Also, increase assertion message verbosity.
jonpryor added a commit that referenced this pull request Jan 15, 2025
Context: xamarin/monodroid@e318861
Context: 130905e
Context: de04316
Context: #9636
Context: dotnet/java-interop#1293

In the beginning there was Mono for Android, which had a set of
`Mono.Android.dll` assemblies (one per supported API level), each of
which contained "duplicated" binding logic: each API level had its
own `Java.Lang.Object`, `Android.Runtime.JNIEnv`, etc.

dotnet/java-interop started, in part, as a way to "split out" the
core integration logic, so that it *wouldn't* need to be duplicated
across every assembly.  As part of this, it introduced its own core
abstractions, notably `Java.Interop.IJavaPeerable` and
`Java.Interop.JavaObject`.

When dotnet/java-interop was first introduced into Xamarin.Android,
with xamarin/monodroid@e318861e, the integration was incomplete.
Integration continued with 130905e, allowing unit tests within
`Java.Interop-Tests.dll` to run within Xamarin.Android and
construction of instances of e.g. `JavaInt32Array`, but one large
piece of integration remained:

Moving GC bridge code *out* of `Java.Lang.Object`, and instead
relying on `Java.Interop.JavaObject`, turning this:

	namespace Java.Lang {
	    public partial class Object : System.Object, IJavaPeerable /* … */ {
	    }
	}

into this:

	namespace Java.Lang {
	    public partial class Object : Java.Interop.JavaObject, IJavaPeerable /* … */ {
	    }
	}

*Why*?  In part because @jonpryor has wanted to do this for literal
years at this point, but also in part because of #9636
and related efforts to use Native AOT, which involves avoiding /
bypassing `DllImportAttribute` invocations (for now, everything
touched by Native AOT becomes a single `.so` binary, which we don't
know the name of).  Avoiding P/Invoke means *embracing* and extending
existing Java.Interop constructs (e.g. de04316).

In addition to altering the base types of `Java.Lang.Object` and
`Java.Lang.Throwable`:

  * Remove `handle` and related fields from `Java.Lang.Object` and
    `Java.Lang.Throwable`.

  * Update `PreserveLists/Mono.Android.xml` so that the removed
    fields are note preserved.

  * Rename `JNIenvInit.AndroidValueManager` to
    `JNIEnvInit.ValueManager`, and change its type to
    `JniRuntime.JniValueManager`.  This is to help "force" usage of
    `JnIRuntime.JniValueManager` in more places, as we can't
    currently use `AndroidValueManager` in Native AOT (P/Invokes!).

  * Cleanup: Remove `JNIEnv.Exit()` and related code.  These were
    used by the Android Designer, which is no longer supported.

  * Update (`internal`) interface `IJavaObjectEx` to remove
    constructs present on `IJavaPeerable.`

  * Update `ExceptionTest.CompareStackTraces()` to use
    `System.Diagnostics.StackTrace(ex, fNeedFileInfo:true)`
    so that when the `debug.mono.debug` system property is set, the
    `ExceptionTest.InnerExceptionIsSet()` unit test doesn't fail.
    Also, increase assertion message verbosity.
jonpryor added a commit that referenced this pull request Jan 17, 2025
Context: #9636
Context: dotnet/java-interop@d5dfa0a
Context: xamarin/monodroid@e318861
Context: 130905e
Context: de04316

Changes: dotnet/java-interop@4f06201...d5dfa0a

  * dotnet/java-interop@d5dfa0aa: [Java.Interop] `Java.Lang.Object, Mono.Android` Unification Changes (dotnet/java-interop#1293)
  * dotnet/java-interop@c86ae26c: [ci] Fail build if any git tracked files were modified. (dotnet/java-interop#1288)

In the beginning there was Mono for Android, which had a set of
`Mono.Android.dll` assemblies (one per supported API level), each of
which contained "duplicated" binding logic: each API level had its
own `Java.Lang.Object`, `Android.Runtime.JNIEnv`, etc.

dotnet/java-interop started, in part, as a way to "split out" the
core integration logic, so that it *wouldn't* need to be duplicated
across every assembly.  As part of this, it introduced its own core
abstractions, notably `Java.Interop.IJavaPeerable` and
`Java.Interop.JavaObject`.

When dotnet/java-interop was first introduced into Xamarin.Android,
with xamarin/monodroid@e318861e, the integration was incomplete.
Integration continued with 130905e, allowing unit tests within
`Java.Interop-Tests.dll` to run within Xamarin.Android and
construction of instances of e.g. `JavaInt32Array`, but one large
piece of integration remained:

Move GC bridge code *out* of `Java.Lang.Object`, and instead rely on
`Java.Interop.JavaObject`, turning this:

	namespace Java.Lang {
	    public partial class Object : System.Object, IJavaPeerable /* … */ {
	    }
	}

into this:

	namespace Java.Lang {
	    public partial class Object : Java.Interop.JavaObject, IJavaPeerable /* … */ {
	    }
	}

*Why*?  In part because @jonpryor has wanted to do this for literal
years at this point, but also in part because of #9636
and related efforts to use Native AOT, which involves avoiding /
bypassing `DllImportAttribute` invocations (for now, everything
touched by Native AOT becomes a single `.so` binary, which we don't
know the name of).  Avoiding P/Invoke means *embracing* and extending
existing Java.Interop constructs (e.g. de04316).

In addition to altering the base types of `Java.Lang.Object` and
`Java.Lang.Throwable`:

  * Remove `handle` and related fields from `Java.Lang.Object` and
    `Java.Lang.Throwable`.

  * Update `PreserveLists/Mono.Android.xml` et al. so that the
    removed fields are not preserved.

  * Rename `JNIenvInit.AndroidValueManager` to
    `JNIEnvInit.ValueManager`, and change its type to
    `JniRuntime.JniValueManager`.  This is to help "force" usage of
    `JnIRuntime.JniValueManager` in more places, as we can't
    currently use `AndroidValueManager` in Native AOT (P/Invokes!).

  * Cleanup: Remove `JNIEnv.Exit()` and related code.  These were
    used by the Android Designer, which is no longer supported.

  * Update (`internal`) interface `IJavaObjectEx` to remove
    constructs present on `IJavaPeerable.`

  * Update the `Java.Lang.Object(IntPtr, JniHandleOwnership)` and
    `Java.Lang.Throwable(IntPtr, JniHandleOwnership)` constructors to
    follow dotnet/java-interop convention, and patch over the
    differences that exist between the two paradigms.

  * Update `ExceptionTest.CompareStackTraces()` to use
    `System.Diagnostics.StackTrace(ex, fNeedFileInfo:true)`
    so that when the `debug.mono.debug` system property is set, the
    `ExceptionTest.InnerExceptionIsSet()` unit test doesn't fail.
    Also, increase assertion message utility.

  * Update `AndroidObjectReferenceManager` so that
    dotnet/java-interop -initiated JNI object reference log messages
    are appropriately captured.

  * Update `JNIEnv.IsGCUserPeer()` to also consider types which
    implement `net.dot.jni.GCUserPeerable` to be "GC User Peers".
@jonathanpeppers
Copy link
Member Author

Looks like NativeAOT tests are green:

image

<_NdkAbi Condition=" '$(RuntimeIdentifier)' == 'android-arm64' ">aarch64</_NdkAbi>
<_NdkAbi Condition=" '$(RuntimeIdentifier)' == 'android-x64' ">x86_64</_NdkAbi>
<_NdkSysrootAbi>$(_NdkAbi)-linux-android</_NdkSysrootAbi>
<_NdkClangPrefix>$(_NdkAbi)-linux-android21-</_NdkClangPrefix>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we comment on why these are needed ? (the _Ndk changes).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NDK has paths like this:

image

So, eventually, we probably need some task that computes these. Do we have something like it @grendello ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to concern ourselves with these directories. All that we need to do is to invoke tools from the toolchains/llvm/prebuilt/${OS}/bin directory, e.g. riscv64-linux-android35-clang, riscv64-linux-android35-clang++, aarch64-linux-android21-clang, aarch64-linux-android25-clang++ etc. Everything we need to build and link any native code is found in the bin directory. The utilities invoked there set the appropriate search paths for include files, libraries etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing using this now, is we need the path to libc++_shared.so for the app to be able to run. Otherwise, it can't load the main app's libFoo.so built for NativeAOT.

There might be an alternative to statically link or something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To find out location of the shared libraries, you can pass -print-runtime-dir to any of the `clang scripts. It will give you output similar to:

$ ./aarch64-linux-android21-clang++ -print-runtime-dir
toolchains/llvm/prebuilt/linux-x86_64/bin$ ./aarch64-linux-android21-clang++ -print-search-dirs
programs: =[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/bin/.:[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/bin
libraries: =[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18:[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/lib/linux/aarch64:[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/bin/./../sysroot/usr/lib/aarch64-linux-android/21:[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/bin/./../sysroot/usr/lib/aarch64-linux-android:[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/bin/./../sysroot/usr/lib

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just discovered another flag that is way more useful for this :)

$ toolchains/llvm/prebuilt/linux-x86_64/bin$ ./aarch64-linux-android21-clang++ -print-file-name=libc++_shared.so
[NDKDIR]/toolchains/llvm/prebuilt/linux-x86_64/bin/./../sysroot/usr/lib/aarch64-linux-android/libc++_shared.so

@jonpryor
Copy link
Member

jonpryor commented Jan 22, 2025

Context: https://github.com/dotnet/java-interop/tree/9b1d8781e8e322849d05efac32119c913b21c192/samples/Hello-NativeAOTFromAndroid

"Import" the [Hello-NativeAOTFromAndroid][0] from
dotnet/java-interop, and update it to use `Mono.Android.dll` and
parts of the .NET for Android build system.

It currently relies on `[InternalsVisibleTo("NativeAOT")]` within
`Mono.Android.dll` for access to things like:

  * `Android.Runtime.JNIEnvInit.InitializeJniRuntime()`

There are a couple MSBuild changes still left:

TODO:

  * `$(_ExtraTrimmerArgs)` needs to be specified for trimmer warnings
    to not be displayed twice.  This is the same thing done in
    xamarin/xamarin-macios.

  * `@(TrimmerRootAssembly)` needs to be set for illink's
    "already trimmed" output for ILC.  We exclude
    `System.Private.CoreLib.dll` from this list.

  * Remove use of `Java.Runtime.Environment.dll`, and otherwise allow
    the sample to be built from the .NET for Android workload packs.

  * "MOAR Integration": sample depends upon a manually specified
    "type map" dictionary.  This needs to be automagic to be useful.

  * Figure out what to do about C++: do we dynamically link against
    and bundle `libc++_shared.so`?
    Statically link against `libc++_static.a`?

[0]: https://github.com/dotnet/java-interop/commit/78d59371a9e27aa601bc32a07a529d09e2f7c796

@jonpryor jonpryor merged commit 7a772f0 into main Jan 22, 2025
56 of 58 checks passed
@jonpryor jonpryor deleted the dev/peppers/nativeaot/runs2 branch January 22, 2025 18:23
grendello added a commit that referenced this pull request Jan 22, 2025
* main:
  [NativeAOT] add sample that runs successfully (#9636)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants