Repository navigation
[xabt] Route NativeAOT linking and native stripping through NDK - #12970
Merged
Merged
Conversation
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]>
Contributor
There was a problem hiding this comment.
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
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. |
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]>
Member
Author
|
@dalexsoto review |
dalexsoto
approved these changes
Oct 6, 2026
dalexsoto
left a comment
Member
There was a problem hiding this comment.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

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. NativeAOTalways 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)=truethrough NDKllvm-stripforDebug/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, andClean.
Keep the remaining shared
NativeLinkercallers, DSO wrapperconfiguration/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:
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.