Skip to content

Commit e7e5f61

Browse files
committed
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) ...
2 parents 21f8a18 + 0004083 commit e7e5f61

File tree

225 files changed

+4725
-3169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

225 files changed

+4725
-3169
lines changed

.config/dotnet-tools.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
]
1616
},
1717
"microsoft.dotnet.xharness.cli": {
18-
"version": "10.0.0-prerelease.25077.1",
18+
"version": "10.0.0-prerelease.25103.1",
1919
"commands": [
2020
"xharness"
2121
]

docs/area-owners.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
1818
| area-Codeflow | @dotnet/dnr-codeflow | @dotnet/dnr-codeflow | Used for automated PRs that ingest code from other repos |
1919
| area-Codegen-AOT-mono | @steveisok | @kotlarmilos | |
2020
| area-CodeGen-coreclr | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | |
21+
| area-Codegen-Interpreter-coreclr | @vitek-karas | @BrzVlad @janvorli | |
2122
| area-Codegen-Interpreter-mono | @vitek-karas | @BrzVlad @kotlarmilos | |
2223
| area-Codegen-Intrinsics-mono | @steveisok | @fanyang-mono | |
2324
| area-Codegen-JIT-mono | @steveisok | | |
2425
| area-Codegen-LLVM-mono | @steveisok | | |
2526
| area-Codegen-meta-mono | @steveisok | | |
26-
| area-CrossGen/NGEN-coreclr | @steveisok | @dotnet/crossgen-contrib | |
2727
| area-crossgen2-coreclr | @steveisok | @dotnet/crossgen-contrib | |
2828
| area-Debugger-mono | @tommcdon | @thaystg | |
2929
| area-DependencyModel | @ericstj | @dotnet/area-dependencymodel | Included:<ul><li>Microsoft.Extensions.DependencyModel</li></ul> |
Loading
Loading
Loading
+170-58
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,212 @@
1-
Cross Compilation for Android on Linux
2-
======================================
1+
# Experimental support of CoreCLR on Android
32

4-
Through cross compilation, on Linux it is possible to build CoreCLR for arm64 Android.
3+
This is the internal documentation which outlines experimental support of CoreCLR on Android and includes instructions on how to:
4+
- [Build CoreCLR for Android](./android.md#building-coreclr-for-android)
5+
- [Build and run a sample application with CoreCLR](./android.md#building-and-running-a-sample-app)
6+
- [Debug the sample app and the runtime](./android.md#debugging-the-runtime-and-the-sample-app)
57

6-
Requirements
7-
------------
8+
## Prerequisite
89

9-
You'll need to generate a toolchain and a sysroot for Android. There's a script which takes care of the required steps.
10+
- Download and install [OpenJDK 23](https://openjdk.org/projects/jdk/23/)
11+
- Download and install [Android Studio](https://developer.android.com/studio/install) and the following:
12+
- Android SDK (minimum supported API level is 21)
13+
- Android NDK r27
1014

11-
Generating the rootfs
12-
---------------------
15+
> [!NOTE]
16+
> Prerequisites can also be downloaded and installed manually:
17+
> - by running the automated script as described in [Testing Libraries on Android](../../testing/libraries/testing-android.md#using-a-terminal)
18+
> - by downloading the archives:
19+
> - Android SDK - Download [command-line tools](https://developer.android.com/studio#command-line-tools-only) and use `sdkmanager` to download the SDK.
20+
> - Android NDK - Download [NDK](https://developer.android.com/ndk/downloads)
1321
14-
To generate the rootfs, run the following command in the `coreclr` folder:
22+
## Building CoreCLR for Android
23+
24+
Supported host systems for building CoreCLR for Android:
25+
- [MacOS](./android.md#macos-and-linux)
26+
- [Linux](./android.md#macos-and-linux)
27+
- [Windows](./android.md#windows) ❌ (only through WSL)
28+
29+
Supported target architectures:
30+
- x86 ❌
31+
- x64 ✔
32+
- arm ❌
33+
- arm64 ✔
34+
35+
### MacOS and Linux
36+
37+
#### Requirements
38+
39+
Set the following environment variables:
40+
- ANDROID_SDK_ROOT=`<full-path-to-android-sdk>`
41+
- ANDROID_NDK_ROOT=`<full-path-to-android-ndk>`
42+
43+
#### Building the runtime, libraries and tools
44+
45+
To build CoreCLR runtime, libraries and tools for local development, run the following command from `<repo-root>`:
1546

1647
```
17-
cross/init-android-rootfs.sh
48+
./build.sh clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs -os android -arch <x64|arm64> -c <Debug|Release>
1849
```
1950

20-
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.
51+
To build CoreCLR runtime NuGet packages, run the following command from `<repo-root>`:
52+
53+
```
54+
./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>
55+
```
2156

57+
> [!NOTE]
58+
> The runtime packages will be located at: `<repo-root>/artifacts/packages/<configuration>/Shipping/`
2259
23-
Cross compiling CoreCLR
24-
-----------------------
25-
Once the rootfs has been generated, it will be possible to cross compile CoreCLR.
60+
### Windows
2661

27-
When cross compiling, you need to set both the `CONFIG_DIR` and `ROOTFS_DIR` variables.
62+
Building on Windows is not directly supported yet. However it is possible to use WSL2 for this purpose.
2863

29-
To compile for arm64, run:
64+
#### WSL2
65+
66+
##### Requirements
67+
68+
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.
69+
- In case of Android Studio:
70+
- Make sure WSL is updated: from Windows host, `wsl --update`
71+
- [Enabled systemd](https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/#set-the-systemd-flag-set-in-your-wsl-distro-settings)
72+
- `sudo snap install android-studio --classic`
73+
2. Set the following environment variables:
74+
- ANDROID_SDK_ROOT=`<full-path-to-android-sdk>`
75+
- ANDROID_NDK_ROOT=`<full-path-to-android-ndk>`
76+
77+
#### Building the runtime, libraries and tools
78+
79+
To build CoreCLR runtime, libraries and tools, run the following command from `<repo-root>`:
3080

3181
```
32-
CONFIG_DIR=`realpath cross/android/arm64` ROOTFS_DIR=`realpath cross/android-rootfs/toolchain/arm64/sysroot` ./build.sh cross arm64 cmakeargs -DENABLE_LLDBPLUGIN=0
82+
./build.sh clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs -os android -arch <x64|arm64> -c <Debug|Release>
3383
```
3484

35-
The resulting binaries will be found in `artifacts/bin/coreclr/Linux.BuildArch.BuildType/`
85+
## Building and running a sample app
86+
87+
To demonstrate building and running an Android sample application with CoreCLR, we will use:
88+
- the [HelloAndroid sample app](../../../../src/mono/sample/Android/AndroidSampleApp.csproj).
89+
- a functional tests [Android.Device_Emulator.JIT.Test](../../../../src/tests/FunctionalTests/Android/Device_Emulator/JIT/Android.Device_Emulator.JIT.Test.csproj)
3690

37-
Running the PAL tests on Android
38-
--------------------------------
91+
A prerequisite for building and running samples locally is to have CoreCLR successfully built for desired Android platform.
3992

40-
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
41-
`adb`, and then run them in an interactive Android shell using `adb shell`:
93+
### Building HelloAndroid sample
94+
95+
To build `HelloAndroid`, run the following command from `<repo_root>`:
4296

43-
To copy the PAL tests over to an Android phone:
4497
```
45-
adb push artifacts/obj/coreclr/Linux.arm64.Debug/src/pal/tests/palsuite/ /data/local/tmp/coreclr/pal/tests/palsuite
46-
adb push cross/android/toolchain/arm64/sysroot/usr/lib/libandroid-support.so /data/local/tmp/coreclr/lib/
47-
adb push cross/android/toolchain/arm64/sysroot/usr/lib/libandroid-glob.so /data/local/tmp/coreclr/lib/
48-
adb push src/pal/tests/palsuite/paltestlist.txt /data/local/tmp/coreclr
49-
adb push src/pal/tests/palsuite/runpaltests.sh /data/local/tmp/coreclr/
98+
make BUILD_CONFIG=<Debug|Release> TARGET_ARCH=<x64|arm64> RUNTIME_FLAVOR=CoreCLR DEPLOY_AND_RUN=false run -C src/mono/sample/Android
5099
```
51100

52-
Then, use `adb shell` to launch a shell on Android. Inside that shell, you can launch the PAL tests:
101+
On successful execution, the command will output the `HelloAndroid.apk` at:
53102
```
54-
LD_LIBRARY_PATH=/data/local/tmp/coreclr/lib ./runpaltests.sh /data/local/tmp/coreclr/
103+
<repo-root>artifacts/bin/AndroidSampleApp/<x64|arm64>/<Debug|Release>/android-<x64|arm64>/Bundle/bin/HelloAndroid.apk
55104
```
56105

57-
Debugging coreclr on Android
58-
----------------------------
106+
### Running HelloAndroid sample on an emulator
59107

60-
You can debug coreclr on Android using a remote lldb server which you run on your Android device.
108+
To run the sample on an emulator, the emulator first needs to be up and running.
61109

62-
First, push the lldb server to Android:
110+
Creating an emulator (ADV - Android Virtual Device) can be achieved through [Android Studio - Device Manager](https://developer.android.com/studio/run/managing-avds).
63111

112+
After its creation, the emulator needs to be booted up and running, so that we can run the `HelloAndroid` sample on it via:
64113
```
65-
adb push cross/android/lldb/2.2/android/arm64-v8a/lldb-server /data/local/tmp/
114+
make BUILD_CONFIG=<Debug|Release> TARGET_ARCH=<x64|arm64> RUNTIME_FLAVOR=CoreCLR DEPLOY_AND_RUN=true run -C src/mono/sample/Android
66115
```
67116

68-
Then, launch the lldb server on the Android device. Open a shell using `adb shell` and run:
117+
118+
> [!NOTE]
119+
> Emulators can be also started from the terminal via:
120+
> ```
121+
> $ANDROID_SDK_ROOT/emulator/emulator -avd <emulator-name>
122+
> ```
123+
124+
#### WSL2
125+
126+
The app can be run on an emulator running on the Windows host.
127+
1. Install Android Studio on the Windows host (same versions as in [prerequisites](#prerequisite))
128+
2. In Windows, create and start an emulator
129+
3. In WSL, swap the `adb` from the Android SDK in WSL2 with that from Windows
130+
- `mv $ANDROID_SDK_ROOT/platform-tools/adb $ANDROID_SDK_ROOT/platform-tools/adb-orig`
131+
- `ln -s /mnt/<path-to-adb-on-host> $ANDROID_SDK_ROOT/platform-tools/adb`
132+
4. In WSL, Make xharness use the `adb` corresponding to the Windows host:
133+
- `export ADB_EXE_PATH=$ANDROID_SDK_ROOT/platform-tools/adb`
134+
5. In WSL, run the `make` command as [above](#running-helloandroid-sample-on-an-emulator)
135+
136+
### Building and running functional tests on an emulator
137+
138+
Similarly to the `HelloAndroid` sample, it is possible to build and run a functional test on Android with CoreCLR on an emulator.
139+
140+
To build and run a functional test on Android with CoreCLR, run the following command from `<repo_root>`:
69141
70142
```
71-
adb shell
72-
cd /data/local/tmp
73-
./lldb-server platform --listen *:1234
143+
./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
74144
```
75145
76-
After that, you'll need to forward port 1234 from your Android device to your PC:
146+
> [!NOTE]
147+
> Similarly to the `HelloAndroid` sample the emulator needs to be up and running.
148+
149+
### Useful make commands
150+
151+
For convenience it is possible to run a single make command which builds all required dependencies, the app and runs it:
77152
```
78-
adb forward tcp:1234 tcp:1234
153+
make BUILD_CONFIG=<Debug|Release> TARGET_ARCH=<x64|arm64> RUNTIME_FLAVOR=CoreCLR DEPLOY_AND_RUN=true all -C src/mono/sample/Android
79154
```
80155
81-
Finally, install lldb on your PC and connect to the debug server running on your Android device:
156+
## Debugging the runtime and the sample app
82157
83-
```
84-
lldb-3.9
85-
(lldb) platform select remote-android
86-
Platform: remote-android
87-
Connected: no
88-
(lldb) platform connect connect://localhost:1234
89-
Platform: remote-android
90-
Triple: aarch64-*-linux-android
91-
OS Version: 23.0.0 (3.10.84-perf-gf38969a)
92-
Kernel: #1 SMP PREEMPT Fri Sep 16 11:29:29 2016
93-
Hostname: localhost
94-
Connected: yes
95-
WorkingDir: /data/local/tmp
158+
Managed debugging is currently not supported, but we can debug:
159+
- Java portion of the sample app
160+
- Native code for the CoreCLR host and the runtime it self
161+
162+
This can be achieved in `Android Studio` via `Profile or Debug APK`.
163+
164+
### Steps
165+
166+
1. Build the runtime and `HelloAndroid` sample app in `Debug` configuration targeting `arm64` target architecture.
167+
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`
168+
3. Open Android Studio and select `Profile or Debug APK` project.
169+
4. Find and select the desired `.apk` file (example: `<repo_root>/artifacts/bin/AndroidSampleApp/arm64/Debug/android-arm64/Bundle/bin/HelloAndroid.apk`)
170+
5. In the project pane, expand `HelloAndroid->cpp->libcoreclr` and double-click `libcoreclr.so`
171+
![Adding debug symbols](./android-studio-coreclr-debug-symbols-adding.png)
172+
6. From the `Debug Symbols` pane on the right, select `Add`
173+
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`
174+
8. Once loaded it will show all the source files under `HelloAndroid->cpp->libcoreclr`
175+
![Debug symbols loaded](./android-studio-coreclr-debug-symbols-adding.png)
176+
9. Find the `exports.cpp` and set a breakpoint in `coreclr_initialize` function and launch the debug session
177+
![Debugging CoreCLR](./android-studio-coreclr-debugging.png)
96178
97-
(lldb) target create coreclr/pal/tests/palsuite/file_io/CopyFileA/test4/paltest_copyfilea_test4
98-
(lldb) env LD_LIBRARY_PATH=/data/local/tmp/coreclr/lib
99-
(lldb) run
179+
> [!NOTE]
180+
> 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`).
181+
> This can be achieved by including `-keepnativesymbols true` option when building the runtime, e.g.,:
182+
> ```
183+
> ./build.sh clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs -os android -arch <x64|arm64> -c Debug -keepnativesymbols true
184+
> ```
185+
186+
## See also
187+
188+
Similar instructions for debugging Android apps with Mono runtime can be found [here](../../debugging/mono/android-debugging.md).
189+
190+
## Troubleshooting
191+
192+
### Android samples or functional tests fail to build
193+
194+
If multiple JDKs are installed on your system, you may encounter the following error:
195+
196+
```
197+
`src/mono/msbuild/android/build/AndroidBuild.targets(237,5): error MSB4018: java.lang.NullPointerException: Cannot invoke String.length() because <parameter1> is null
100198
```
199+
200+
when building the Android samples or functional tests.
201+
202+
To resolve this:
203+
1. Remove older JDK versions
204+
2. Install [OpenJDK 23](https://openjdk.org/projects/jdk/23/)
205+
3. Make sure OpenJDK 23 binaries are added to the path.
206+
- On Unix system this can be verifed via:
207+
```
208+
$> java -version
209+
openjdk version "23.0.1" 2024-10-15
210+
OpenJDK Runtime Environment Homebrew (build 23.0.1)
211+
OpenJDK 64-Bit Server VM Homebrew (build 23.0.1, mixed mode, sharing)
212+
```

eng/CodeAnalysis.src.globalconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,7 @@ dotnet_diagnostic.SA1013.severity = none
11781178
dotnet_diagnostic.SA1014.severity = warning
11791179

11801180
# SA1015: Closing generic bracket should not be followed by a space
1181-
dotnet_diagnostic.SA1015.severity = none
1181+
dotnet_diagnostic.SA1015.severity = warning
11821182

11831183
# SA1018: Nullable type symbol should not be preceded by a space
11841184
dotnet_diagnostic.SA1018.severity = warning

0 commit comments

Comments
 (0)