Skip to content

Commit

Permalink
Fix cross-compilation of LLVM to aarch64 Windows targets
Browse files Browse the repository at this point in the history
When cross-compiling, the LLVM build system recurses to build tools
that need to run on the host system. However, since we pass cmake defines
to set the compiler and target, LLVM still compiles these tools for the
target system, rather than the host. The tools then fail to execute
during the LLVM build.

This change sets defines for the tools that need to run on the
host (llvm-nm, llvm-tablegen, and llvm-config), so that the LLVM build
does not attempt to build them, and instead relies on the tools already built.

If compiling with clang-cl, this change also adds the `--target` option
to specify the target triple. MSVC compilers do not require this, since there
is a separate compiler binary for cross-compilation.
  • Loading branch information
arlosi committed Jul 8, 2020
1 parent 1d919c9 commit 59f979f
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 11 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,9 @@ version = "0.1.0"

[[package]]
name = "cc"
version = "1.0.54"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
checksum = "0fde55d2a2bfaa4c9668bbc63f531fbdeee3ffe188f4662511ce2c22b3eedebe"
dependencies = [
"jobserver",
]
Expand Down
31 changes: 23 additions & 8 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! ensure that they're always in place if needed.

use std::env;
use std::env::consts::EXE_EXTENSION;
use std::ffi::OsString;
use std::fs::{self, File};
use std::io;
Expand Down Expand Up @@ -252,8 +253,14 @@ impl Step for Llvm {
// FIXME: if the llvm root for the build triple is overridden then we
// should use llvm-tblgen from there, also should verify that it
// actually exists most of the time in normal installs of LLVM.
let host = builder.llvm_out(builder.config.build).join("bin/llvm-tblgen");
cfg.define("CMAKE_CROSSCOMPILING", "True").define("LLVM_TABLEGEN", &host);
let host_bin = builder.llvm_out(builder.config.build).join("bin");
cfg.define("CMAKE_CROSSCOMPILING", "True");
cfg.define("LLVM_TABLEGEN", host_bin.join("llvm-tblgen").with_extension(EXE_EXTENSION));
cfg.define("LLVM_NM", host_bin.join("llvm-nm").with_extension(EXE_EXTENSION));
cfg.define(
"LLVM_CONFIG_PATH",
host_bin.join("llvm-config").with_extension(EXE_EXTENSION),
);

if target.contains("netbsd") {
cfg.define("CMAKE_SYSTEM_NAME", "NetBSD");
Expand All @@ -262,8 +269,6 @@ impl Step for Llvm {
} else if target.contains("windows") {
cfg.define("CMAKE_SYSTEM_NAME", "Windows");
}

cfg.define("LLVM_NATIVE_BUILD", builder.llvm_out(builder.config.build).join("build"));
}

if let Some(ref suffix) = builder.config.llvm_version_suffix {
Expand Down Expand Up @@ -431,6 +436,9 @@ fn configure_cmake(
cflags.push_str(" -miphoneos-version-min=10.0");
}
}
if builder.config.llvm_clang_cl.is_some() {
cflags.push_str(&format!(" --target={}", target))
}
cfg.define("CMAKE_C_FLAGS", cflags);
let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" ");
if builder.config.llvm_static_stdcpp && !target.contains("msvc") && !target.contains("netbsd") {
Expand All @@ -439,6 +447,9 @@ fn configure_cmake(
if let Some(ref s) = builder.config.llvm_cxxflags {
cxxflags.push_str(&format!(" {}", s));
}
if builder.config.llvm_clang_cl.is_some() {
cxxflags.push_str(&format!(" --target={}", target))
}
cfg.define("CMAKE_CXX_FLAGS", cxxflags);
if let Some(ar) = builder.ar(target) {
if ar.is_absolute() {
Expand Down Expand Up @@ -484,7 +495,7 @@ impl Step for Lld {
run.builder.ensure(Lld { target: run.target });
}

/// Compile LLVM for `target`.
/// Compile LLD for `target`.
fn run(self, builder: &Builder<'_>) -> PathBuf {
if builder.config.dry_run {
return PathBuf::from("lld-out-dir-test-gen");
Expand Down Expand Up @@ -521,6 +532,7 @@ impl Step for Lld {
// 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");

cfg.out_dir(&out_dir)
.profile("Release")
.env("LLVM_CONFIG_REAL", &llvm_config)
Expand All @@ -543,7 +555,10 @@ impl Step for Lld {
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"));
.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
Expand Down Expand Up @@ -595,8 +610,8 @@ impl Step for TestHelpers {
}

// We may have found various cross-compilers a little differently due to our
// extra configuration, so inform gcc of these compilers. Note, though, that
// on MSVC we still need gcc's detection of env vars (ugh).
// extra configuration, so inform cc of these compilers. Note, though, that
// on MSVC we still need cc's detection of env vars (ugh).
if !target.contains("msvc") {
if let Some(ar) = builder.ar(target) {
cfg.archiver(ar);
Expand Down
2 changes: 1 addition & 1 deletion src/llvm-project

0 comments on commit 59f979f

Please sign in to comment.