Skip to content

[xabt] Route NativeAOT linking and native stripping through NDK - #12970

Merged
simonrozsival merged 11 commits into
mainfrom
simonrozsival-official-ndk-tool-routing
Oct 6, 2026
Merged

simonrozsival merged 11 commits into
mainfrom
simonrozsival-official-ndk-tool-routing

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

Part of #12940.

NativeAOT currently defaults to workload-provided linker tools and
runtime-pack CRT/sysroot/compiler-runtime assets. Optional native
library stripping also uses a bundled tool and can package an unstripped
fallback after a failed command. Route these two consumers through a
complete, official Android NDK without imposing an NDK requirement on
ordinary CoreCLR builds.

Move <ResolveAndroidNdk/>, <LinkNativeAotSharedLibrary/>, and
<SetIlcToolchainPath/> into the modern build-task assembly. NativeAOT
always resolves NDK ld.lld, llvm-objcopy, CRT objects, sysroot libraries,
and compiler-rt; remove the workload-linker fallback for this path.
Preserve main's generated JNI-init/environment objects and their link
order, ARM EHABI globalization/weakening in a copied GC archive, and
extract-debug -> strip -> add-debuglink ordering. Remove incomplete
shared libraries and native sidecars on tool failure.

Route $(AndroidStripNativeLibraries)=true through NDK llvm-strip for
Debug/Fast Deployment and Release APK/AAB packaging. Strip intermediate
copies, leave project/runtime-pack inputs unchanged, report missing
NDK/tools and failed strip commands, and never package an unstripped
fallback after a failed strip. Include the effective runtime and strip
flag in dependency discovery/property caching, and persist stripped
copies in @(FileWrites) across late packaging, incremental builds, and
Clean.

Keep the remaining shared NativeLinker callers, DSO wrapper
configuration/cleanup, runtime-pack library directories, LLVM generation,
and bundled tool download/distribution/runtime-pack assets intact. This
is a standalone main-targeting slice: no bootstrap, remapping, typemap
removal, ELF writer, discrete/store wrapper, installer, or runtime-pack
pruning changes, and no dependency on the other PoC PRs.

Validation:

Coverage Result
Modern resolver/linker/ILC PATH unit cases 28 passed, 0 skipped
Main-based workload integration cases 24 passed, 0 skipped

Integration covers all three NativeAOT ABIs, retained generated objects,
actual weak ARM EHABI symbols, ordinary CoreCLR without an NDK, effective
runtime dependency discovery, missing NDK diagnostics, Debug/Release
APK/AAB strip copies and dynamic exports, original preservation,
incremental off/on repackaging, FileWrites/Clean, and corrupt-input strip
failure. Unit coverage includes missing tools/sysroot/Clang directories,
response order, and link/debug-sidecar failure cleanup.

Use a private APFS-cloned SDK/toolchain seed, then rebuild this branch's
shipped tasks/targets, API 37/37.1/37.2 bindings, host test/config outputs,
and freshly configured CoreCLR/NativeAOT native runtimes; regenerate the
local workload before running integration. No parent PoC build outputs
are used as the validation baseline. No baseline blockers encountered;
device tests and Windows/Linux host execution are not run.

  • Useful description of why the change is necessary
  • Related issue linked without closing the umbrella issue
  • Unit and integration tests

Route NativeAOT final linking and ARM EHABI archive preparation through the installed Android NDK while preserving generated JNI and environment objects. Require the NDK only for effective NativeAOT, requested stripping, and checked builds.\n\nFail requested stripping on missing tools or failed commands, preserve native inputs, and track intermediate copies across packaging, incremental flag toggles, and Clean. Keep shared CoreCLR linking, DSO wrapping, and bundled tool distribution unchanged.\n\nPart of #12940.

Co-authored-by: Copilot App <[email protected]>
Copilot AI balanced review requested due to automatic review settings October 1, 2026 07:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The net11-only task migrations cannot execute correctly under Visual Studio’s Full MSBuild host.

Review effort: Balanced
Findings: 3 High severity

Open (3)
What changed in this PR

Routes NativeAOT linking and optional native-library stripping through the official Android NDK.

Changes:

  • Adds NDK resolution and native-tool validation.
  • Migrates NativeAOT linker tasks to the modern task assembly.
  • Adds stripping, cleanup, incremental-build coverage, diagnostics, and documentation.
File Description
Xamarin.Android.Common.targets Integrates NDK resolution and stripped outputs.
ProjectExtensions.cs Stops globally bypassing NDK resolution.
NativeAotBuildTests.cs Expands NativeAOT and stripping integration coverage.
AndroidDependenciesTests.cs Tests effective-runtime NDK dependencies.
Old LinkNativeAotSharedLibrary.cs Removes legacy linker task.
CollectNativeFilesForArchive.cs Uses NDK stripping with failure cleanup.
Microsoft.Android.Sdk.NativeAOT.targets Routes NativeAOT through NDK tools.
TaskItemExtensions.cs Adds Boolean metadata handling.
AndroidNdkTools.cs Adds NDK toolchain discovery.
SetIlcToolchainPathTests.cs Tests PATH setup.
ResolveAndroidNdkTests.cs Tests NDK resolution failures and outputs.
LinkNativeAotSharedLibraryTests.cs Tests linking, ordering, and cleanup.
SetIlcToolchainPath.cs Moves NDK PATH configuration.
ResolveAndroidNdk.cs Adds conditional NDK resolution.
New LinkNativeAotSharedLibrary.cs Implements asynchronous NDK linking.
Microsoft.Android.Build.Tasks.csproj Includes shared metadata definitions.
TOC.yml Links diagnostic documentation.
xa5105.md Documents missing NDK utilities.
xa5104.md Documents missing NDK installation.
xa5101.md Documents incomplete toolchains.
xa3008.md Updates debug-processing failure guidance.
xa3007.md Documents native-link failures.
xa0142.md Documents stripping command failures.
messages/​index.md Links updated diagnostics.
build-properties.md Documents NDK requirements and stripping.

Comment thread src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
simonrozsival and others added 10 commits October 1, 2026 21:33
Include main through c35205f, including the merged trimmable-typemap legacy scanner fix from #12976. Preserve the standalone NDK routing slice and its generated native objects.

Co-authored-by: Copilot App <[email protected]>
Windows NativeAOT builds succeed but the NDK sysroot assertion compares a backslash-only expected path against a valid mixed-separator linker response. Normalize both comparison operands without changing the required NDK toolchain roots, generated objects, or product linker behavior.

Co-authored-by: Copilot App <[email protected]>
Select the modern .NET runtime on resolver and linker task invocations, without adding task-host attributes to shipped UsingTask declarations.

Replace SetIlcToolchainPath's process-wide PATH mutation with canonical NDK compiler, archive, and objcopy paths and an escaped per-ILC Exec environment. Preserve existing environment settings and keep the MSBuild process's PATH unchanged.

Add actual-MSBuild target, environment, and failure-cleanup regressions, with Windows Full-MSBuild counterparts when Visual Studio 2026 is available. Preserve NativeAOT generated objects and ARM EHABI handling.

Co-authored-by: Copilot App <[email protected]>
Remove duplicated resolver smoke checks, mocked success and response-format assertions, XML-only runtime guards, and redundant ABI/configuration combinations.

Retain real three-ABI NativeAOT linking and ARM EHABI checks, native failure cleanup, missing tools, scoped ILC and Full-MSBuild execution, strip input preservation and incremental Clean behavior, and effective-runtime NDK requirements. Product code remains unchanged.

Co-authored-by: Copilot App <[email protected]>
Remove the synthetic MSBuild runtime fixture and the task-level resolver and mocked linker suites. Drop their test-project metadata and unused linker mocking hooks.

Keep the real NativeAOT, strip packaging, and effective-runtime dependency regressions. Replace the runtime fixture with a compact Windows Full-MSBuild test that builds and packages actual CoreCLR and NativeAOT applications using the existing project tools.

Co-authored-by: Copilot App <[email protected]>
Merge main through 7ef934d.

Retain the shared metadata helper and strict NDK stripping behavior while adopting main's removal of obsolete assembly-store cleanup. Preserve the real feature tests and previous test-scaffolding cleanup.

Co-authored-by: Copilot App <[email protected]>
Keep only the new stripping and failed-strip behavioral regressions in NativeAotBuildTests. Reuse the existing three-ABI NativeAOT and ARM EHABI coverage.

Remove the custom Full-MSBuild launcher, duplicate missing-NDK case, and task-log, response-path, FileWrites, and timestamp implementation assertions. Preserve packaged ELF/export checks, original input immutability, incremental strip toggles, and Clean behavior.

Co-authored-by: Copilot App <[email protected]>
Android links the NativeAOT object directly and already handles required stripping, debug extraction, and GNU debug links using the resolved NDK tools.

Disable ILC's unused stripping phase in all configurations. Its Windows setup probe passes an absolute llvm-objcopy path to where, which rejects the path as an invalid pattern and fails Release builds before native compilation.

Exercise the existing three-ABI build test with DebugSymbols=false. Keep NDK tool validation and Android's final stripping behavior unchanged.

Co-authored-by: Copilot App <[email protected]>
Recognize wrap.sh by its effective archive filename as well as its physical input path. A differently named script linked as wrap.sh must not be passed to llvm-strip.

Extend the existing APK and AAB stripping feature cases to verify that linked wrapper scripts are packaged unchanged. Preserve strict failures for invalid native libraries and the existing incremental and input-immutability checks.

Co-authored-by: Copilot App <[email protected]>
Merge main through 352d8ba.

Adopt the Java NativeAOT bootstrap and removal of generated LLVM bootstrap objects while preserving official NDK tool routing, the Windows stripping-probe fix, and linked wrapper scripts. Keep upstream crypto retention and incremental bootstrap coverage alongside the existing ARM EHABI checks.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival

Copy link
Copy Markdown
Member Author

@dalexsoto review

@dalexsoto dalexsoto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The complete 22-file, actual-main NDK routing change looks sound. NET task-host selection and explicit ILC child tool/environment configuration resolve the prior Full-MSBuild and process-wide PATH concerns. Strip-copy/error handling, linker/debug cleanup, packaging inputs, incremental invalidation, FileWrites and Clean remain connected. No blocking issue remains within the stated standalone scope.

@simonrozsival
simonrozsival enabled auto-merge (squash) October 6, 2026 08:33
@simonrozsival
simonrozsival merged commit aca1723 into main Oct 6, 2026
44 checks passed
@simonrozsival
simonrozsival deleted the simonrozsival-official-ndk-tool-routing branch October 6, 2026 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants