summaryrefslogtreecommitdiffstats
path: root/src/bootstrap/native.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/native.rs')
-rw-r--r--src/bootstrap/native.rs153
1 files changed, 77 insertions, 76 deletions
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index f6c453ebe..e0d1504c9 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -24,9 +24,20 @@ use crate::util::get_clang_cl_resource_dir;
use crate::util::{self, exe, output, t, up_to_date};
use crate::{CLang, GitRepo};
+use build_helper::ci::CiEnv;
+
+#[derive(Clone)]
+pub struct LlvmResult {
+ /// Path to llvm-config binary.
+ /// NB: This is always the host llvm-config!
+ pub llvm_config: PathBuf,
+ /// Path to LLVM cmake directory for the target.
+ pub llvm_cmake_dir: PathBuf,
+}
+
pub struct Meta {
stamp: HashStamp,
- build_llvm_config: PathBuf,
+ res: LlvmResult,
out_dir: PathBuf,
root: String,
}
@@ -54,17 +65,17 @@ impl LdFlags {
}
}
-// This returns whether we've already previously built LLVM.
-//
-// It's used to avoid busting caches during x.py check -- if we've already built
-// LLVM, it's fine for us to not try to avoid doing so.
-//
-// This will return the llvm-config if it can get it (but it will not build it
-// if not).
+/// This returns whether we've already previously built LLVM.
+///
+/// It's used to avoid busting caches during x.py check -- if we've already built
+/// LLVM, it's fine for us to not try to avoid doing so.
+///
+/// This will return the llvm-config if it can get it (but it will not build it
+/// if not).
pub fn prebuilt_llvm_config(
builder: &Builder<'_>,
target: TargetSelection,
-) -> Result<PathBuf, Meta> {
+) -> Result<LlvmResult, Meta> {
builder.config.maybe_download_ci_llvm();
// If we're using a custom LLVM bail out here, but we can only use a
@@ -72,7 +83,14 @@ pub fn prebuilt_llvm_config(
if let Some(config) = builder.config.target_config.get(&target) {
if let Some(ref s) = config.llvm_config {
check_llvm_version(builder, s);
- return Ok(s.to_path_buf());
+ let llvm_config = s.to_path_buf();
+ let mut llvm_cmake_dir = llvm_config.clone();
+ llvm_cmake_dir.pop();
+ llvm_cmake_dir.pop();
+ llvm_cmake_dir.push("lib");
+ llvm_cmake_dir.push("cmake");
+ llvm_cmake_dir.push("llvm");
+ return Ok(LlvmResult { llvm_config, llvm_cmake_dir });
}
}
@@ -84,8 +102,9 @@ pub fn prebuilt_llvm_config(
llvm_config_ret_dir.push("build");
}
llvm_config_ret_dir.push("bin");
-
let build_llvm_config = llvm_config_ret_dir.join(exe("llvm-config", builder.config.build));
+ let llvm_cmake_dir = out_dir.join("lib/cmake/llvm");
+ let res = LlvmResult { llvm_config: build_llvm_config, llvm_cmake_dir };
let stamp = out_dir.join("llvm-finished-building");
let stamp = HashStamp::new(stamp, builder.in_tree_llvm_info.sha());
@@ -96,7 +115,7 @@ pub fn prebuilt_llvm_config(
Using a potentially stale build of LLVM; \
This may not behave well.",
);
- return Ok(build_llvm_config);
+ return Ok(res);
}
if stamp.is_done() {
@@ -110,10 +129,10 @@ pub fn prebuilt_llvm_config(
stamp.path.display()
));
}
- return Ok(build_llvm_config);
+ return Ok(res);
}
- Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() })
+ Err(Meta { stamp, res, out_dir, root: root.into() })
}
/// This retrieves the LLVM sha we *want* to use, according to git history.
@@ -200,7 +219,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
return false;
}
- if crate::util::CiEnv::is_ci() {
+ if CiEnv::is_ci() {
// We assume we have access to git, so it's okay to unconditionally pass
// `true` here.
let llvm_sha = detect_llvm_sha(config, true);
@@ -223,7 +242,7 @@ pub struct Llvm {
}
impl Step for Llvm {
- type Output = PathBuf; // path to llvm-config
+ type Output = LlvmResult;
const ONLY_HOSTS: bool = true;
@@ -236,7 +255,7 @@ impl Step for Llvm {
}
/// Compile LLVM for `target`.
- fn run(self, builder: &Builder<'_>) -> PathBuf {
+ fn run(self, builder: &Builder<'_>) -> LlvmResult {
let target = self.target;
let target_native = if self.target.starts_with("riscv") {
// RISC-V target triples in Rust is not named the same as C compiler target triples.
@@ -252,11 +271,10 @@ impl Step for Llvm {
target.to_string()
};
- let Meta { stamp, build_llvm_config, out_dir, root } =
- match prebuilt_llvm_config(builder, target) {
- Ok(p) => return p,
- Err(m) => m,
- };
+ let Meta { stamp, res, out_dir, root } = match prebuilt_llvm_config(builder, target) {
+ Ok(p) => return p,
+ Err(m) => m,
+ };
builder.update_submodule(&Path::new("src").join("llvm-project"));
if builder.llvm_link_shared() && target.contains("windows") {
@@ -430,7 +448,8 @@ impl Step for Llvm {
// https://llvm.org/docs/HowToCrossCompileLLVM.html
if target != builder.config.build {
- let llvm_config = builder.ensure(Llvm { target: builder.config.build });
+ let LlvmResult { llvm_config, .. } =
+ builder.ensure(Llvm { target: builder.config.build });
if !builder.config.dry_run() {
let llvm_bindir = output(Command::new(&llvm_config).arg("--bindir"));
let host_bin = Path::new(llvm_bindir.trim());
@@ -480,7 +499,7 @@ impl Step for Llvm {
// tools and libs on all platforms.
if builder.config.dry_run() {
- return build_llvm_config;
+ return res;
}
cfg.build();
@@ -490,7 +509,7 @@ impl Step for Llvm {
// for a versioned path like libLLVM-14.dylib. Manually create a symbolic
// link to make llvm-config happy.
if builder.llvm_link_shared() && target.contains("apple-darwin") {
- let mut cmd = Command::new(&build_llvm_config);
+ let mut cmd = Command::new(&res.llvm_config);
let version = output(cmd.arg("--version"));
let major = version.split('.').next().unwrap();
let lib_name = match llvm_version_suffix {
@@ -509,18 +528,18 @@ impl Step for Llvm {
// LLVM after a configuration change, so to rebuild it the build files have to be removed,
// which will also remove these modified files.
if builder.config.llvm_bolt_profile_generate {
- instrument_with_bolt_inplace(&get_built_llvm_lib_path(&build_llvm_config));
+ instrument_with_bolt_inplace(&get_built_llvm_lib_path(&res.llvm_config));
}
if let Some(path) = &builder.config.llvm_bolt_profile_use {
optimize_library_with_bolt_inplace(
- &get_built_llvm_lib_path(&build_llvm_config),
+ &get_built_llvm_lib_path(&res.llvm_config),
&Path::new(path),
);
}
t!(stamp.write());
- build_llvm_config
+ res
}
}
@@ -600,6 +619,9 @@ fn configure_cmake(
if target.starts_with("aarch64") {
// macOS uses a different name for building arm64
cfg.define("CMAKE_OSX_ARCHITECTURES", "arm64");
+ } else if target.starts_with("i686") {
+ // macOS uses a different name for building i386
+ cfg.define("CMAKE_OSX_ARCHITECTURES", "i386");
} else {
cfg.define("CMAKE_OSX_ARCHITECTURES", target.triple.split('-').next().unwrap());
}
@@ -803,7 +825,21 @@ impl Step for Lld {
}
let target = self.target;
- let llvm_config = builder.ensure(Llvm { target: self.target });
+ let LlvmResult { llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target });
+
+ // The `dist` step packages LLD next to LLVM's binaries for download-ci-llvm. The root path
+ // we usually expect here is `./build/$triple/ci-llvm/`, with the binaries in its `bin`
+ // subfolder. We check if that's the case, and if LLD's binary already exists there next to
+ // `llvm-config`: if so, we can use it instead of building LLVM/LLD from source.
+ let ci_llvm_bin = llvm_config.parent().unwrap();
+ if ci_llvm_bin.is_dir() && ci_llvm_bin.file_name().unwrap() == "bin" {
+ let lld_path = ci_llvm_bin.join(exe("lld", target));
+ if lld_path.exists() {
+ // The following steps copying `lld` as `rust-lld` to the sysroot, expect it in the
+ // `bin` subfolder of this step's out dir.
+ return ci_llvm_bin.parent().unwrap().to_path_buf();
+ }
+ }
let out_dir = builder.lld_out(target);
let done_stamp = out_dir.join("lld-finished-building");
@@ -834,22 +870,6 @@ impl Step for Lld {
configure_cmake(builder, target, &mut cfg, true, ldflags);
configure_llvm(builder, target, &mut cfg);
- // This is an awful, awful hack. Discovered when we migrated to using
- // clang-cl to compile LLVM/LLD it turns out that LLD, when built out of
- // tree, will execute `llvm-config --cmakedir` and then tell CMake about
- // that directory for later processing. Unfortunately if this path has
- // forward slashes in it (which it basically always does on Windows)
- // then CMake will hit a syntax error later on as... something isn't
- // escaped it seems?
- //
- // Instead of attempting to fix this problem in upstream CMake and/or
- // LLVM/LLD we just hack around it here. This thin wrapper will take the
- // output from llvm-config and replace all instances of `\` with `/` to
- // ensure we don't hit the same bugs with escaping. It means that you
- // can't build on a system where your paths require `\` on Windows, but
- // there's probably a lot of reasons you can't do that other than this.
- let llvm_config_shim = env::current_exe().unwrap().with_file_name("llvm-config-wrapper");
-
// Re-use the same flags as llvm to control the level of debug information
// generated for lld.
let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
@@ -860,36 +880,17 @@ impl Step for Lld {
cfg.out_dir(&out_dir)
.profile(profile)
- .env("LLVM_CONFIG_REAL", &llvm_config)
- .define("LLVM_CONFIG_PATH", llvm_config_shim)
+ .define("LLVM_CMAKE_DIR", llvm_cmake_dir)
.define("LLVM_INCLUDE_TESTS", "OFF");
- // While we're using this horrible workaround to shim the execution of
- // llvm-config, let's just pile on more. I can't seem to figure out how
- // to build LLD as a standalone project and also cross-compile it at the
- // same time. It wants a natively executable `llvm-config` to learn
- // about LLVM, but then it learns about all the host configuration of
- // LLVM and tries to link to host LLVM libraries.
- //
- // To work around that we tell our shim to replace anything with the
- // build target with the actual target instead. This'll break parts of
- // LLD though which try to execute host tools, such as llvm-tblgen, so
- // we specifically tell it where to find those. This is likely super
- // brittle and will break over time. If anyone knows better how to
- // cross-compile LLD it would be much appreciated to fix this!
if target != builder.config.build {
- cfg.env("LLVM_CONFIG_SHIM_REPLACE", &builder.config.build.triple)
- .env("LLVM_CONFIG_SHIM_REPLACE_WITH", &target.triple)
- .define(
- "LLVM_TABLEGEN_EXE",
- llvm_config.with_file_name("llvm-tblgen").with_extension(EXE_EXTENSION),
- );
+ // Use the host llvm-tblgen binary.
+ cfg.define(
+ "LLVM_TABLEGEN_EXE",
+ llvm_config.with_file_name("llvm-tblgen").with_extension(EXE_EXTENSION),
+ );
}
- // Explicitly set C++ standard, because upstream doesn't do so
- // for standalone builds.
- cfg.define("CMAKE_CXX_STANDARD", "14");
-
cfg.build();
t!(File::create(&done_stamp));
@@ -906,7 +907,7 @@ impl Step for TestHelpers {
type Output = ();
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("src/test/auxiliary/rust_test_helpers.c")
+ run.path("tests/auxiliary/rust_test_helpers.c")
}
fn make_run(run: RunConfig<'_>) {
@@ -928,7 +929,7 @@ impl Step for TestHelpers {
self.target
};
let dst = builder.test_helpers_out(target);
- let src = builder.src.join("src/test/auxiliary/rust_test_helpers.c");
+ let src = builder.src.join("tests/auxiliary/rust_test_helpers.c");
if up_to_date(&src, &dst.join("librust_test_helpers.a")) {
return;
}
@@ -957,7 +958,7 @@ impl Step for TestHelpers {
.opt_level(0)
.warnings(false)
.debug(false)
- .file(builder.src.join("src/test/auxiliary/rust_test_helpers.c"))
+ .file(builder.src.join("tests/auxiliary/rust_test_helpers.c"))
.compile("rust_test_helpers");
}
}
@@ -991,7 +992,7 @@ impl Step for Sanitizers {
return runtimes;
}
- let llvm_config = builder.ensure(Llvm { target: builder.config.build });
+ let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build });
if builder.config.dry_run() {
return runtimes;
}
@@ -1086,12 +1087,12 @@ fn supported_sanitizers(
match &*target.triple {
"aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
- "aarch64-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]),
+ "aarch64-unknown-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]),
"aarch64-unknown-linux-gnu" => {
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"])
}
"x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
- "x86_64-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]),
+ "x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]),
"x86_64-unknown-freebsd" => common_libs("freebsd", "x86_64", &["asan", "msan", "tsan"]),
"x86_64-unknown-netbsd" => {
common_libs("netbsd", "x86_64", &["asan", "lsan", "msan", "tsan"])