diff --git a/config.toml.example b/config.toml.example index 1f5747456e957..90805847e850d 100644 --- a/config.toml.example +++ b/config.toml.example @@ -334,6 +334,18 @@ changelog-seen = 2 # this is not intended to be used during local development. #metrics = false +# When targeting Android, specify the location of the Android NDK. This variable +# needs to be set to the location of the LLVM toolchain subdirectory within +# the NDK, found under "toolchains/llvm/prebuilt/-". +# +# This option is only compatible with Android NDK r19 or newer. If you are using +# an older NDK, you will need to create a standalone toolchain and specify the +# path via the target-specific android-ndk option. +#android-ndk = (path) + +# When targeting Android, specify the minimum API level to target. +#android-api-level = 21 + # ============================================================================= # General install configuration options # ============================================================================= @@ -700,6 +712,10 @@ changelog-seen = 2 # the NDK for the target lives. This is used to find the C compiler to link and # build native code. # See `src/bootstrap/cc_detect.rs` for details. +# +# This option is deprecated as it requires building a standalone toolchain, +# which is unnecessary with NDK r19 and newer. Instead, prefer to use the same +# option under the [build] section. #android-ndk = (path) # Build the sanitizer runtimes for this target. diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index 759a99c330c27..e01b412d96dee 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -34,7 +34,7 @@ use crate::{Build, CLang, GitRepo}; // so use some simplified logic here. First we respect the environment variable `AR`, then // try to infer the archiver path from the C compiler path. // In the future this logic should be replaced by calling into the `cc` crate. -fn cc2ar(cc: &Path, target: TargetSelection) -> Option { +fn cc2ar(cc: &Path, target: TargetSelection, build: &Build) -> Option { if let Some(ar) = env::var_os(format!("AR_{}", target.triple.replace("-", "_"))) { Some(PathBuf::from(ar)) } else if let Some(ar) = env::var_os("AR") { @@ -47,6 +47,8 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option { Some(PathBuf::from("ar")) } else if target.contains("vxworks") { Some(PathBuf::from("wr-ar")) + } else if target.contains("android") && build.config.android_ndk.is_some() { + Some(build.config.android_ndk.as_ref().unwrap().join("bin").join("llvm-ar")) } else { let parent = cc.parent().unwrap(); let file = cc.file_name().unwrap().to_str().unwrap(); @@ -108,7 +110,7 @@ pub fn find(build: &mut Build) { let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) { ar } else { - cc2ar(compiler.path(), target) + cc2ar(compiler.path(), target, build) }; build.cc.insert(target, compiler.clone()); @@ -174,6 +176,16 @@ fn set_compiler( .replace("thumbv7", "arm"); let compiler = format!("{}-{}", target, compiler.clang()); cfg.compiler(ndk.join("bin").join(compiler)); + } else if let Some(ndk) = build.config.android_ndk.as_ref() { + let target = target + .triple + .replace("armv7neon", "armv7a") + .replace("armv7", "armv7a") + .replace("thumbv7neon", "armv7a") + .replace("thumbv7", "armv7a"); + let api_level = build.config.android_api_level.unwrap_or(21); + let compiler = format!("{}{}-{}", target, api_level, compiler.clang()); + cfg.compiler(ndk.join("bin").join(compiler)); } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 8c501f637d97e..1e6a7186db3fe 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -75,6 +75,8 @@ pub struct Config { pub stage0_metadata: Stage0Metadata, /// Whether to use the `c` feature of the `compiler_builtins` crate. pub optimized_compiler_builtins: bool, + pub android_ndk: Option, + pub android_api_level: Option, pub on_fail: Option, pub stage: u32, @@ -600,6 +602,8 @@ define_config! { patch_binaries_for_nix: Option = "patch-binaries-for-nix", metrics: Option = "metrics", optimized_compiler_builtins: Option = "optimized-compiler-builtins", + android_ndk: Option = "android-ndk", + android_api_level: Option = "android-api-level", } } @@ -951,6 +955,8 @@ impl Config { config.gdb = build.gdb.map(PathBuf::from); config.python = build.python.map(PathBuf::from); config.submodules = build.submodules; + config.android_ndk = build.android_ndk; + config.android_api_level = build.android_api_level; set(&mut config.low_priority, build.low_priority); set(&mut config.compiler_docs, build.compiler_docs); set(&mut config.docs_minification, build.docs_minification);