Skip to content

NDK default version needs bumping with NativeAOT #10539

@jonpryor

Description

@jonpryor

Android framework version

net10.0-android (Preview)

Affected platform version

.NET 10 RC2

Description

Funnily enough, this started happening with .NET 10 RC2.

Consider the repro at: #10463

It builds for NativeAOT for me under .NET 10 RC1:

% export PATH=$HOME/Downloads/dotnet-sdk-10.0.100-rc.1.25451.107-osx-x64:$PATH
% dotnet build -c Release -p:PublishAot=true
# no errors, 5 warnings

It fails to build for NativeAOT for me under .NET 10 RC2:

% export PATH=$HOME/Downloads/dotnet-sdk-10.0.100-rc.2.25502.107-osx-x64:$PATH
% dotnet build -c Release -p:PublishAot=true
…
    ld.lld : error undefined symbol: std::__ndk1::__libcpp_verbose_abort(char const*, ...)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, float, std::__ndk1::chars_format, int)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, float, std::__ndk1::chars_format)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, float)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, double, std::__ndk1::chars_format, int)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, double, std::__ndk1::chars_format)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, double)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, __float128, std::__ndk1::chars_format, int)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, __float128, std::__ndk1::chars_format)
    ld.lld : error undefined symbol: std::__ndk1::to_chars(char*, char*, __float128)
    clang-14 : error linker command failed with exit code 1 (use -v to see invocation)
    …
    $HOME/.nuget/packages/microsoft.dotnet.ilcompiler/10.0.0-rc.2.25502.107/build/Microsoft.NETCore.Native.targets(389,5): error MSB3073: The command ""clang" "obj/Release/net10.0-android/android-x64/native/Scratch.net10-android-sha1-create.o" -o "bin/Release/net10.0-android/android-x64/native/Scratch.net10-android-sha1-create.so" -Wl,--version-script="obj/Release/net10.0-android/android-x64/native/Scratch.net10-android-sha1-create.exports" -Wl,--export-dynamic -fuse-ld=lld /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libSystem.Native.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libSystem.Globalization.Native.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libSystem.IO.Compression.Native.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libSystem.Security.Cryptography.Native.Android.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libbootstrapperdll.o /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libRuntime.WorkstationGC.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libeventpipe-disabled.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libRuntime.VxsortDisabled.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libstandalonegc-disabled.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libaotminipal.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libbrotlienc.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libbrotlidec.a /Users/jon/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.android-x64/10.0.0-rc.2.25502.107/runtimes/android-x64/native/libbrotlicommon.a --target=x86_64-linux-android21 -g -Wl,--build-id=sha1 -Wl,--as-needed -Wl,-e,0x0 -pthread -ldl -lz -llog -lm -shared -Wl,-z,relro -Wl,-z,now -Wl,--eh-frame-hdr -Wl,-z,max-page-size=16384 "-Wl,-soname,libScratch.net10-android-sha1-create.so" -Wl,--error-unresolved-symbols -Wl,--no-undefined /Users/jon/Downloads/dotnet-sdk-10.0.100-rc.2.25502.107-osx-x64/packs/Microsoft.Android.Runtime.NativeAOT.36.android-x64/36.0.0-rc.2.332/runtimes/android-x64/native/libnaot-android.release-static-release.a /Users/jon/android-toolchain/sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_static.a /Users/jon/android-toolchain/sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++abi.a obj/Release/net10.0-android/android-x64/android/jni_init_funcs.x86_64.o obj/Release/net10.0-android/android-x64/android/environment.x86_64.o -Wl,--discard-all -Wl,--gc-sections -Wl,-T,"obj/Release/net10.0-android/android-x64/native/sections.ld"" exited with code 1.
…
Build failed with 24 error(s) and 3 warning(s) in 27.8s

?!

Turns Out™ that the issue is the NDK that is used: my failing NativeAOT build is using NDK 25.1.8937393, which doesn't work.

"Okay," thinks I, "what about using the default NDK"?

Update Scratch.net10-android-sha1-create.csproj to contain:

  <ItemGroup>
    <AndroidDependency Include="ndk/$(AndroidNdkVersion)" Version="$(AndroidNdkVersion)" />
  </ItemGroup>

(This forces provisioning of an NDK from the InstallAndroidDependencies target.)

Note: $(AndroidNdkVersion) is 26.1.10909125 in .NET 10 RC2.

Then run Our Favorite:

dotnet build -t:InstallAndroidDependencies -p:AndroidSdkDirectory=`pwd`.sdk -bl -p:AcceptAndroidSDKLicenses=true

Try to build under .NET 10 RC2, and:

% dotnet build -c Release -p:PublishAot=true -p:AndroidSdkDirectory=`pwd`.sdk -bl
…
  Scratch.net10-android-sha1-create net10.0-android android-x64 failed with 2 error(s) (1.3s)
    clang-17 : error no input files
    $HOME/.nuget/packages/microsoft.dotnet.ilcompiler/10.0.0-rc.2.25502.107/build/Microsoft.NETCore.Native.Unix.targets(321,5): error MSB3073: The command ""clang" -fuse-ld=lld -Wl,--version" exited with code 1.
  Scratch.net10-android-sha1-create net10.0-android android-arm64 failed with 2 error(s) (1.5s)
    clang-17 : error no input files
    $HOME/.nuget/packages/microsoft.dotnet.ilcompiler/10.0.0-rc.2.25502.107/build/Microsoft.NETCore.Native.Unix.targets(321,5): error MSB3073: The command ""clang" -fuse-ld=lld -Wl,--version" exited with code 1.
  Scratch.net10-android-sha1-create net10.0-android failed with 1 warning(s) (8.0s) → bin/Release/net10.0-android/Scratch.net10-android-sha1-create.dll
…
Build failed with 4 error(s) and 1 warning(s) in 11.1s

?!

Indeed, this command fails:

% `pwd`.sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -fuse-ld=lld -Wl,--version
…/Scratch.net10-android-sha1-create.sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang: line 1: clang-17: command not found

Update it to use clang-17 instead of clang, and:

% `pwd`.sdk/ndk/26.1.10909125/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang-17 -fuse-ld=lld -Wl,--version
clang-17: error: unable to execute command: posix_spawn failed: Exec format error
clang-17: error: linker command failed with exit code 1 (use -v to see invocation)

Which is a long way of saying that (default!) NDK 26.1.10909125 doesn't work either!

What other NDKs are readily accessible? Turning my attention to https://aka.ms/AndroidManifestFeed/d17-14 (485cb4d), it currently includes NDKs:

  • 28.0.12916984.3
  • 27.2.12479018

among others.

Update Scratch.net10-android-sha1-create.csproj with:

  <ItemGroup>
    <AndroidDependency Include="ndk/27.2.12479018" Version="27.2.12479018" />
  </ItemGroup>

i.e. provision NDK 27.2.12479018, re-run dotnet build -t:InstallAndroidDependencies, rebuild with dotnet build -p:PublishAot=true, and:

% dotnet build -c Release -p:PublishAot=true -p:AndroidSdkDirectory=`pwd`.sdk -bl
…
Build succeeded with 3 warning(s) in 58.9s

It works!

Which is a very long-winded way of saying that the default NDK version should be bumped to at least NDK r27, which in turn means that AndroidSdkBase.MaximumCompatibleNDKMajorVersion should be bumped to at least 27:

https://github.com/dotnet/android-tools/blob/2609c38a8d3232ba24c4a70cb88be3f505dab5bd/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs#L14

Additionally, it would be "nice" if the build system could preemptively warn if the NDK version is "known bad" for NativeAOT compilation purposes. The above ld.lld : error messages were very confusing and had me stumped until I thought that the NDK was the problem.


(Additionally, for reasons I no longer remember, $HOME/android-toolchain/sdk/ndk exists on my machine, which is why NDK r25 was being used even though monodroid-config.xml specified $HOME/android-toolchain/ndk which is NDK r28! Which brings us to…)

Other questions:

Why is the "SDK-bundled NDK" given priority over $HOME/.config/xbuild/monodroid-config.xml? I don't remember, and dotnet/android-tools@b2d9fdf doesn't explain why the bundled NDK should be given precedence over an explicitly configured NDK.

https://github.com/dotnet/android-tools/blob/2609c38a8d3232ba24c4a70cb88be3f505dab5bd/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs#L124

Steps to Reproduce

See rambling description. It's a story! (I love creative writing!)

Did you find any workaround?

No response

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: App+Library BuildIssues when building Library projects or Application projects.needs-triageIssues that need to be assigned.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions