Skip to content

Commit

Permalink
Link against lld for linking compiled object files
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Sep 26, 2024
1 parent 5b48d87 commit 3fce704
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 2 deletions.
23 changes: 23 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,29 @@ fn link_natively(

// Invoke the system linker
info!("{cmd:?}");

#[cfg(target_os = "wasi")]
if matches!(flavor, LinkerFlavor::Gnu(Cc::No, Lld::Yes) | LinkerFlavor::WasmLld(Cc::No)) {
extern "C" {
fn RustRunLld(
argc: std::ffi::c_int,
argv: *const *const std::ffi::c_char,
) -> std::ffi::c_int;
}

let cmd = cmd.command();
println!("Linking using {cmd:?}");
let mut args = cmd
.get_args()
.map(|arg| std::ffi::CString::new(arg.as_encoded_bytes()).unwrap())
.collect::<Vec<_>>();
args.insert(0, std::ffi::CString::new(cmd.get_program().as_encoded_bytes()).unwrap());
let argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();

let ret = unsafe { RustRunLld(args.len() as std::ffi::c_int, argv.as_ptr()) };
std::process::exit(ret);
}

let retry_on_segfault = env::var("RUSTC_RETRY_LINKER_ON_SEGFAULT").is_ok();
let unknown_arg_regex =
Regex::new(r"(unknown|unrecognized) (command line )?(option|argument)").unwrap();
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ fn main() {
.file("llvm-wrapper/CoverageMappingWrapper.cpp")
.file("llvm-wrapper/SymbolWrapper.cpp")
.file("llvm-wrapper/Linker.cpp")
.file("llvm-wrapper/LLD.cpp")
.cpp(true)
.cpp_link_stdlib(None) // we handle this below
.compile("llvm-wrapper");
Expand Down Expand Up @@ -328,6 +329,11 @@ fn main() {
println!("cargo:rustc-link-lib={kind}={name}");
}

println!("cargo:rustc-link-lib=static=LLVMOption");
println!("cargo:rustc-link-lib=static=lldCommon");
println!("cargo:rustc-link-lib=static=lldELF");
println!("cargo:rustc-link-lib=static=lldWasm");

// LLVM ldflags
//
// If we're a cross-compile of LLVM then unfortunately we can't trust these
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/LLD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "lld/Common/Driver.h"

LLD_HAS_DRIVER(elf)
LLD_HAS_DRIVER(wasm)

extern "C" int RustRunLld(int argc, char **argv) {
llvm::ArrayRef<const char *> args(argv, argv + argc);
auto r = lld::lldMain(args, llvm::outs(), llvm::errs(),
{{lld::Gnu, &lld::elf::link}, {lld::Wasm, &lld::wasm::link}});
return r.retCode;
}
2 changes: 1 addition & 1 deletion config.llvm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ docs = false
extended = false
tools = []
host = ["wasm32-wasip1-threads"]
target = ["x86_64-unknown-linux-gnu", "wasm32-wasip1-threads"]
target = ["x86_64-unknown-linux-gnu", "wasm32-wasip1"]
cargo-native-static = true

[install]
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/src/core/build_steps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ impl Step for Llvm {
return res;
}

cfg.define("LLVM_ENABLE_PROJECTS", "lld");

if target.contains("wasi") {
let wasi_sysroot = env::var("WASI_SYSROOT").expect("WASI_SYSROOT not set");
let wasi_sdk_path = std::path::Path::new(&wasi_sysroot)
Expand Down Expand Up @@ -669,7 +671,6 @@ impl Step for Llvm {
.define("LLVM_TOOL_XCODE_TOOLCHAIN_BUILD", "OFF")
.define("LLVM_TOOL_YAML2OBJ_BUILD", "OFF")
// .define("LLVM_ENABLE_PROJECTS", "clang;lld")
.define("LLVM_ENABLE_PROJECTS", "")
// .define("CLANG_ENABLE_ARCMT", "OFF")
// .define("CLANG_ENABLE_STATIC_ANALYZER", "OFF")
// .define("CLANG_INCLUDE_TESTS", "OFF")
Expand Down

0 comments on commit 3fce704

Please sign in to comment.