From 0546d115288ce0d6c3a819909de12fba5ce673fd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 24 Apr 2020 11:18:59 -0700 Subject: [PATCH] Fix cross-compiling LLD to different platforms Looks like the native build system isn't great a coping with this, so try to work around that with a few workarounds. --- src/bootstrap/bin/llvm-config-wrapper.rs | 9 ++++++++- src/bootstrap/native.rs | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/bin/llvm-config-wrapper.rs b/src/bootstrap/bin/llvm-config-wrapper.rs index cf77af44ff6..89984bb55df 100644 --- a/src/bootstrap/bin/llvm-config-wrapper.rs +++ b/src/bootstrap/bin/llvm-config-wrapper.rs @@ -10,7 +10,14 @@ fn main() { let mut cmd = Command::new(real_llvm_config); cmd.args(env::args().skip(1)).stderr(Stdio::piped()); let output = cmd.output().expect("failed to spawn llvm-config"); - let stdout = String::from_utf8_lossy(&output.stdout); + let mut stdout = String::from_utf8_lossy(&output.stdout); + + if let Ok(to_replace) = env::var("LLVM_CONFIG_SHIM_REPLACE") { + if let Ok(replace_with) = env::var("LLVM_CONFIG_SHIM_REPLACE_WITH") { + stdout = stdout.replace(&to_replace, &replace_with).into(); + } + } + print!("{}", stdout.replace("\\", "/")); io::stdout().flush().unwrap(); process::exit(output.status.code().unwrap_or(1)); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 0c87695ff7c..0f39e33c5f4 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -479,10 +479,29 @@ fn run(self, builder: &Builder<'_>) -> PathBuf { let llvm_config_shim = env::current_exe().unwrap().with_file_name("llvm-config-wrapper"); cfg.out_dir(&out_dir) .profile("Release") - .env("LLVM_CONFIG_REAL", llvm_config) + .env("LLVM_CONFIG_REAL", &llvm_config) .define("LLVM_CONFIG_PATH", llvm_config_shim) .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) + .env("LLVM_CONFIG_SHIM_REPLACE_WITH", &target) + .define("LLVM_TABLEGEN_EXE", llvm_config.with_file_name("llvm-tblgen")); + } + cfg.build(); t!(File::create(&done_stamp));