From ea4fb95dc9e234d35a7a94f6cdc37cb5103c35ed Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 11 Jan 2019 13:37:08 +0100 Subject: Support clang-based run-make tests in rustbuild. --- src/bootstrap/test.rs | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 2edc78ebaa9..ff66c75dc8c 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1106,13 +1106,13 @@ impl Step for Compiletest { }).to_string() }) }; - let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") { + let (lldb_exe, clang_exe) = + if builder.config.lldb_enabled && !target.contains("emscripten") { // Test against the lldb that was just built. - builder.llvm_out(target) - .join("bin") - .join("lldb") + (builder.llvm_out(target).join("bin").join("lldb"), + builder.llvm_out(target).join("bin").join("clang")) } else { - PathBuf::from("lldb") + (PathBuf::from("lldb"), PathBuf::from("clang")) }; let lldb_version = Command::new(&lldb_exe) .arg("--version") @@ -1127,6 +1127,31 @@ impl Step for Compiletest { } } + let clang_version = Command::new(&clang_exe) + .arg("--version") + .output() + .map(|output| { String::from_utf8_lossy(&output.stdout).to_string() }) + .ok(); + if let Some(ref vers) = clang_version { + cmd.arg("--clang-version").arg(vers); + } + + if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") { + match &var.to_string_lossy()[..] { + "1" | "yes" | "on" => { + cmd.arg("--force-clang-based-tests"); + } + "0" | "no" | "off" => { + // Nothing to do. + } + other => { + // Let's make sure typos don't get unnoticed + panic!("Unrecognized option '{}' set in \ + RUSTBUILD_FORCE_CLANG_BASED_TESTS", other); + } + } + } + // Get paths from cmd args let paths = match &builder.config.cmd { Subcommand::Test { ref paths, .. } => &paths[..], -- cgit 1.4.1-3-g733a5 From b38125c3bba8c6137bf47365c2009b647766059c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 15 Jan 2019 18:07:12 +0100 Subject: compiletest: Simplify handling of Clang-based tests. --- src/bootstrap/test.rs | 25 +++--- .../cross-lang-lto-clang/Makefile | 6 +- src/tools/compiletest/src/common.rs | 9 +-- src/tools/compiletest/src/header.rs | 2 +- src/tools/compiletest/src/main.rs | 89 ++-------------------- src/tools/compiletest/src/runtest.rs | 4 + 6 files changed, 26 insertions(+), 109 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index ff66c75dc8c..c9160aca917 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1106,13 +1106,11 @@ impl Step for Compiletest { }).to_string() }) }; - let (lldb_exe, clang_exe) = - if builder.config.lldb_enabled && !target.contains("emscripten") { + let lldb_exe = if builder.config.lldb_enabled && !target.contains("emscripten") { // Test against the lldb that was just built. - (builder.llvm_out(target).join("bin").join("lldb"), - builder.llvm_out(target).join("bin").join("clang")) + builder.llvm_out(target).join("bin").join("lldb") } else { - (PathBuf::from("lldb"), PathBuf::from("clang")) + PathBuf::from("lldb") }; let lldb_version = Command::new(&lldb_exe) .arg("--version") @@ -1127,19 +1125,14 @@ impl Step for Compiletest { } } - let clang_version = Command::new(&clang_exe) - .arg("--version") - .output() - .map(|output| { String::from_utf8_lossy(&output.stdout).to_string() }) - .ok(); - if let Some(ref vers) = clang_version { - cmd.arg("--clang-version").arg(vers); - } - if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") { - match &var.to_string_lossy()[..] { + match &var.to_string_lossy().to_lowercase()[..] { "1" | "yes" | "on" => { - cmd.arg("--force-clang-based-tests"); + assert!(builder.config.lldb_enabled, + "RUSTBUILD_FORCE_CLANG_BASED_TESTS needs Clang/LLDB to \ + be built."); + let clang_exe = builder.llvm_out(target).join("bin").join("clang"); + cmd.arg("--run-clang-based-tests-with").arg(clang_exe); } "0" | "no" | "off" => { // Nothing to do. diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile index 1e5df8f8812..cf687070bc2 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile @@ -9,7 +9,7 @@ all: cpp-executable rust-executable cpp-executable: $(RUSTC) -Zcross-lang-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs - clang -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3 + $(CLANG) -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3 # Make sure we don't find a call instruction to the function we expect to # always be inlined. llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -v -e "call.*rust_always_inlined" @@ -18,8 +18,8 @@ cpp-executable: llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -e "call.*rust_never_inlined" rust-executable: - clang ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 + $(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) - $(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=clang -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain + $(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined" llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined" diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index d034630a4df..f6f8ef1dff4 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -144,9 +144,9 @@ pub struct Config { /// (or, alternatively, to silently run them like regular run-pass tests). pub force_valgrind: bool, - /// Whether to fail if we don't have a clang version available that matches - /// rustc's LLVM version. - pub force_clang_based_tests: bool, + /// The path to the Clang executable to run Clang-based tests with. If + /// `None` then these tests will be ignored. + pub run_clang_based_tests_with: Option, /// The directory containing the tests to run pub src_base: PathBuf, @@ -209,9 +209,6 @@ pub struct Config { /// Is LLVM a system LLVM pub system_llvm: bool, - /// The version of Clang available to run-make tests (if any). - pub clang_version: Option, - /// Path to the android tools pub android_cross_path: PathBuf, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 0d664d4852b..6a00bd3c426 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -112,7 +112,7 @@ impl EarlyProps { props.ignore = Ignore::Ignore; } - if !config.force_clang_based_tests && + if config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln) { props.ignore = Ignore::Ignore; } diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index bf6ea2a0403..682cce663a1 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -50,32 +50,12 @@ pub mod util; fn main() { env_logger::init(); - let mut config = parse_config(env::args().collect()); + let config = parse_config(env::args().collect()); if config.valgrind_path.is_none() && config.force_valgrind { panic!("Can't find Valgrind to run Valgrind tests"); } - // Some run-make tests need a version of Clang available that matches - // rustc's LLVM version. Since this isn't always the case, these tests are - // opt-in. - let clang_based_tests_possible = check_clang_based_tests_possible(&config); - match (clang_based_tests_possible, config.force_clang_based_tests) { - (Ok(_), true) | - (Err(_), false) => { - // Nothing to do - } - (Ok(_), false) => { - // If a valid clang version is available, run the tests even if - // they are not forced. - config.force_clang_based_tests = true; - } - (Err(msg), true) => { - // Tests are forced but we don't have a valid version of Clang. - panic!("{}", msg) - } - } - log_config(&config); run_tests(&config); } @@ -128,10 +108,11 @@ pub fn parse_config(args: Vec) -> Config { "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind", ) - .optflag( + .optopt( "", - "force-clang-based-tests", - "fail if Clang-based run-make tests can't be run for some reason", + "run-clang-based-tests-with", + "path to Clang executable", + "PATH", ) .optopt( "", @@ -214,12 +195,6 @@ pub fn parse_config(args: Vec) -> Config { "VERSION STRING", ) .optflag("", "system-llvm", "is LLVM the system LLVM") - .optopt( - "", - "clang-version", - "the version of Clang available to run-make tests", - "VERSION STRING", - ) .optopt( "", "android-cross-path", @@ -329,7 +304,7 @@ pub fn parse_config(args: Vec) -> Config { docck_python: matches.opt_str("docck-python").unwrap(), valgrind_path: matches.opt_str("valgrind-path"), force_valgrind: matches.opt_present("force-valgrind"), - force_clang_based_tests: matches.opt_present("force-clang-based-tests"), + run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"), llvm_filecheck: matches.opt_str("llvm-filecheck").map(|s| PathBuf::from(&s)), src_base, build_base: opt_path(matches, "build-base"), @@ -355,7 +330,6 @@ pub fn parse_config(args: Vec) -> Config { lldb_native_rust, llvm_version: matches.opt_str("llvm-version"), system_llvm: matches.opt_present("system-llvm"), - clang_version: matches.opt_str("clang-version"), android_cross_path: android_cross_path, adb_path: opt_str2(matches.opt_str("adb-path")), adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")), @@ -1064,54 +1038,3 @@ fn test_extract_gdb_version() { 7012050: "GNU gdb (GDB) 7.12.50.20161027-git", } } - - -fn check_clang_based_tests_possible(config: &Config) -> Result<(), String> { - - let llvm_version = if let Some(llvm_version) = config.llvm_version.as_ref() { - llvm_version - } else { - return Err(format!("Running `compiletest` with `--force-clang-based-tests` \ - requires `--llvm-version` to be specified.")); - }; - - let clang_major_version = if let Some(ref version_string) = config.clang_version { - major_version_from_clang_version_string(version_string)? - } else { - return Err(format!("Clang is required for running tests \ - (because of --force-clang-based-tests) \ - but it does not seem to be available.")); - }; - - let rustc_llvm_major_version = major_version_from_llvm_version_string(&llvm_version)?; - - return if clang_major_version != rustc_llvm_major_version { - Err(format!("`--force-clang-based-tests` needs the major version of Clang \ - and rustc's LLVM to be the same. Clang version is: {}, \ - Rustc LLVM is: {}", - config.clang_version.clone().unwrap(), - llvm_version)) - } else { - Ok(()) - }; - - fn major_version_from_clang_version_string(clang_version: &str) -> Result<&str, String> { - let re = regex::Regex::new(r"clang version (\d)\.\d").unwrap(); - if let Some(captures) = re.captures(clang_version) { - Ok(captures.get(1).unwrap().as_str()) - } else { - Err(format!("Failed to parse major version from Clang version \ - string '{}'.", clang_version)) - } - } - - fn major_version_from_llvm_version_string(llvm_version: &str) -> Result<&str, String> { - let re = regex::Regex::new(r"(\d)\.\d").unwrap(); - if let Some(captures) = re.captures(llvm_version) { - Ok(captures.get(1).unwrap().as_str()) - } else { - Err(format!("Failed to parse major version from LLVM version \ - string '{}'.", llvm_version)) - } - } -} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 400c205d44b..f0050f2adb9 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2587,6 +2587,10 @@ impl<'test> TestCx<'test> { cmd.env("RUSTC_LINKER", linker); } + if let Some(ref clang) = self.config.run_clang_based_tests_with { + cmd.env("CLANG", clang); + } + // We don't want RUSTFLAGS set from the outside to interfere with // compiler flags set in the test cases: cmd.env_remove("RUSTFLAGS"); -- cgit 1.4.1-3-g733a5 From 9c29517af9cc44683fabcdf8c4b9b9c650e33ca6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 25 Jan 2019 12:34:59 +0100 Subject: bootstrap: Make LLD available to run-make tests. --- src/bootstrap/tool.rs | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 9f6db73e6f7..cd3afc59e56 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -1,6 +1,5 @@ use std::fs; use std::env; -use std::iter; use std::path::PathBuf; use std::process::{Command, exit}; use std::collections::HashSet; @@ -666,19 +665,33 @@ impl<'a> Builder<'a> { // Add the llvm/bin directory to PATH since it contains lots of // useful, platform-independent tools - if tool.uses_llvm_tools() { + if tool.uses_llvm_tools() && !self.config.dry_run { + let mut additional_paths = vec![]; + if let Some(llvm_bin_path) = self.llvm_bin_path() { - if host.contains("windows") { - // On Windows, PATH and the dynamic library path are the same, - // so we just add the LLVM bin path to lib_path - lib_paths.push(llvm_bin_path); - } else { - let old_path = env::var_os("PATH").unwrap_or_default(); - let new_path = env::join_paths(iter::once(llvm_bin_path) - .chain(env::split_paths(&old_path))) - .expect("Could not add LLVM bin path to PATH"); - cmd.env("PATH", new_path); - } + additional_paths.push(llvm_bin_path); + } + + // If LLD is available, add that too. + if self.config.lld_enabled { + let lld_install_root = self.ensure(native::Lld { + target: self.config.build, + }); + + let lld_bin_path = lld_install_root.join("bin"); + additional_paths.push(lld_bin_path); + } + + if host.contains("windows") { + // On Windows, PATH and the dynamic library path are the same, + // so we just add the LLVM bin path to lib_path + lib_paths.extend(additional_paths); + } else { + let old_path = env::var_os("PATH").unwrap_or_default(); + let new_path = env::join_paths(additional_paths.into_iter() + .chain(env::split_paths(&old_path))) + .expect("Could not add LLVM bin path to PATH"); + cmd.env("PATH", new_path); } } @@ -686,7 +699,7 @@ impl<'a> Builder<'a> { } fn llvm_bin_path(&self) -> Option { - if self.config.llvm_enabled && !self.config.dry_run { + if self.config.llvm_enabled { let llvm_config = self.ensure(native::Llvm { target: self.config.build, emscripten: false, -- cgit 1.4.1-3-g733a5 From dc20c8cc25a6d1bc9baaa4cc3a879a9c0f9f6657 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 30 Jan 2019 13:27:12 +0100 Subject: bootstrap: Expose LLVM_USE_LINKER cmake option to config.toml. --- config.toml.example | 4 ++++ src/bootstrap/config.rs | 3 +++ src/bootstrap/native.rs | 4 ++++ 3 files changed, 11 insertions(+) (limited to 'src/bootstrap') diff --git a/config.toml.example b/config.toml.example index 23943d34b7c..548aa691633 100644 --- a/config.toml.example +++ b/config.toml.example @@ -96,6 +96,10 @@ # that your host compiler ships with libc++. #use-libcxx = true +# The value specified here will be passed as `-DLLVM_USE_LINKER` to CMake. +#use-linker = "lld" + + # ============================================================================= # General build configuration options # ============================================================================= diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9421817ae6d..2871db2c9a2 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -77,6 +77,7 @@ pub struct Config { pub llvm_experimental_targets: String, pub llvm_link_jobs: Option, pub llvm_version_suffix: Option, + pub llvm_use_linker: Option, pub lld_enabled: bool, pub lldb_enabled: bool, @@ -255,6 +256,7 @@ struct Llvm { version_suffix: Option, clang_cl: Option, use_libcxx: Option, + use_linker: Option, } #[derive(Deserialize, Default, Clone)] @@ -517,6 +519,7 @@ impl Config { config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); set(&mut config.llvm_use_libcxx, llvm.use_libcxx); + config.llvm_use_linker = llvm.use_linker.clone(); } if let Some(ref rust) = toml.rust { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index cb9c86df550..e4325179f63 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -231,6 +231,10 @@ impl Step for Llvm { cfg.define("LLVM_VERSION_SUFFIX", suffix); } + if let Some(ref linker) = builder.config.llvm_use_linker { + cfg.define("LLVM_USE_LINKER", linker); + } + if let Some(ref python) = builder.config.python { cfg.define("PYTHON_EXECUTABLE", python); } -- cgit 1.4.1-3-g733a5