diff --git a/config.example.toml b/config.example.toml index 4f44121410e..66fa91d4bad 100644 --- a/config.example.toml +++ b/config.example.toml @@ -30,7 +30,7 @@ # # If `change-id` does not match the version that is currently running, # `x.py` will prompt you to update it and check the related PR for more details. -change-id = 115898 +change-id = 116998 # ============================================================================= # Tweaking how LLVM is compiled @@ -377,6 +377,9 @@ change-id = 115898 # this is not intended to be used during local development. #metrics = false +# Specify the location of the Android NDK. Used when targeting Android. +#android-ndk = "/path/to/android-ndk-r25b" + # ============================================================================= # General install configuration options # ============================================================================= @@ -756,12 +759,6 @@ change-id = 115898 # it must link to `libgcc_eh.a` to get a working output, and this option have no effect. #llvm-libunwind = 'no' if Linux, 'in-tree' if Fuchsia -# If this target is for Android, this option will be required to specify where -# 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. -#android-ndk = (path) - # Build the sanitizer runtimes for this target. # This option will override the same option under [build] section. #sanitizers = build.sanitizers (bool) diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index fefd6b18739..7f16cac7890 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -103,7 +103,7 @@ class GenerateAndParseConfig(unittest.TestCase): """Test that we can serialize and deserialize a config.toml file""" def test_no_args(self): build = serialize_and_parse([]) - self.assertEqual(build.get_toml("change-id"), '115898') + self.assertEqual(build.get_toml("change-id"), '116998') self.assertEqual(build.get_toml("profile"), 'dist') self.assertIsNone(build.get_toml("llvm.download-ci-llvm")) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index f469dbea6db..bfef3e67240 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -97,20 +97,7 @@ v("llvm-root", None, "set LLVM root") v("llvm-config", None, "set path to llvm-config") v("llvm-filecheck", None, "set path to LLVM's FileCheck utility") v("python", "build.python", "set path to python") -v("android-cross-path", "target.arm-linux-androideabi.android-ndk", - "Android NDK standalone path (deprecated)") -v("i686-linux-android-ndk", "target.i686-linux-android.android-ndk", - "i686-linux-android NDK standalone path") -v("arm-linux-androideabi-ndk", "target.arm-linux-androideabi.android-ndk", - "arm-linux-androideabi NDK standalone path") -v("armv7-linux-androideabi-ndk", "target.armv7-linux-androideabi.android-ndk", - "armv7-linux-androideabi NDK standalone path") -v("thumbv7neon-linux-androideabi-ndk", "target.thumbv7neon-linux-androideabi.android-ndk", - "thumbv7neon-linux-androideabi NDK standalone path") -v("aarch64-linux-android-ndk", "target.aarch64-linux-android.android-ndk", - "aarch64-linux-android NDK standalone path") -v("x86_64-linux-android-ndk", "target.x86_64-linux-android.android-ndk", - "x86_64-linux-android NDK standalone path") +v("android-ndk", "build.android-ndk", "set path to Android NDK") v("musl-root", "target.x86_64-unknown-linux-musl.musl-root", "MUSL root installation directory (deprecated)") v("musl-root-x86_64", "target.x86_64-unknown-linux-musl.musl-root", diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 7ca1bbad968..5b5334b0a55 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -21,7 +21,6 @@ use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX; use crate::core::config::flags::{Color, Flags, Warnings}; use crate::utils::cache::{Interned, INTERNER}; -use crate::utils::cc_detect::{ndk_compiler, Language}; use crate::utils::channel::{self, GitInfo}; use crate::utils::helpers::{exe, output, t}; use build_helper::exit; @@ -142,6 +141,7 @@ pub struct Config { pub color: Color, pub patch_binaries_for_nix: Option, pub stage0_metadata: Stage0Metadata, + pub android_ndk: Option, pub stdout_is_tty: bool, pub stderr_is_tty: bool, @@ -521,7 +521,6 @@ pub struct Target { pub ranlib: Option, pub default_linker: Option, pub linker: Option, - pub ndk: Option, pub sanitizers: Option, pub profiler: Option, pub rpath: Option, @@ -799,6 +798,7 @@ struct Build { patch_binaries_for_nix: Option = "patch-binaries-for-nix", // NOTE: only parsed by bootstrap.py, `--feature build-metrics` enables metrics unconditionally metrics: Option = "metrics", + android_ndk: Option = "android-ndk", } } @@ -1039,7 +1039,6 @@ struct TomlTarget { llvm_has_rust_patches: Option = "llvm-has-rust-patches", llvm_filecheck: Option = "llvm-filecheck", llvm_libunwind: Option = "llvm-libunwind", - android_ndk: Option = "android-ndk", sanitizers: Option = "sanitizers", profiler: Option = "profiler", rpath: Option = "rpath", @@ -1320,6 +1319,7 @@ fn get_table(option: &str) -> Result { config.python = build.python.map(PathBuf::from); config.reuse = build.reuse.map(PathBuf::from); config.submodules = build.submodules; + config.android_ndk = build.android_ndk; set(&mut config.low_priority, build.low_priority); set(&mut config.compiler_docs, build.compiler_docs); set(&mut config.library_docs_private_items, build.library_docs_private_items); @@ -1600,18 +1600,11 @@ fn get_table(option: &str) -> Result { .llvm_libunwind .as_ref() .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); - if let Some(ref s) = cfg.android_ndk { - target.ndk = Some(config.src.join(s)); - } if let Some(s) = cfg.no_std { target.no_std = s; } - target.cc = cfg.cc.map(PathBuf::from).or_else(|| { - target.ndk.as_ref().map(|ndk| ndk_compiler(Language::C, &triple, ndk)) - }); - target.cxx = cfg.cxx.map(PathBuf::from).or_else(|| { - target.ndk.as_ref().map(|ndk| ndk_compiler(Language::CPlusPlus, &triple, ndk)) - }); + target.cc = cfg.cc.map(PathBuf::from); + target.cxx = cfg.cxx.map(PathBuf::from); target.ar = cfg.ar.map(PathBuf::from); target.ranlib = cfg.ranlib.map(PathBuf::from); target.linker = cfg.linker.map(PathBuf::from); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 97c743074af..705c27bb922 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -78,7 +78,7 @@ /// /// If you make any major changes (such as adding new values or changing default values), please /// ensure that the associated PR ID is added to the end of this list. -pub const CONFIG_CHANGE_HISTORY: &[usize] = &[115898]; +pub const CONFIG_CHANGE_HISTORY: &[usize] = &[115898, 116998]; /// Extra --check-cfg to add when building /// (Mode restriction, config name, config values (if any)) diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index 3d3f93f7720..52b36ce75f3 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -26,7 +26,7 @@ use std::process::Command; use std::{env, iter}; -use crate::core::config::{Target, TargetSelection}; +use crate::core::config::TargetSelection; use crate::utils::helpers::output; use crate::{Build, CLang, GitRepo}; @@ -107,10 +107,11 @@ pub fn find(build: &Build) { pub fn find_target(build: &Build, target: TargetSelection) { let mut cfg = new_cc_build(build, target); let config = build.config.target_config.get(&target); - if let Some(cc) = config.and_then(|c| c.cc.as_ref()) { + if let Some(cc) = config + .and_then(|c| c.cc.clone()) + .or_else(|| default_compiler(&mut cfg, Language::C, target, build)) + { cfg.compiler(cc); - } else { - set_compiler(&mut cfg, Language::C, target, config, build); } let compiler = cfg.get_compiler(); @@ -127,12 +128,12 @@ pub fn find_target(build: &Build, target: TargetSelection) { // We'll need one anyways if the target triple is also a host triple let mut cfg = new_cc_build(build, target); cfg.cpp(true); - let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { + let cxx_configured = if let Some(cxx) = config + .and_then(|c| c.cxx.clone()) + .or_else(|| default_compiler(&mut cfg, Language::CPlusPlus, target, build)) + { cfg.compiler(cxx); true - } else if build.hosts.contains(&target) || build.build == target { - set_compiler(&mut cfg, Language::CPlusPlus, target, config, build); - true } else { // Use an auto-detected compiler (or one configured via `CXX_target_triple` env vars). cfg.try_get_compiler().is_ok() @@ -161,22 +162,21 @@ pub fn find_target(build: &Build, target: TargetSelection) { } } -fn set_compiler( +fn default_compiler( cfg: &mut cc::Build, compiler: Language, target: TargetSelection, - config: Option<&Target>, build: &Build, -) { +) -> Option { match &*target.triple { // When compiling for android we may have the NDK configured in the // config.toml in which case we look there. Otherwise the default // compiler already takes into account the triple in question. - t if t.contains("android") => { - if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) { - cfg.compiler(ndk_compiler(compiler, &*target.triple, ndk)); - } - } + t if t.contains("android") => build + .config + .android_ndk + .as_ref() + .map(|ndk| ndk_compiler(compiler, &*target.triple, ndk)), // The default gcc version from OpenBSD may be too old, try using egcc, // which is a gcc version from ports, if this is the case. @@ -184,45 +184,48 @@ fn set_compiler( let c = cfg.get_compiler(); let gnu_compiler = compiler.gcc(); if !c.path().ends_with(gnu_compiler) { - return; + return None; } let output = output(c.to_command().arg("--version")); - let i = match output.find(" 4.") { - Some(i) => i, - None => return, - }; + let i = output.find(" 4.")?; match output[i + 3..].chars().next().unwrap() { '0'..='6' => {} - _ => return, + _ => return None, } let alternative = format!("e{gnu_compiler}"); if Command::new(&alternative).output().is_ok() { - cfg.compiler(alternative); + Some(PathBuf::from(alternative)) + } else { + None } } - "mips-unknown-linux-musl" => { + "mips-unknown-linux-musl" if compiler == Language::C => { if cfg.get_compiler().path().to_str() == Some("gcc") { - cfg.compiler("mips-linux-musl-gcc"); + Some(PathBuf::from("mips-linux-musl-gcc")) + } else { + None } } - "mipsel-unknown-linux-musl" => { + "mipsel-unknown-linux-musl" if compiler == Language::C => { if cfg.get_compiler().path().to_str() == Some("gcc") { - cfg.compiler("mipsel-linux-musl-gcc"); + Some(PathBuf::from("mipsel-linux-musl-gcc")) + } else { + None } } - t if t.contains("musl") => { + t if t.contains("musl") && compiler == Language::C => { if let Some(root) = build.musl_root(target) { let guess = root.join("bin/musl-gcc"); - if guess.exists() { - cfg.compiler(guess); - } + if guess.exists() { Some(guess) } else { None } + } else { + None } } - _ => {} + _ => None, } } @@ -243,10 +246,22 @@ pub(crate) fn ndk_compiler(compiler: Language, triple: &str, ndk: &Path) -> Path let api_level = if triple.contains("aarch64") || triple.contains("x86_64") { "21" } else { "19" }; let compiler = format!("{}{}-{}", triple_translated, api_level, compiler.clang()); - ndk.join("bin").join(compiler) + let host_tag = if cfg!(target_os = "macos") { + // The NDK uses universal binaries, so this is correct even on ARM. + "darwin-x86_64" + } else if cfg!(target_os = "windows") { + "windows-x86_64" + } else { + // NDK r25b only has official releases for macOS, Windows and Linux. + // Try the Linux directory everywhere else, on the assumption that the OS has an + // emulation layer that can cope (e.g. BSDs). + "linux-x86_64" + }; + ndk.join("toolchains").join("llvm").join("prebuilt").join(host_tag).join("bin").join(compiler) } /// The target programming language for a native compiler. +#[derive(PartialEq)] pub(crate) enum Language { /// The compiler is targeting C. C, diff --git a/src/ci/docker/host-x86_64/arm-android/Dockerfile b/src/ci/docker/host-x86_64/arm-android/Dockerfile index db11700af28..abca06fb9fb 100644 --- a/src/ci/docker/host-x86_64/arm-android/Dockerfile +++ b/src/ci/docker/host-x86_64/arm-android/Dockerfile @@ -30,7 +30,7 @@ ENV PATH=$PATH:/android/sdk/platform-tools ENV TARGETS=arm-linux-androideabi -ENV RUST_CONFIGURE_ARGS --arm-linux-androideabi-ndk=/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/ +ENV RUST_CONFIGURE_ARGS --android-ndk=/android/ndk/ ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target $TARGETS diff --git a/src/ci/docker/host-x86_64/dist-android/Dockerfile b/src/ci/docker/host-x86_64/dist-android/Dockerfile index b09b6edb01a..20b72b377ca 100644 --- a/src/ci/docker/host-x86_64/dist-android/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-android/Dockerfile @@ -19,12 +19,7 @@ ENV TARGETS=$TARGETS,x86_64-linux-android ENV RUST_CONFIGURE_ARGS \ --enable-extended \ --enable-profiler \ - --arm-linux-androideabi-ndk=/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/ \ - --armv7-linux-androideabi-ndk=/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/ \ - --thumbv7neon-linux-androideabi-ndk=/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/ \ - --i686-linux-android-ndk=/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/ \ - --aarch64-linux-android-ndk=/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/ \ - --x86_64-linux-android-ndk=/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/ \ + --android-ndk=/android/ndk/ \ --disable-docs ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS