runtime: Unable to publish NativeAOT project for linux-bionic-arm64

Description

Building a simple Hello World sample works for the linux-bionic-x64 and linux-bionic-arm64 rids, but publishing AOT fails for linux-bionic-arm64, but works for linux-bionic-x64. The following error is thrown immediately when attempting the build,

/home/emmaus/.nuget/packages/microsoft.dotnet.ilcompiler/8.0.0-preview.6.23307.4/build/Microsoft.NETCore.Native.Publish.targets(75,5): error : The PrivateSdkAssemblies ItemGroup is required for _ComputeAssembliesToCompileToNative [/home/emmaus/test/test.csproj]

Reproduction Steps

A simple project with the required nuget packages already referenced here, https://github.com/emmauss/test-aot. Restore and build it with dotnet publish -r linux-bionic-arm64 -c Debug -p:SysRoot=/.tools/android-rootfs/android-ndk-r21/sysroot. The error is immediately thrown.

Expected behavior

The project quickly builds and a compatible executable is generated.

Actual behavior

The following error is displayed,

/home/emmaus/.nuget/packages/microsoft.dotnet.ilcompiler/8.0.0-preview.6.23307.4/build/Microsoft.NETCore.Native.Publish.targets(75,5): error : The PrivateSdkAssemblies ItemGroup is required for _ComputeAssembliesToCompileToNative [/home/emmaus/test/test.csproj]

Regression?

No response

Known Workarounds

No response

Configuration

OS: Fedora 38 on WSL2 running on Windows 11 x64 host .Net Version: 8.0.0-preview.6.23307.4 daily build

Other information

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 39 (22 by maintainers)

Commits related to this issue

Most upvoted comments

Setting lld makes it build successfully with ndk 25

Thanks for confirming! #88179 should fix this.

Thanks for confirming - I created #87862 to include this by default when targeting Bionic. Once that merges and propagates through the systems, the workaround won’t be needed.

It’s possible to try this out now:

  • Download the latest installer build from dotnet/installer repo. I just download the ZIP variant and unpack it somewhere.
  • Download Android NDK and unpack it somewhere. If you have Android Studio, you probably already have this somewhere.
  • Then (these instructions are for Windows, but basically just replace set with export for Linux):
    # Put the downloaded installer on PATH (update the path as necessary)
    $ set path=c:\net8;%path%
    # Put the downloaded Android NDK on PATH (update path as necessary) - we need Android clang to be first on PATH
    $ set path=C:\Programs\android-ndk-r21b\toolchains\llvm\prebuilt\windows-x86_64\bin;%path%
    # Make a new console app. Shared libraries should also work but I didn't test.
    # If you get a failure during restore, you need to create a NuGet.config as described
    # in the root README.md of the dotnet/installer repo.
    $ dotnet new console -o HelloBionic --aot
    $ cd HelloBionic
    # Publish for ARM64 Bionic. Current gotchas:
    # 1. Needs to be a Debug build. This is fixed, but the fix didn't reach installer repo yet.
    # 2. Need to specify StripSymbols=false. Didn't look into this yet.
    # 3. Need to specify InvariantGlobalization=true (the `dotnet new console --aot` template does this) or you get a FailFast. Didn't look into this yet.
    $ dotnet publish -r linux-bionic-arm64 -c Debug -p:DisableUnsupportedError=true -p:PublishAotUsingRuntimePack=true -p:StripSymbols=false
    
  • You should have a binary under bin\Debug\net8.0\linux-bionic-arm64\publish. Copy this 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. There will also be a warning, that one is also fixed and will be in dotnet/installer in a day or two.

The more interesting variation of this is building shared libraries that you can call into with JNI. There’s a sample for that at https://github.com/josephmoresena/NativeAOT-AndroidHelloJniLib. The instructions obviously don’t explain how to use this with today’s bits, but @josephmoresena should be able to greatly simplify it soon (or you can send a PR).

Cc @kekekeks @maxkatz6

I think, in the unlikely event, when this (platform->[default]linker) list becomes large or unmaintainable, we can replace it with the detection but for now™️, lets add the third one for linux-bionic. 😃

Sounds good, thank you! @emmauss if you can confirm <LinkerFlavor>lld</LinkerFlavor> resolves this, I can make this the default for Bionic.

Setting <LinkerFlavor>lld</LinkerFlavor> makes it build successfully with ndk 25

We can deal with that problem once/if Unity runs into it. This is not the only place where Android treatment is debatable today. For example, OperatingSystem.IsLinux() returns false for Android RID with Java interop today.

cannot locate symbol "__android_log_print" referenced by "XXlib/arm/libsample.so"...

Can you try adding this to the project file, delete obj and bin directories and publish again?

<ItemGroup>
  <LinkerArg Include="-llog" />
</ItemGroup>

Adding this works, and I’m able to call functions from the library. Thanks.

cannot locate symbol "__android_log_print" referenced by "XXlib/arm/libsample.so"...

Can you try adding this to the project file, delete obj and bin directories and publish again?

<ItemGroup>
  <LinkerArg Include="-llog" />
</ItemGroup>