android: Compile native code against min_sdk, not target_sdk - #245
Closed
MarijnS95 wants to merge 1 commit into
Closed
android: Compile native code against min_sdk, not target_sdk#245MarijnS95 wants to merge 1 commit into
MarijnS95 wants to merge 1 commit into
Conversation
The NDK compile level — the `<api>` suffix on `--target=<triple><api>`, i.e. `__ANDROID_API__` — gates which symbols the compiler treats as available. Setting it to `target_sdk_version` lets native code link strong references to symbols that don't exist on the oldest supported device, which then fails to load at runtime: exactly the compatibility breakage `min_sdk_version` exists to prevent. Only aapt and `android.jar` should follow `target_sdk_version`. This was never a deliberate target-over-min choice: the API level wasn't set at all until #209, and when the versioned `--target` was finally added it simply reused the pre-existing `target_sdk_version` variable that had been wired up for `android.jar`, so the target-SDK level was inherited incidentally from that earlier path. cargo-apk got this right back in 2021 — rust-mobile/ndk#197 ("cargo-apk: Use min_sdk_version to select compiler target"), pre-split from cargo-apk's own repo, per https://developer.android.com/ndk/guides/sdk-versions#minsdkversion Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What
The Android NDK compile level — the
<api>suffix on--target=<triple><api>, i.e.__ANDROID_API__— gates which symbols the compiler treats as available. xbuild currently feedstarget_sdk_versioninto it (BuildEnv::cargo_build→use_android_ndk), so with e.g. min_sdk 21 / target_sdk 34 the native.sois compiled at API 34.Compiling above
min_sdk_versionlets native code emit strong references to symbols absent on the oldest supported device, which then fails to load at runtime — the exact compatibility breakagemin_sdk_versionexists to prevent. Onlyaapt/android.jarshould tracktarget_sdk_version(unchanged here).Why it was wrong
Not a deliberate target-over-min choice: the API level wasn't set at all until #209; when the versioned
--targetwas finally added it reused the pre-existingtarget_sdk_versionvariable already wired up forandroid.jar, inheriting the target level incidentally.Prior art
cargo-apk got this right back in 2021 — rust-mobile/ndk#197 ("cargo-apk: Use
min_sdk_versionto select compiler target"), from before cargo-apk was split into its own repo — per the NDK docs.Change
use_android_ndknow takesmin_sdk_version(renamed param) andBuildEnv::cargo_buildpassesmanifest.sdk.min_sdk_versioninstead oftarget_sdk_version.android.jarselection is untouched.