Skip to content

Commit

Permalink
Re-fix macOS host + linux-bionic-arm64 target cross-compile
Browse files Browse the repository at this point in the history
Context: a2fd74c
Context: https://github.com/dotnet/runtime/blob/132725d3702d51d78b5f68b0501c5e5845921d04/src/coreclr/nativeaot/docs/android-bionic.md#known-issues

Commit a2fd74c had a fatal flaw: it would immediately crash on launch:

	F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
	F DEBUG   : Build fingerprint: 'google/raven/raven:14/AP1A.240305.019.A1/11445699:user/release-keys'
	F DEBUG   : Revision: 'MP1.0'
	F DEBUG   : ABI: 'arm64'
	F DEBUG   : Timestamp: 2024-05-01 11:01:48.710687354-0400
	F DEBUG   : Process uptime: 1s
	F DEBUG   : Cmdline: com.jonathanpeppers.nativeaot
	F DEBUG   : pid: 10516, tid: 10516, name: ppers.nativeaot  >>> com.jonathanpeppers.nativeaot <<<
	F DEBUG   : uid: 10371
	F DEBUG   : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
	F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000006
	F DEBUG   : Cause: null pointer dereference
	F DEBUG   :     x0  0000000000000006  x1  0000007fda6f3340  x2  0000007eb6852980  x3  0000007fda6ef330
	F DEBUG   :     x4  0000007eb6852a00  x5  0000000000000004  x6  0000000001414d4c  x7  0000007eb6852004
	F DEBUG   :     x8  0000007eb6852980  x9  0000000000000006  x10 000000000000000f  x11 757274736e6f6320
	F DEBUG   :     x12 676e696c6c61632c  x13 000180000045dfd0  x14 0000000000018510  x15 0000000000000000
	F DEBUG   :     x16 0000007eb7b3d680  x17 0000007eb7a5fb00  x18 0000007eb6d90000  x19 0000007fda6f3340
	F DEBUG   :     x20 0000007eb6852980  x21 0000000000000006  x22 0000007eb7b4b000  x23 0000007eb67c9e70
	F DEBUG   :     x24 0000007fda6f0518  x25 0000000000000022  x26 0000007eb6843c00  x27 0000007fda6f0500
	F DEBUG   :     x28 0000007eb7b49000  x29 0000007fda6ef2e0
	F DEBUG   :     lr  0000007b57aebc80  sp  0000007fda6ef2c0  pc  0000007b57aebcb0  pst 0000000080001000
	F DEBUG   : 1 total frames
	F DEBUG   : backtrace:
	F DEBUG   :       #00 pc 00000000000c1cb0  /data/app/~~y5LQdnO4d1iwNk2Z6I4Jpg==/com.jonathanpeppers.nativeaot-HJbM4Jw2CNRiWe4-Rn2IxA==/lib/arm64/libdotnet.so (BuildId: 21c56035e6fc411dab6ab373715ba35e82c0fb5f)

Turns out™ that the [android-bionic.md][0] documentation has a
[Known issues][1] section, which has a *better* workaround:

> If you hit
> `error : version script assignment of 'V1.0' to symbol '_init' failed: symbol not defined` -
> this is a known issue with .NET 8 release dotnet/runtime#92272, you
> can add following lines to your csproj to work around:
>
> ```xml
> <ItemGroup Condition="$(RuntimeIdentifier.StartsWith('linux-bionic'))">
>   <LinkerArg Include="-Wl,--undefined-version" />
> </ItemGroup>
> ```

That workaround *does* work, better than the attempted workaround in
a2fd74c.

Update `libdotnet.targets` to use the documented workaround.

Additionally, `libdotnet.so` depends on `libc++_shared.so`:

	% $ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf -a DotNet/bin/Release/net8.0/linux-bionic-arm64/publish/libdotnet.so
	  0x0000000000000001 (NEEDED)       Shared library: [libdl.so]
	  0x0000000000000001 (NEEDED)       Shared library: [libc++_shared.so]
	  0x0000000000000001 (NEEDED)       Shared library: [libc.so]

and `libc++_shared.so` needs to be included in the `.apk`.

Add a new `_CopyLibcppShared` target which copies `libc++_shared.so`
from the NDK into `Native/app/src/main/jniLibs/arm64-v8a`.  Failure
to do so results in an error at startup:

	E AndroidRuntime: java.lang.UnsatisfiedLinkError: Unable to load native library "/data/app/~~p6cCHwNVFV8uzhECCUKmCg==/com.jonathanpeppers.nativeaot-wVDfzgY8K6AbDgBPnccb_w==/lib/arm64/libnativeaot.so":
	dlopen failed: library "libc++_shared.so" not found: needed by /data/app/~~p6cCHwNVFV8uzhECCUKmCg==/com.jonathanpeppers.nativeaot-wVDfzgY8K6AbDgBPnccb_w==/lib/arm64/libdotnet.so in namespace clns-4

Update `README.md` to contain clear(er) instruction on how to build
and run this sample.

[0]: https://github.com/dotnet/runtime/blob/132725d3702d51d78b5f68b0501c5e5845921d04/src/coreclr/nativeaot/docs/android-bionic.md
[1]: https://github.com/dotnet/runtime/blob/132725d3702d51d78b5f68b0501c5e5845921d04/src/coreclr/nativeaot/docs/android-bionic.md#known-issues
  • Loading branch information
jonpryor committed May 1, 2024
1 parent a2fd74c commit 81a9388
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
19 changes: 14 additions & 5 deletions DotNet/libdotnet.targets
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@
</PropertyGroup>

<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith('linux-bionic'))">
<LinkStandardCPlusPlusLibrary>true</LinkStandardCPlusPlusLibrary>
<CppCompilerAndLinker>$(_NdkBinDir)/$(_NdkClangPrefix)clang++</CppCompilerAndLinker>
<ObjCopyName>$(_NdkBinDir)/llvm-objcopy</ObjCopyName>
</PropertyGroup>

<ItemGroup Condition="$(RuntimeIdentifier.StartsWith('linux-bionic'))">
<LinkerArg Include="-Wl,--defsym,_init=__libc_init" />
<LinkerArg Include="-Wl,--defsym,_fini=__libc_fini" />
<LinkerArg Include="-L &quot;$(_NdkSysrootDir)&quot;" />
<NativeSystemLibrary Include="c" />
<LinkerArg Include="-Wl,--undefined-version" />
</ItemGroup>

<Target Name="_ValidateEnvironment"
Expand All @@ -32,4 +28,17 @@
Text="NDK 'sysroot' dir `$(_NdkSysrootDir)` does not exist. You're on your own."
/>
</Target>

<Target Name="_CopyLibcppShared"
AfterTargets="Publish">
<PropertyGroup>
<_JniLibsDir>../Native/app/src/main/jniLibs/arm64-v8a</_JniLibsDir>
</PropertyGroup>
<MakeDir Directories="../Native/app/src/main/jniLibs/arm64-v8a" />
<ItemGroup>
<_Source Include="$(_NdkSysrootDir)\libc++_shared.so" />
<_Target Include="$(_JniLibsDir)\libc++_shared.so" />
</ItemGroup>
<Copy SourceFiles="@(_Source)" DestinationFiles="@(_Target)" />
</Target>
</Project>
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,33 @@

A .NET 8, NativeAOT example on Android.

## Getting started

Configure your environment: the following environment variables are required:

* `ANDROID_NDK_HOME`: The path to an Android NDK installation.
* `ANDROID_HOME`: The path to an Android SDK installation.

Build the project:

```console
dotnet build
dotnet publish DotNet/libdotnet.csproj
(cd Native && ./gradlew assembleRelease)
```

Install the app:

```console
$ANDROID_HOME/platform-tools/adb install Native/app/build/outputs/apk/release/app-release.apk
```

Run the app:

```console
$ANDROID_HOME/platform-tools/adb shell am start com.jonathanpeppers.nativeaot/android.app.NativeActivity
```

## Example using SkiaSharp

This sample has a C++ Android Studio project:
Expand Down

0 comments on commit 81a9388

Please sign in to comment.