From 523ffb1705811db344437b8c04b9c383f09c7695 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 22 Nov 2021 23:57:56 +0100 Subject: [PATCH] ndk-build,cargo-apk: Default `target_sdk_version` to 29 or lower As discussed in [197] setting `target_sdk_version` to the "arbitrary" highest available SDK version is nonsense. This target version (unlike `min_sdk_version` which defines the least set of symbols that should be available) has real impact on the runtime of an application, in particular the compatibility or stringency of rules Android applies to your application. Certain APIs may not work at all or be heavily restricted on newer target versions because they are deemed too dangerous, and Android expects the user has tested their app against these limitations and is communicating this by setting `target_sdk_version` to that particular value. Hence this shouldn't change purely based on the environment, even for the default. To retain some backwards compatibility with previous `cargo-apk` we set this to level 29 which is the least [required by Google Play] today, and approximately what users with recent SDKs will be targeting already. However, care has to be taken around ie. scoped storage, hence this is considered a **Breaking** change. [197]: https://github.com/rust-windowing/android-ndk-rs/pull/197#issuecomment-970283527 [required by Google Play]: https://developer.android.com/distribute/best-practices/develop/target-sdk --- cargo-apk/CHANGELOG.md | 4 ++++ cargo-apk/README.md | 2 +- cargo-apk/src/apk.rs | 6 +++--- ndk-build/CHANGELOG.md | 4 ++++ ndk-build/src/apk.rs | 2 +- ndk-build/src/ndk.rs | 10 +++++++++- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/cargo-apk/CHANGELOG.md b/cargo-apk/CHANGELOG.md index 221f851e..4b0c7f4f 100644 --- a/cargo-apk/CHANGELOG.md +++ b/cargo-apk/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +- **Breaking**: Default `target_sdk_version` to `29` or lower for more consistent + interaction with Android backwards compatibility and tighter rules: + https://developer.android.com/distribute/best-practices/develop/target-sdk + # 0.8.2 (2021-11-22) - Fixed the library name in case of multiple build artifacts in the Android manifest. diff --git a/cargo-apk/README.md b/cargo-apk/README.md index 0408eb0f..90116a39 100644 --- a/cargo-apk/README.md +++ b/cargo-apk/README.md @@ -49,7 +49,7 @@ runtime_libs = "path/to/libs_folder" # See https://developer.android.com/guide/topics/manifest/uses-sdk-element # -# Defaults to a `min_sdk_version` of 23 and `target_sdk_version` is based on the ndk's default platform. +# Defaults to a `min_sdk_version` of 23 and `target_sdk_version` of 29 (or lower if the detected NDK doesn't support this). [package.metadata.android.sdk] min_sdk_version = 16 target_sdk_version = 29 diff --git a/cargo-apk/src/apk.rs b/cargo-apk/src/apk.rs index 87af153b..092f9239 100644 --- a/cargo-apk/src/apk.rs +++ b/cargo-apk/src/apk.rs @@ -59,13 +59,13 @@ impl<'a> ApkBuilder<'a> { .android_manifest .sdk .target_sdk_version - .get_or_insert(ndk.default_platform()); + .get_or_insert_with(|| ndk.default_target_platform()); manifest .android_manifest .application .debuggable - .get_or_insert(*cmd.profile() == Profile::Dev); + .get_or_insert_with(|| *cmd.profile() == Profile::Dev); Ok(Self { cmd, @@ -238,7 +238,7 @@ impl<'a> ApkBuilder<'a> { .android_manifest .sdk .target_sdk_version - .unwrap_or_else(|| ndk.default_platform()); + .unwrap_or_else(|| ndk.default_target_platform()); for target in &self.build_targets { let mut cargo = cargo_ndk(&ndk, *target, target_sdk_version)?; cargo.args(self.cmd.args()); diff --git a/ndk-build/CHANGELOG.md b/ndk-build/CHANGELOG.md index ed4b1e29..ea1754a8 100644 --- a/ndk-build/CHANGELOG.md +++ b/ndk-build/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +- **Breaking**: Default `target_sdk_version` to `29` or lower for more consistent + interaction with Android backwards compatibility and tighter rules: + https://developer.android.com/distribute/best-practices/develop/target-sdk + # 0.4.3 (2021-11-22) - Provide NDK `build_tag` version from `source.properties` in the NDK root. diff --git a/ndk-build/src/apk.rs b/ndk-build/src/apk.rs index 43548d0d..b6e6b165 100644 --- a/ndk-build/src/apk.rs +++ b/ndk-build/src/apk.rs @@ -40,7 +40,7 @@ impl ApkConfig { .manifest .sdk .target_sdk_version - .unwrap_or_else(|| self.ndk.default_platform()); + .unwrap_or_else(|| self.ndk.default_target_platform()); let mut aapt = self.build_tool(bin!("aapt"))?; aapt.arg("package") .arg("-f") diff --git a/ndk-build/src/ndk.rs b/ndk-build/src/ndk.rs index a53c40e8..1e1ee115 100644 --- a/ndk-build/src/ndk.rs +++ b/ndk-build/src/ndk.rs @@ -159,10 +159,18 @@ impl Ndk { Ok(Command::new(dunce::canonicalize(path)?)) } - pub fn default_platform(&self) -> u32 { + pub fn highest_supported_platform(&self) -> u32 { self.platforms().iter().max().cloned().unwrap() } + /// Returns platform `29` as currently [required by Google Play], or lower + /// when the detected SDK does not support it yet. + /// + /// [required by Google Play]: https://developer.android.com/distribute/best-practices/develop/target-sdk + pub fn default_target_platform(&self) -> u32 { + self.highest_supported_platform().min(29) + } + pub fn platform_dir(&self, platform: u32) -> Result { let dir = self .sdk_path