Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve android-ndk property interface #116998

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
# =============================================================================
Expand Down Expand Up @@ -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 = <none> (path)

# Build the sanitizer runtimes for this target.
# This option will override the same option under [build] section.
#sanitizers = build.sanitizers (bool)
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/bootstrap_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"))

Expand Down
15 changes: 1 addition & 14 deletions src/bootstrap/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,7 @@ def v(*args):
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",
Expand Down
17 changes: 5 additions & 12 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use std::str::FromStr;
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;
Expand Down Expand Up @@ -142,6 +141,7 @@ pub struct Config {
pub color: Color,
pub patch_binaries_for_nix: Option<bool>,
pub stage0_metadata: Stage0Metadata,
pub android_ndk: Option<PathBuf>,

pub stdout_is_tty: bool,
pub stderr_is_tty: bool,
Expand Down Expand Up @@ -521,7 +521,6 @@ pub struct Target {
pub ranlib: Option<PathBuf>,
pub default_linker: Option<PathBuf>,
pub linker: Option<PathBuf>,
pub ndk: Option<PathBuf>,
pub sanitizers: Option<bool>,
pub profiler: Option<StringOrBool>,
pub rpath: Option<bool>,
Expand Down Expand Up @@ -799,6 +798,7 @@ define_config! {
patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
// NOTE: only parsed by bootstrap.py, `--feature build-metrics` enables metrics unconditionally
metrics: Option<bool> = "metrics",
android_ndk: Option<PathBuf> = "android-ndk",
}
}

Expand Down Expand Up @@ -1039,7 +1039,6 @@ define_config! {
llvm_has_rust_patches: Option<bool> = "llvm-has-rust-patches",
llvm_filecheck: Option<String> = "llvm-filecheck",
llvm_libunwind: Option<String> = "llvm-libunwind",
android_ndk: Option<String> = "android-ndk",
sanitizers: Option<bool> = "sanitizers",
profiler: Option<StringOrBool> = "profiler",
rpath: Option<bool> = "rpath",
Expand Down Expand Up @@ -1320,6 +1319,7 @@ impl Config {
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);
Expand Down Expand Up @@ -1600,18 +1600,11 @@ impl Config {
.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);
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
///
/// 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))
Expand Down
81 changes: 48 additions & 33 deletions src/bootstrap/src/utils/cc_detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::path::{Path, PathBuf};
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};

Expand Down Expand Up @@ -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();
Expand All @@ -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()
Expand Down Expand Up @@ -161,68 +162,70 @@ 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<PathBuf> {
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.
t if t.contains("openbsd") => {
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,
}
}

Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/arm-android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 1 addition & 6 deletions src/ci/docker/host-x86_64/dist-android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading