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

Add docs on using Bionic with NativeAOT #88817

Merged
merged 4 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/nativeaot/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
- [Reflection In AOT](reflection-in-aot-mode.md)
- [Troubleshooting](troubleshooting.md)
- [RD.xml Documentation](rd-xml-format.md)
- [Using Native AOT on Android-Bionic](android-bionic.md)
32 changes: 32 additions & 0 deletions src/coreclr/nativeaot/docs/android-bionic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Using Native AOT with Android Bionic

Starting with .NET 8 Preview 7, it's possible to build shared libraries and command line executables for Android.

Not a full Android experience is available - it's only possible to publish for two Bionic RID: linux-bionic-arm64 and linux-bionic-x64. Publishing for Android RIDs (android-arm64/android-x64) is not possible. This limited experience corresponds to building with [Android NDK](https://developer.android.com/ndk) from Native code - the limitations are similar. Interop with Java needs to be done manually through JNI, if necessary.

The minimum API level is 21 at the time of writing the document, but search for AndroidApiLevelMin in this repo for more up-to-date information.

To build for Bionic:

* Ensure you have [Android NDK](https://developer.android.com/ndk/downloads) for your system downloaded and extracted somewhere. We build and test with NDK r23c but anything newer should also work. Double check with the NDK version referenced [here](https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/libraries/testing-android.md), which might be more up-to-date than this document.
* Update your PATH to include `{NDK_ROOT}\toolchains\llvm\prebuilt\{OS_ARCH}\bin`. Replace `{NDK_ROOT}` with the path where you extracted the NDK, and replace `{OS_ARCH}` with your host OS and architecture (e.g. windows-x86_64 or linux-x86_64). Make sure this entry is first in your path - we need to make sure that running `clang` will execute `clang` from this directory.
* You can either create a new project or use an existing project. For this guide, let's create a new one:
```sh
$ dotnet new console -o HelloBionic --aot
$ cd HelloBionic
```
Note: the `--aot` parameter added `<PublishAot>true</PublishAot>` to the new project.
* Publish the project:
```sh
$ dotnet publish -r linux-bionic-arm64 -p:DisableUnsupportedError=true -p:PublishAotUsingRuntimePack=true
Copy link
Member

Choose a reason for hiding this comment

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

Are the two properties going away eventually? If not, we should probably at least mention them in this doc. Their names don't make it super clear what they're doing.

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 PublishAotUsingRuntimePack is supposed to go away. We currently have to set this for iDevices for the same reason. We'd like to use the runtime pack for all configurations, not just iDevices/Bionic. There's an 8.0 issue on it.

```
* You should have a binary under `bin\Release\net8.0\linux-bionic-arm64\publish`. Copy it to an Android device. Either `adb push` or using some GUI.
* You can probably run it with `adb shell`, but I used Termux: open Termux, give it access to file system by running `termux-setup-storage`. This will give you access to phone storage under `~/storage`. Copy the binary from `~/storage/...` to `~` (internal storage is not executable and you won't be able to run stuff from it). Then `chmod +x HelloBionic` and `./HelloBionic`. You should see Hello World.

Command line apps are not very interesting for Android. The more interesting scenario are shared libraries that can be called into from Java/Kotlin through JNI. This is very similar to building shared libraries in other languages like C/C++/Rust. `PublishAot` allows building shared libraries that are callable from non-.NET languages. See https://learn.microsoft.com/dotnet/core/deploying/native-aot/interop#native-exports.

For an example of a Native AOT shared library invoked through JNI from Java see https://github.com/josephmoresena/NativeAOT-AndroidHelloJniLib.

## Libssl dependency

Crypto in .NET is implemented on top of OS-provided crypto libraries (we do not build or service crypto algorithm implementations). Since Android doesn't come with the standard openssl library inbox, your app will need to provide it. The runtime code can handle various versions of the openssl library. The library has to be placed next to the app.