diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 4f88b5854b69293b73c1eead19264e184487992a..0d387ff1e37c20f2e111b482a6da6b6c8e1ad33d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -26,7 +26,7 @@ use crate::test; use crate::tool::{self, SourceType}; use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir}; -use crate::{Build, DocTests, GitRepo, Mode}; +use crate::{Build, CLang, DocTests, GitRepo, Mode}; pub use crate::Compiler; // FIXME: replace with std::lazy after it gets stabilized and reaches beta @@ -1511,7 +1511,7 @@ pub fn cargo( let cc = ccacheify(&self.cc(target)); cargo.env(format!("CC_{}", target.triple), &cc); - let cflags = self.cflags(target, GitRepo::Rustc).join(" "); + let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" "); cargo.env(format!("CFLAGS_{}", target.triple), &cflags); if let Some(ar) = self.ar(target) { @@ -1523,9 +1523,10 @@ pub fn cargo( if let Ok(cxx) = self.cxx(target) { let cxx = ccacheify(&cxx); + let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" "); cargo .env(format!("CXX_{}", target.triple), &cxx) - .env(format!("CXXFLAGS_{}", target.triple), cflags); + .env(format!("CXXFLAGS_{}", target.triple), cxxflags); } } diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index e750c2963dddcc403282ccd892255074d93582da..8c47f625d732bc3868c5018828d9371f0626435f 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -29,7 +29,7 @@ use build_helper::output; use crate::config::{Target, TargetSelection}; -use crate::{Build, GitRepo}; +use crate::{Build, CLang, GitRepo}; // The `cc` crate doesn't provide a way to obtain a path to the detected archiver, // so use some simplified logic here. First we respect the environment variable `AR`, then @@ -109,7 +109,7 @@ pub fn find(build: &mut Build) { }; build.cc.insert(target, compiler.clone()); - let cflags = build.cflags(target, GitRepo::Rustc); + let cflags = build.cflags(target, GitRepo::Rustc, CLang::C); // If we use llvm-libunwind, we will need a C++ compiler as well for all targets // We'll need one anyways if the target triple is also a host triple @@ -142,8 +142,9 @@ pub fn find(build: &mut Build) { build.verbose(&format!("CC_{} = {:?}", &target.triple, build.cc(target))); build.verbose(&format!("CFLAGS_{} = {:?}", &target.triple, cflags)); if let Ok(cxx) = build.cxx(target) { + let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); build.verbose(&format!("CXX_{} = {:?}", &target.triple, cxx)); - build.verbose(&format!("CXXFLAGS_{} = {:?}", &target.triple, cflags)); + build.verbose(&format!("CXXFLAGS_{} = {:?}", &target.triple, cxxflags)); } if let Some(ar) = ar { build.verbose(&format!("AR_{} = {:?}", &target.triple, ar)); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b4c6210b3881487916fcbab32617ad10573605ec..99717780346014a60d086e8ef4f95a77aed66e82 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -28,7 +28,7 @@ use crate::tool::SourceType; use crate::util::{exe, is_debug_info, is_dylib, symlink_dir}; use crate::LLVM_TOOLS; -use crate::{Compiler, DependencyType, GitRepo, Mode}; +use crate::{CLang, Compiler, DependencyType, GitRepo, Mode}; #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] pub struct Std { @@ -249,7 +249,7 @@ fn copy_self_contained_objects( } } else if target.contains("windows-gnu") { for obj in ["crt2.o", "dllcrt2.o"].iter() { - let src = compiler_file(builder, builder.cc(target), target, obj); + let src = compiler_file(builder, builder.cc(target), target, CLang::C, obj); let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained)); @@ -727,7 +727,13 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS && !target.contains("msvc") && !target.contains("apple") { - let file = compiler_file(builder, builder.cxx(target).unwrap(), target, "libstdc++.a"); + let file = compiler_file( + builder, + builder.cxx(target).unwrap(), + target, + CLang::Cxx, + "libstdc++.a", + ); cargo.env("LLVM_STATIC_STDCPP", file); } if builder.config.llvm_link_shared { @@ -948,10 +954,11 @@ pub fn compiler_file( builder: &Builder<'_>, compiler: &Path, target: TargetSelection, + c: CLang, file: &str, ) -> PathBuf { let mut cmd = Command::new(compiler); - cmd.args(builder.cflags(target, GitRepo::Rustc)); + cmd.args(builder.cflags(target, GitRepo::Rustc, c)); cmd.arg(format!("-print-file-name={}", file)); let out = output(&mut cmd); PathBuf::from(out.trim()) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 86339c8d7f88d2992458fcc197c0b2d8eb2aa35f..abfac2a5897939499ab2ce8ef92024e4a26d3cce 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -339,6 +339,11 @@ pub fn must_support_dlopen(&self) -> bool { } } +pub enum CLang { + C, + Cxx, +} + impl Build { /// Creates a new set of build configuration from the `flags` on the command /// line and the filesystem `config`. @@ -941,10 +946,15 @@ fn cc(&self, target: TargetSelection) -> &Path { /// Returns a list of flags to pass to the C compiler for the target /// specified. - fn cflags(&self, target: TargetSelection, which: GitRepo) -> Vec { + fn cflags(&self, target: TargetSelection, which: GitRepo, c: CLang) -> Vec { + let base = match c { + CLang::C => &self.cc[&target], + CLang::Cxx => &self.cxx[&target], + }; + // Filter out -O and /O (the optimization flags) that we picked up from // cc-rs because the build scripts will determine that for themselves. - let mut base = self.cc[&target] + let mut base = base .args() .iter() .map(|s| s.to_string_lossy().into_owned()) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index f00875239040db8b67d298b0019bcf4939952c11..a751a6e3ece7f918ab2df0860c190daca1c5f915 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -21,7 +21,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; use crate::util::{self, exe}; -use crate::GitRepo; +use crate::{CLang, GitRepo}; use build_helper::up_to_date; pub struct Meta { @@ -529,7 +529,7 @@ fn configure_cmake( } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); - let mut cflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into(); + let mut cflags: OsString = builder.cflags(target, GitRepo::Llvm, CLang::C).join(" ").into(); if let Some(ref s) = builder.config.llvm_cflags { cflags.push(" "); cflags.push(s); @@ -545,12 +545,8 @@ fn configure_cmake( if builder.config.llvm_clang_cl.is_some() { cflags.push(&format!(" --target={}", target)); } - if let Some(flags) = env::var_os("CFLAGS") { - cflags.push(" "); - cflags.push(flags); - } cfg.define("CMAKE_C_FLAGS", cflags); - let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into(); + let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm, CLang::Cxx).join(" ").into(); if let Some(ref s) = builder.config.llvm_cxxflags { cxxflags.push(" "); cxxflags.push(s); @@ -558,10 +554,6 @@ fn configure_cmake( if builder.config.llvm_clang_cl.is_some() { cxxflags.push(&format!(" --target={}", target)); } - if let Some(flags) = env::var_os("CXXFLAGS") { - cxxflags.push(" "); - cxxflags.push(flags); - } cfg.define("CMAKE_CXX_FLAGS", cxxflags); if let Some(ar) = builder.ar(target) { if ar.is_absolute() { @@ -583,7 +575,7 @@ fn configure_cmake( ldflags.push_all(flags); } - if let Some(flags) = env::var_os("LDFLAGS") { + if let Some(flags) = get_var("LDFLAGS", &builder.config.build.triple, &target.triple) { ldflags.push_all(&flags); } @@ -596,6 +588,16 @@ fn configure_cmake( } } +// Adapted from https://github.com/alexcrichton/cc-rs/blob/fba7feded71ee4f63cfe885673ead6d7b4f2f454/src/lib.rs#L2347-L2365 +fn get_var(var_base: &str, host: &str, target: &str) -> Option { + let kind = if host == target { "HOST" } else { "TARGET" }; + let target_u = target.replace("-", "_"); + env::var_os(&format!("{}_{}", var_base, target)) + .or_else(|| env::var_os(&format!("{}_{}", var_base, target_u))) + .or_else(|| env::var_os(&format!("{}_{}", kind, var_base))) + .or_else(|| env::var_os(var_base)) +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Lld { pub target: TargetSelection, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 176c06114e01df5de5a0401cec8c631604fc3d6b..19d98df3ce9023a2fb91b1d326b3f4d3c5a6d3cc 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -24,7 +24,7 @@ use crate::toolstate::ToolState; use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var}; use crate::Crate as CargoCrate; -use crate::{envify, DocTests, GitRepo, Mode}; +use crate::{envify, CLang, DocTests, GitRepo, Mode}; const ADB_TEST_DIR: &str = "/data/tmp/work"; @@ -1509,7 +1509,9 @@ fn run(self, builder: &Builder<'_>) { .arg("--cxx") .arg(builder.cxx(target).unwrap()) .arg("--cflags") - .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); + .arg(builder.cflags(target, GitRepo::Rustc, CLang::C).join(" ")) + .arg("--cxxflags") + .arg(builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ")); copts_passed = true; if let Some(ar) = builder.ar(target) { cmd.arg("--ar").arg(ar); @@ -1520,7 +1522,14 @@ fn run(self, builder: &Builder<'_>) { cmd.arg("--llvm-components").arg(""); } if !copts_passed { - cmd.arg("--cc").arg("").arg("--cxx").arg("").arg("--cflags").arg(""); + cmd.arg("--cc") + .arg("") + .arg("--cxx") + .arg("") + .arg("--cflags") + .arg("") + .arg("--cxxflags") + .arg(""); } if builder.remote_tested(target) { diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 82fe790a576ab04c8fccc84af8bb1ebc1c1fcdb1..1bf6e6d011e5c125a2be7e7f64c5c3c54cbc15e5 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -357,6 +357,7 @@ pub struct Config { pub cc: String, pub cxx: String, pub cflags: String, + pub cxxflags: String, pub ar: String, pub linker: Option, pub llvm_components: String, diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 157b42e2d17f5a52f3bfdb8870178c7a0f28c7ba..5b144a1020f4c3e0f9baeb51299b3875c8e0a0af 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -52,6 +52,7 @@ fn config() -> Config { "--cc=c", "--cxx=c++", "--cflags=", + "--cxxflags=", "--llvm-components=", "--android-cross-path=", "--target=x86_64-unknown-linux-gnu", diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 58cde108b33221987b025fd0e5dcae64f8c5e8ff..3f2cd3ae232ba5822452816d8dd8524fecea1e00 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -126,6 +126,7 @@ pub fn parse_config(args: Vec) -> Config { .reqopt("", "cc", "path to a C compiler", "PATH") .reqopt("", "cxx", "path to a C++ compiler", "PATH") .reqopt("", "cflags", "flags for the C compiler", "FLAGS") + .reqopt("", "cxxflags", "flags for the CXX compiler", "FLAGS") .optopt("", "ar", "path to an archiver", "PATH") .optopt("", "linker", "path to a linker", "PATH") .reqopt("", "llvm-components", "list of LLVM components built in", "LIST") @@ -288,6 +289,7 @@ fn make_absolute(path: PathBuf) -> PathBuf { cc: matches.opt_str("cc").unwrap(), cxx: matches.opt_str("cxx").unwrap(), cflags: matches.opt_str("cflags").unwrap(), + cxxflags: matches.opt_str("cxxflags").unwrap(), ar: matches.opt_str("ar").unwrap_or_else(|| String::from("ar")), linker: matches.opt_str("linker"), llvm_components: matches.opt_str("llvm-components").unwrap(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 3f67a64971b678193185769eee00d9eeab0f96e8..8431aa7b818df7b71b1dcd1ea1e4afd9c6872c5a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2919,15 +2919,22 @@ fn run_rmake_test(&self) { .map(|s| s.replace("/", "-")) .collect::>() .join(" "); + let cxxflags = self + .config + .cxxflags + .split(' ') + .map(|s| s.replace("/", "-")) + .collect::>() + .join(" "); cmd.env("IS_MSVC", "1") .env("IS_WINDOWS", "1") .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) .env("CC", format!("'{}' {}", self.config.cc, cflags)) - .env("CXX", format!("'{}'", &self.config.cxx)); + .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags)); } else { cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags)) - .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags)) + .env("CXX", format!("{} {}", self.config.cxx, self.config.cxxflags)) .env("AR", &self.config.ar); if self.config.target.contains("windows") {