Skip to content

Commit 4a78d87

Browse files
committed
Update Android compiler detection for NDK r25
This commit updates the compiler detection logic for the Android platform to work with NDK r25. This code is largely identical to the corresponding code in rustc/src/bootstrap/cc_detect.rs.
1 parent 53fb72c commit 4a78d87

File tree

1 file changed

+28
-49
lines changed

1 file changed

+28
-49
lines changed

Diff for: src/lib.rs

+28-49
Original file line numberDiff line numberDiff line change
@@ -2286,7 +2286,7 @@ impl Build {
22862286
} else if target.contains("apple-watchos") {
22872287
clang.to_string()
22882288
} else if target.contains("android") {
2289-
autodetect_android_compiler(&target, &host, gnu, clang)
2289+
autodetect_android_compiler(&target, &host, clang)
22902290
} else if target.contains("cloudabi") {
22912291
format!("{}-{}", target, traditional)
22922292
} else if target == "wasm32-wasi"
@@ -3221,16 +3221,6 @@ fn command_add_output_file(
32213221
}
32223222
}
32233223

3224-
// Use by default minimum available API level
3225-
// See note about naming here
3226-
// https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/docs/BuildSystemMaintainers.md#Clang
3227-
static NEW_STANDALONE_ANDROID_COMPILERS: [&str; 4] = [
3228-
"aarch64-linux-android21-clang",
3229-
"armv7a-linux-androideabi16-clang",
3230-
"i686-linux-android16-clang",
3231-
"x86_64-linux-android21-clang",
3232-
];
3233-
32343224
// New "standalone" C/C++ cross-compiler executables from recent Android NDK
32353225
// are just shell scripts that call main clang binary (from Android NDK) with
32363226
// proper `--target` argument.
@@ -3253,7 +3243,7 @@ fn android_clang_compiler_uses_target_arg_internally(clang_path: &Path) -> bool
32533243

32543244
#[test]
32553245
fn test_android_clang_compiler_uses_target_arg_internally() {
3256-
for version in 16..21 {
3246+
for version in 16..33 {
32573247
assert!(android_clang_compiler_uses_target_arg_internally(
32583248
&PathBuf::from(format!("armv7a-linux-androideabi{}-clang", version))
32593249
));
@@ -3269,50 +3259,39 @@ fn test_android_clang_compiler_uses_target_arg_internally() {
32693259
));
32703260
}
32713261

3272-
fn autodetect_android_compiler(target: &str, host: &str, gnu: &str, clang: &str) -> String {
3273-
let new_clang_key = match target {
3274-
"aarch64-linux-android" => Some("aarch64"),
3275-
"armv7-linux-androideabi" => Some("armv7a"),
3276-
"i686-linux-android" => Some("i686"),
3277-
"x86_64-linux-android" => Some("x86_64"),
3278-
_ => None,
3262+
fn autodetect_android_compiler(target: &str, host: &str, clang: &str) -> String {
3263+
let mut triple_iter = target.split("-");
3264+
let triple_translated = if let Some(arch) = triple_iter.next() {
3265+
let arch_new = match arch {
3266+
"arm" | "armv7" | "armv7neon" | "thumbv7" | "thumbv7neon" => "armv7a",
3267+
other => other,
3268+
};
3269+
std::iter::once(arch_new)
3270+
.chain(triple_iter)
3271+
.collect::<Vec<&str>>()
3272+
.join("-")
3273+
} else {
3274+
target.to_string()
32793275
};
32803276

3281-
let new_clang = new_clang_key
3282-
.map(|key| {
3283-
NEW_STANDALONE_ANDROID_COMPILERS
3284-
.iter()
3285-
.find(|x| x.starts_with(key))
3286-
})
3287-
.unwrap_or(None);
3288-
3289-
if let Some(new_clang) = new_clang {
3290-
if Command::new(new_clang).output().is_ok() {
3291-
return (*new_clang).into();
3292-
}
3293-
}
3294-
3295-
let target = target
3296-
.replace("armv7neon", "arm")
3297-
.replace("armv7", "arm")
3298-
.replace("thumbv7neon", "arm")
3299-
.replace("thumbv7", "arm");
3300-
let gnu_compiler = format!("{}-{}", target, gnu);
3301-
let clang_compiler = format!("{}-{}", target, clang);
3277+
// API 19 is the earliest API level supported by NDK r25b but AArch64 and x86_64 support
3278+
// begins at API level 21.
3279+
let api_level = if target.contains("aarch64") || target.contains("x86_64") {
3280+
"21"
3281+
} else {
3282+
"19"
3283+
};
3284+
let compiler = format!("{}{}-{}", triple_translated, api_level, clang);
33023285

33033286
// On Windows, the Android clang compiler is provided as a `.cmd` file instead
33043287
// of a `.exe` file. `std::process::Command` won't run `.cmd` files unless the
33053288
// `.cmd` is explicitly appended to the command name, so we do that here.
3306-
let clang_compiler_cmd = format!("{}-{}.cmd", target, clang);
3307-
3308-
// Check if gnu compiler is present
3309-
// if not, use clang
3310-
if Command::new(&gnu_compiler).output().is_ok() {
3311-
gnu_compiler
3312-
} else if host.contains("windows") && Command::new(&clang_compiler_cmd).output().is_ok() {
3313-
clang_compiler_cmd
3289+
let windows_compiler_cmd = format!("{}.cmd", compiler);
3290+
3291+
if host.contains("windows") && Command::new(&windows_compiler_cmd).output().is_ok() {
3292+
windows_compiler_cmd
33143293
} else {
3315-
clang_compiler
3294+
compiler
33163295
}
33173296
}
33183297

0 commit comments

Comments
 (0)