forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into dev/grendel/android-clr-host-local
* main: (71 commits) Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20250212.3 (dotnet#112626) JIT: Unify struct arg morphing (dotnet#112612) Enable `SA1015`: Closing generic bracket should not be followed by a space (dotnet#112597) Clean up normalizeLocale for mono browser target (dotnet#112575) SPMI: Ensure proper zero extension for isObjectImmutable and friends (dotnet#112617) Quote --version-scripts path (dotnet#112603) Remove incompatible API from PKCS netstandard2.0 lib [main] Update dependencies from dotnet/emsdk (dotnet#112393) Avoid `Unsafe.As` in `RangeCharSearchValues` (dotnet#112606) Fixed the issue of incorrect return value of PalVirtualAlloc (dotnet#112579) Fix size used for vectorization check in BitArray (dotnet#111558) (dotnet#111564) Fix build of windows arm64 crossdac (dotnet#112553) Simplify `ShuffleTakeIterator.GetCount` (dotnet#112593) Fix VS div-by-0 in DacEnumerableHashTable code (dotnet#112542) R2RDump: normalize GC info totalInterruptibleLength (dotnet#112003) Fix alignment padding and add test for saving managed resources (dotnet#110915) Adds `ccmp` logic into emitter backend. (dotnet#112153) Disable AVX10.2 by default (dotnet#112572) Outbox AesGcm in to Microsoft.Bcl.Cryptography Make test `IUnknown` conforming (dotnet#112566) ...
- Loading branch information
Showing
225 changed files
with
4,725 additions
and
3,169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file added
BIN
+169 KB
docs/workflow/building/coreclr/android-studio-coreclr-debug-symbols-added.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+196 KB
docs/workflow/building/coreclr/android-studio-coreclr-debug-symbols-adding.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,212 @@ | ||
Cross Compilation for Android on Linux | ||
====================================== | ||
# Experimental support of CoreCLR on Android | ||
|
||
Through cross compilation, on Linux it is possible to build CoreCLR for arm64 Android. | ||
This is the internal documentation which outlines experimental support of CoreCLR on Android and includes instructions on how to: | ||
- [Build CoreCLR for Android](./android.md#building-coreclr-for-android) | ||
- [Build and run a sample application with CoreCLR](./android.md#building-and-running-a-sample-app) | ||
- [Debug the sample app and the runtime](./android.md#debugging-the-runtime-and-the-sample-app) | ||
|
||
Requirements | ||
------------ | ||
## Prerequisite | ||
|
||
You'll need to generate a toolchain and a sysroot for Android. There's a script which takes care of the required steps. | ||
- Download and install [OpenJDK 23](https://openjdk.org/projects/jdk/23/) | ||
- Download and install [Android Studio](https://developer.android.com/studio/install) and the following: | ||
- Android SDK (minimum supported API level is 21) | ||
- Android NDK r27 | ||
|
||
Generating the rootfs | ||
--------------------- | ||
> [!NOTE] | ||
> Prerequisites can also be downloaded and installed manually: | ||
> - by running the automated script as described in [Testing Libraries on Android](../../testing/libraries/testing-android.md#using-a-terminal) | ||
> - by downloading the archives: | ||
> - Android SDK - Download [command-line tools](https://developer.android.com/studio#command-line-tools-only) and use `sdkmanager` to download the SDK. | ||
> - Android NDK - Download [NDK](https://developer.android.com/ndk/downloads) | ||
To generate the rootfs, run the following command in the `coreclr` folder: | ||
## Building CoreCLR for Android | ||
|
||
Supported host systems for building CoreCLR for Android: | ||
- [MacOS](./android.md#macos-and-linux) ✔ | ||
- [Linux](./android.md#macos-and-linux) ✔ | ||
- [Windows](./android.md#windows) ❌ (only through WSL) | ||
|
||
Supported target architectures: | ||
- x86 ❌ | ||
- x64 ✔ | ||
- arm ❌ | ||
- arm64 ✔ | ||
|
||
### MacOS and Linux | ||
|
||
#### Requirements | ||
|
||
Set the following environment variables: | ||
- ANDROID_SDK_ROOT=`<full-path-to-android-sdk>` | ||
- ANDROID_NDK_ROOT=`<full-path-to-android-ndk>` | ||
|
||
#### Building the runtime, libraries and tools | ||
|
||
To build CoreCLR runtime, libraries and tools for local development, run the following command from `<repo-root>`: | ||
|
||
``` | ||
cross/init-android-rootfs.sh | ||
./build.sh clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs -os android -arch <x64|arm64> -c <Debug|Release> | ||
``` | ||
|
||
This will download the NDK and any packages required to compile Android on your system. It's over 1 GB of data, so it may take a while. | ||
To build CoreCLR runtime NuGet packages, run the following command from `<repo-root>`: | ||
|
||
``` | ||
./build.sh clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+host+packs -os android -arch <x64|arm64> -c <Debug|Release> | ||
``` | ||
|
||
> [!NOTE] | ||
> The runtime packages will be located at: `<repo-root>/artifacts/packages/<configuration>/Shipping/` | ||
Cross compiling CoreCLR | ||
----------------------- | ||
Once the rootfs has been generated, it will be possible to cross compile CoreCLR. | ||
### Windows | ||
|
||
When cross compiling, you need to set both the `CONFIG_DIR` and `ROOTFS_DIR` variables. | ||
Building on Windows is not directly supported yet. However it is possible to use WSL2 for this purpose. | ||
|
||
To compile for arm64, run: | ||
#### WSL2 | ||
|
||
##### Requirements | ||
|
||
1. Install the Android SDK and NDK in WSL per the [prerequisites](#prerequisite). This can be done by downloading the archives or using Android Studio. | ||
- In case of Android Studio: | ||
- Make sure WSL is updated: from Windows host, `wsl --update` | ||
- [Enabled systemd](https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/#set-the-systemd-flag-set-in-your-wsl-distro-settings) | ||
- `sudo snap install android-studio --classic` | ||
2. Set the following environment variables: | ||
- ANDROID_SDK_ROOT=`<full-path-to-android-sdk>` | ||
- ANDROID_NDK_ROOT=`<full-path-to-android-ndk>` | ||
|
||
#### Building the runtime, libraries and tools | ||
|
||
To build CoreCLR runtime, libraries and tools, run the following command from `<repo-root>`: | ||
|
||
``` | ||
CONFIG_DIR=`realpath cross/android/arm64` ROOTFS_DIR=`realpath cross/android-rootfs/toolchain/arm64/sysroot` ./build.sh cross arm64 cmakeargs -DENABLE_LLDBPLUGIN=0 | ||
./build.sh clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs -os android -arch <x64|arm64> -c <Debug|Release> | ||
``` | ||
|
||
The resulting binaries will be found in `artifacts/bin/coreclr/Linux.BuildArch.BuildType/` | ||
## Building and running a sample app | ||
|
||
To demonstrate building and running an Android sample application with CoreCLR, we will use: | ||
- the [HelloAndroid sample app](../../../../src/mono/sample/Android/AndroidSampleApp.csproj). | ||
- a functional tests [Android.Device_Emulator.JIT.Test](../../../../src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj) | ||
|
||
Running the PAL tests on Android | ||
-------------------------------- | ||
A prerequisite for building and running samples locally is to have CoreCLR successfully built for desired Android platform. | ||
|
||
You can run the PAL tests on an Android device. To run the tests, you first copy the PAL tests to your Android phone using | ||
`adb`, and then run them in an interactive Android shell using `adb shell`: | ||
### Building HelloAndroid sample | ||
|
||
To build `HelloAndroid`, run the following command from `<repo_root>`: | ||
|
||
To copy the PAL tests over to an Android phone: | ||
``` | ||
adb push artifacts/obj/coreclr/Linux.arm64.Debug/src/pal/tests/palsuite/ /data/local/tmp/coreclr/pal/tests/palsuite | ||
adb push cross/android/toolchain/arm64/sysroot/usr/lib/libandroid-support.so /data/local/tmp/coreclr/lib/ | ||
adb push cross/android/toolchain/arm64/sysroot/usr/lib/libandroid-glob.so /data/local/tmp/coreclr/lib/ | ||
adb push src/pal/tests/palsuite/paltestlist.txt /data/local/tmp/coreclr | ||
adb push src/pal/tests/palsuite/runpaltests.sh /data/local/tmp/coreclr/ | ||
make BUILD_CONFIG=<Debug|Release> TARGET_ARCH=<x64|arm64> RUNTIME_FLAVOR=CoreCLR DEPLOY_AND_RUN=false run -C src/mono/sample/Android | ||
``` | ||
|
||
Then, use `adb shell` to launch a shell on Android. Inside that shell, you can launch the PAL tests: | ||
On successful execution, the command will output the `HelloAndroid.apk` at: | ||
``` | ||
LD_LIBRARY_PATH=/data/local/tmp/coreclr/lib ./runpaltests.sh /data/local/tmp/coreclr/ | ||
<repo-root>artifacts/bin/AndroidSampleApp/<x64|arm64>/<Debug|Release>/android-<x64|arm64>/Bundle/bin/HelloAndroid.apk | ||
``` | ||
|
||
Debugging coreclr on Android | ||
---------------------------- | ||
### Running HelloAndroid sample on an emulator | ||
|
||
You can debug coreclr on Android using a remote lldb server which you run on your Android device. | ||
To run the sample on an emulator, the emulator first needs to be up and running. | ||
|
||
First, push the lldb server to Android: | ||
Creating an emulator (ADV - Android Virtual Device) can be achieved through [Android Studio - Device Manager](https://developer.android.com/studio/run/managing-avds). | ||
|
||
After its creation, the emulator needs to be booted up and running, so that we can run the `HelloAndroid` sample on it via: | ||
``` | ||
adb push cross/android/lldb/2.2/android/arm64-v8a/lldb-server /data/local/tmp/ | ||
make BUILD_CONFIG=<Debug|Release> TARGET_ARCH=<x64|arm64> RUNTIME_FLAVOR=CoreCLR DEPLOY_AND_RUN=true run -C src/mono/sample/Android | ||
``` | ||
|
||
Then, launch the lldb server on the Android device. Open a shell using `adb shell` and run: | ||
|
||
> [!NOTE] | ||
> Emulators can be also started from the terminal via: | ||
> ``` | ||
> $ANDROID_SDK_ROOT/emulator/emulator -avd <emulator-name> | ||
> ``` | ||
#### WSL2 | ||
The app can be run on an emulator running on the Windows host. | ||
1. Install Android Studio on the Windows host (same versions as in [prerequisites](#prerequisite)) | ||
2. In Windows, create and start an emulator | ||
3. In WSL, swap the `adb` from the Android SDK in WSL2 with that from Windows | ||
- `mv $ANDROID_SDK_ROOT/platform-tools/adb $ANDROID_SDK_ROOT/platform-tools/adb-orig` | ||
- `ln -s /mnt/<path-to-adb-on-host> $ANDROID_SDK_ROOT/platform-tools/adb` | ||
4. In WSL, Make xharness use the `adb` corresponding to the Windows host: | ||
- `export ADB_EXE_PATH=$ANDROID_SDK_ROOT/platform-tools/adb` | ||
5. In WSL, run the `make` command as [above](#running-helloandroid-sample-on-an-emulator) | ||
### Building and running functional tests on an emulator | ||
Similarly to the `HelloAndroid` sample, it is possible to build and run a functional test on Android with CoreCLR on an emulator. | ||
To build and run a functional test on Android with CoreCLR, run the following command from `<repo_root>`: | ||
``` | ||
adb shell | ||
cd /data/local/tmp | ||
./lldb-server platform --listen *:1234 | ||
./dotnet.sh build -c Release src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj /p:TargetOS=android /p:TargetArchitecture=arm64 /t:Test /p:RuntimeFlavor=coreclr | ||
``` | ||
After that, you'll need to forward port 1234 from your Android device to your PC: | ||
> [!NOTE] | ||
> Similarly to the `HelloAndroid` sample the emulator needs to be up and running. | ||
### Useful make commands | ||
For convenience it is possible to run a single make command which builds all required dependencies, the app and runs it: | ||
``` | ||
adb forward tcp:1234 tcp:1234 | ||
make BUILD_CONFIG=<Debug|Release> TARGET_ARCH=<x64|arm64> RUNTIME_FLAVOR=CoreCLR DEPLOY_AND_RUN=true all -C src/mono/sample/Android | ||
``` | ||
Finally, install lldb on your PC and connect to the debug server running on your Android device: | ||
## Debugging the runtime and the sample app | ||
``` | ||
lldb-3.9 | ||
(lldb) platform select remote-android | ||
Platform: remote-android | ||
Connected: no | ||
(lldb) platform connect connect://localhost:1234 | ||
Platform: remote-android | ||
Triple: aarch64-*-linux-android | ||
OS Version: 23.0.0 (3.10.84-perf-gf38969a) | ||
Kernel: #1 SMP PREEMPT Fri Sep 16 11:29:29 2016 | ||
Hostname: localhost | ||
Connected: yes | ||
WorkingDir: /data/local/tmp | ||
Managed debugging is currently not supported, but we can debug: | ||
- Java portion of the sample app | ||
- Native code for the CoreCLR host and the runtime it self | ||
This can be achieved in `Android Studio` via `Profile or Debug APK`. | ||
### Steps | ||
1. Build the runtime and `HelloAndroid` sample app in `Debug` configuration targeting `arm64` target architecture. | ||
2. Rename the debug symbols file of the runtime library from `libcoreclr.so.dbg` into `libcoreclr.so.so`, the file is located at: `<repo_root>/artifacts/bin/AndroidSampleApp/arm64/Debug/android-arm64/publish/libcoreclr.so.dbg` | ||
3. Open Android Studio and select `Profile or Debug APK` project. | ||
4. Find and select the desired `.apk` file (example: `<repo_root>/artifacts/bin/AndroidSampleApp/arm64/Debug/android-arm64/Bundle/bin/HelloAndroid.apk`) | ||
5. In the project pane, expand `HelloAndroid->cpp->libcoreclr` and double-click `libcoreclr.so` | ||
 | ||
6. From the `Debug Symbols` pane on the right, select `Add` | ||
7. Navigate to the renamed file from step 2. and select it `<repo_root>/artifacts/bin/AndroidSampleApp/arm64/Debug/android-arm64/publish/libcoreclr.so.so` | ||
8. Once loaded it will show all the source files under `HelloAndroid->cpp->libcoreclr` | ||
 | ||
9. Find the `exports.cpp` and set a breakpoint in `coreclr_initialize` function and launch the debug session | ||
 | ||
(lldb) target create coreclr/pal/tests/palsuite/file_io/CopyFileA/test4/paltest_copyfilea_test4 | ||
(lldb) env LD_LIBRARY_PATH=/data/local/tmp/coreclr/lib | ||
(lldb) run | ||
> [!NOTE] | ||
> Steps 5) through 8) can be omitted if the runtime is built without stripping debug symbols to a separate file (e.g., `libcoreclr.so.dbg`). | ||
> This can be achieved by including `-keepnativesymbols true` option when building the runtime, e.g.,: | ||
> ``` | ||
> ./build.sh clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs -os android -arch <x64|arm64> -c Debug -keepnativesymbols true | ||
> ``` | ||
## See also | ||
Similar instructions for debugging Android apps with Mono runtime can be found [here](../../debugging/mono/android-debugging.md). | ||
## Troubleshooting | ||
### Android samples or functional tests fail to build | ||
If multiple JDKs are installed on your system, you may encounter the following error: | ||
``` | ||
`src/mono/msbuild/android/build/AndroidBuild.targets(237,5): error MSB4018: java.lang.NullPointerException: Cannot invoke String.length() because <parameter1> is null | ||
``` | ||
when building the Android samples or functional tests. | ||
To resolve this: | ||
1. Remove older JDK versions | ||
2. Install [OpenJDK 23](https://openjdk.org/projects/jdk/23/) | ||
3. Make sure OpenJDK 23 binaries are added to the path. | ||
- On Unix system this can be verifed via: | ||
``` | ||
$> java -version | ||
openjdk version "23.0.1" 2024-10-15 | ||
OpenJDK Runtime Environment Homebrew (build 23.0.1) | ||
OpenJDK 64-Bit Server VM Homebrew (build 23.0.1, mixed mode, sharing) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.