From 51963f0f544ed90315b3afa2b6187d57b349cf00 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 29 Aug 2016 17:03:51 -0500 Subject: [PATCH 1/9] internal lld linker this commit embeds lld, the LLVM linker, into rustc. If the `-Z use-lld` flag is passed to rustc, then rustc will use lld (via a library call), instead of an external linker like cc, to link a Rust executable. This has been tested by building the following minimal program: ``` rust #![feature(lang_items)] #![feature(no_core)] #![feature(start)] #![no_core] #[link(name = "c")] extern {} #[start] fn start(_: isize, _: *const *const u8) -> isize { 0 } #[lang = "copy"] trait Copy {} #[lang = "sized"] trait Sized {} ``` Note that lld doesn't implicitly pass libraries (-lc) or startup object (crt1.o) like cc does, so one has to manually pass these to lld via `-C link-args`: ``` $ rustc -Z print-link-args \ -Z use-lld \ -C link-args='-L /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/Scrt1.o /usr/lib/x86_64-linux-gnu/crti.o' zero.rs ["lld", "--as-needed", "-z", "noexecstack", "-L", "/root/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib", "zero.0.o", "-o", "zero", "--gc-sections", "--pie", "-L", "/root/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib", "--Bstatic", "--Bdynamic", "-l", "c", "-L", "/usr/lib/x86_64-linux-gnu", "/usr/lib/x86_64-linux-gnu/Scrt1.o", "/usr/lib/x86_64-linux-gnu/crti.o", "-l", "compiler-rt"] ``` Which links correctly! But executing the produced binary yields a segfault :-(. There appears to be a problem when lld mixes Rust code and C code but I haven't investigated further. So was this an exercise in futility? No, not so fast. I did one more test: a Rust program with zero C dependencies, i.e. a Rust "kernel". Basically, I grabbed the "Hello, world" program from Intermezzos chapter 3 [1] and turned it into a Cargo project [2] then proceeded to link it using lld: ``` $ cargo rustc --target x86_64 --release -- -Z print-link-args -Z use-lld ["lld", "-Tlayout.ld", "-L", "/root/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64/lib", "/root/eighty-six/target/x86_64/release/kernel.0.o", "-o", "/root/eighty-six/target/x86_64/release/kernel", "--gc-sections", "-L", "/root/eighty-six/target/x86_64/release/deps", "-L", "/root/eighty-six/target/release/build/kernel-24c773dcbde95e48/out", "-L", "/root/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64/lib", "--Bstatic", "--whole-archive", "-l", "boot", "--no-whole-archive", "--Bdynamic", "/root/eighty-six/target/x86_64/release/deps/libcore.rlib"] ``` This linked correctly and after turning the executable into a ISO image, it also worked perfectly under QEMU! ### Extra notes I've only tested ELF executables, not dylibs, MachO or COFF. lld supports ELFs, MachO and COFF formats. So in theory, with an internal lld we could drop the dependency on a external linker pretty much on all the platforms we support. lld is a multi-arch linker so it should be possible to link foreign (e.g. arm or mips) binaries as well but I haven't tested this yet. I actually intended to test this by linking Rust programs for the Cortex-M, as I have experience making C free programs for that target, but lld doesn't support Thumb (yet). Relevant news: "lld now implements almost all of the functionality necessary to function as a system linker for FreeBSD/amd64" -- FreeBSD folk @ LLVM mailing list [3]. The e-mail also mentions that other support for other archs is not quite ready for prime time. [1]: http://intermezzos.github.io/book/booting-up.html [2]: https://github.com/japaric/eighty-six/tree/lld2 [3]: http://lists.llvm.org/pipermail/llvm-dev/2016-August/103998.html --- .gitmodules | 4 + configure | 1 + src/bootstrap/config.rs | 10 +- src/bootstrap/lib.rs | 8 ++ src/bootstrap/native.rs | 20 +++- src/librustc/session/config.rs | 1 + src/librustc_back/target/linux_base.rs | 5 + src/librustc_back/target/mod.rs | 15 +++ src/librustc_driver/Cargo.toml | 3 + src/librustc_lld/Cargo.toml | 14 +++ src/librustc_lld/build.rs | 104 ++++++++++++++++ src/librustc_lld/ffi.rs | 16 +++ src/librustc_lld/lib.rs | 13 ++ src/librustc_lld/src/lib.rs | 0 src/librustc_trans/Cargo.toml | 6 +- src/librustc_trans/back/link.rs | 68 ++++++++++- src/librustc_trans/back/linker.rs | 157 +++++++++++++++++++++++++ src/librustc_trans/lib.rs | 2 + src/lld | 1 + src/rustc/Cargo.lock | 9 ++ src/rustc/Cargo.toml | 1 + src/rustlld/RustWrapper.cpp | 26 ++++ src/test/run-make/lld/Makefile | 10 ++ src/test/run-make/lld/bare.rs | 34 ++++++ src/test/run-make/lld/cortex-m3.json | 11 ++ src/tools/tidy/src/main.rs | 1 + 26 files changed, 531 insertions(+), 9 deletions(-) create mode 100644 src/librustc_lld/Cargo.toml create mode 100644 src/librustc_lld/build.rs create mode 100644 src/librustc_lld/ffi.rs create mode 100644 src/librustc_lld/lib.rs create mode 100644 src/librustc_lld/src/lib.rs create mode 160000 src/lld create mode 100644 src/rustlld/RustWrapper.cpp create mode 100644 src/test/run-make/lld/Makefile create mode 100644 src/test/run-make/lld/bare.rs create mode 100644 src/test/run-make/lld/cortex-m3.json diff --git a/.gitmodules b/.gitmodules index 39288a7ae4907..503d0bff276a7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,7 @@ [submodule "src/liblibc"] path = src/liblibc url = https://github.com/rust-lang/libc.git +[submodule "src/lld"] + path = src/lld + url = git://github.com/japaric/lld.git + branch = rust-lld-2016-07-09 diff --git a/configure b/configure index a8bd3acdff1ac..3f24bf820b697 100755 --- a/configure +++ b/configure @@ -620,6 +620,7 @@ opt rustbuild 0 "use the rust and cargo based build system" opt codegen-tests 1 "run the src/test/codegen tests" opt option-checking 1 "complain about unrecognized options in this configure script" opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)" +opt lld 0 "Build and embed lld, the LLVM linker, into rustc" # Optimization and debugging options. These may be overridden by the release channel, etc. opt_nosave optimize 1 "build optimized rust code" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 0f69bcfbb649d..55a7e5757f503 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -37,19 +37,20 @@ use toml::{Parser, Decoder, Value}; /// `src/bootstrap/config.toml.example`. #[derive(Default)] pub struct Config { - pub ccache: bool, - pub ninja: bool, pub verbose: bool, pub submodules: bool, pub compiler_docs: bool, pub docs: bool, pub target_config: HashMap, - // llvm codegen options + // llvm options (see struct Llvm) + pub ccache: bool, + pub ninja: bool, pub llvm_assertions: bool, pub llvm_optimize: bool, pub llvm_version_check: bool, pub llvm_static_stdcpp: bool, + pub lld: bool, // rust codegen options pub rust_optimize: bool, @@ -128,6 +129,7 @@ struct Llvm { optimize: Option, version_check: Option, static_libstdcpp: Option, + lld: Option, } /// TOML representation of how the Rust build is configured. @@ -229,6 +231,7 @@ impl Config { set(&mut config.llvm_optimize, llvm.optimize); set(&mut config.llvm_version_check, llvm.version_check); set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); + set(&mut config.lld, llvm.lld); } if let Some(ref rust) = toml.rust { set(&mut config.rust_debug_assertions, rust.debug_assertions); @@ -330,6 +333,7 @@ impl Config { ("LOCAL_REBUILD", self.local_rebuild), ("NINJA", self.ninja), ("CODEGEN_TESTS", self.codegen_tests), + ("LLD", self.lld), } match key { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index ebca0c8ecea76..377bfb1ab77ee 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -550,6 +550,11 @@ impl Build { continue } + if submodule.path.components().any(|c| c == Component::Normal("lld".as_ref())) && + !self.config.lld { + continue + } + match submodule.state { State::MaybeDirty => { // drop staged changes @@ -730,6 +735,9 @@ impl Build { if self.config.use_jemalloc { features.push_str(" jemalloc"); } + if self.config.lld { + features.push_str(" lld"); + } return features } diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index df6408e5fe1c8..04b159acf7300 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -27,7 +27,7 @@ use cmake; use gcc; use Build; -use util::up_to_date; +use util::{cp_r, up_to_date}; /// Compile LLVM for `target`. pub fn llvm(build: &Build, target: &str) { @@ -75,6 +75,24 @@ pub fn llvm(build: &Build, target: &str) { .define("LLVM_ENABLE_LIBEDIT", "OFF") .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string()); + // FIXME figure out how to build lld as a external project + // if build.config.lld { + // cfg.define("LLVM_EXTERNAL_PROJECTS", "lld"); + // cfg.define("LLVM_EXTERNAL_LLD_SOURCE_DIR", "../lld"); + // } + + let src_lld = &build.src.join("src/lld"); + let src_llvm_tools_lld = &build.src.join("src/llvm/tools/lld"); + + if src_llvm_tools_lld.exists() { + fs::remove_dir_all(src_llvm_tools_lld).unwrap(); + } + + if build.config.lld { + fs::create_dir(src_llvm_tools_lld).unwrap(); + cp_r(src_lld, src_llvm_tools_lld); + } + if target.starts_with("i686") { cfg.define("LLVM_BUILD_32_BITS", "ON"); } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2009e18f6ee20..f38c6d3a8e62c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -915,6 +915,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "the directory the MIR is dumped into"), perf_stats: bool = (false, parse_bool, [UNTRACKED], "print some performance-related statistics"), + use_lld: bool = (false, parse_bool, [UNTRACKED], "use lld as linker"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_back/target/linux_base.rs b/src/librustc_back/target/linux_base.rs index d1ab71e41404e..b05d9577f33c7 100644 --- a/src/librustc_back/target/linux_base.rs +++ b/src/librustc_back/target/linux_base.rs @@ -30,6 +30,11 @@ pub fn opts() -> TargetOptions { // Always enable NX protection when it is available "-Wl,-z,noexecstack".to_string(), ], + pre_lld_args: vec![ + "--as-needed".to_string(), + "-z".to_string(), + "noexecstack".to_string(), + ], position_independent_executables: true, exe_allocation_crate: super::maybe_jemalloc(), has_elf_tls: true, diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 756586602b45a..835cec6079692 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -245,6 +245,12 @@ pub struct TargetOptions { /// user-defined libraries. pub post_link_args: Vec, + /// lld flags are slightly different from the default linker's (e.g. cc) and we can't always map + /// one to the other so we just maintain a different set of args just for lld + pub pre_lld_args: Vec, + pub late_lld_args: Vec, + pub post_lld_args: Vec, + /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults /// to "generic". pub cpu: String, @@ -355,6 +361,9 @@ impl Default for TargetOptions { ar: option_env!("CFG_DEFAULT_AR").unwrap_or("ar").to_string(), pre_link_args: Vec::new(), post_link_args: Vec::new(), + pre_lld_args: Vec::new(), + late_lld_args: Vec::new(), + post_lld_args: Vec::new(), cpu: "generic".to_string(), features: "".to_string(), dynamic_linking: false, @@ -492,11 +501,14 @@ impl Target { key!(linker); key!(ar); key!(pre_link_args, list); + key!(pre_lld_args, list); key!(pre_link_objects_exe, list); key!(pre_link_objects_dll, list); key!(late_link_args, list); + key!(late_lld_args, list); key!(post_link_objects, list); key!(post_link_args, list); + key!(post_lld_args, list); key!(cpu); key!(features); key!(dynamic_linking, bool); @@ -634,11 +646,14 @@ impl ToJson for Target { target_option_val!(linker); target_option_val!(ar); target_option_val!(pre_link_args); + target_option_val!(pre_lld_args); target_option_val!(pre_link_objects_exe); target_option_val!(pre_link_objects_dll); target_option_val!(late_link_args); + target_option_val!(late_lld_args); target_option_val!(post_link_objects); target_option_val!(post_link_args); + target_option_val!(post_lld_args); target_option_val!(cpu); target_option_val!(features); target_option_val!(dynamic_linking); diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 772d83eb2cfad..507dc5ff67316 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -35,3 +35,6 @@ syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } proc_macro = { path = "../libproc_macro" } + +[features] +lld = ["rustc_trans/lld"] diff --git a/src/librustc_lld/Cargo.toml b/src/librustc_lld/Cargo.toml new file mode 100644 index 0000000000000..1b62eebdd3fa3 --- /dev/null +++ b/src/librustc_lld/Cargo.toml @@ -0,0 +1,14 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_lld" +version = "0.0.0" +build = "build.rs" + +[lib] +name = "rustc_lld" +path = "lib.rs" +crate-type = ["dylib"] + +[build-dependencies] +build_helper = { path = "../build_helper" } +gcc = "0.3.27" diff --git a/src/librustc_lld/build.rs b/src/librustc_lld/build.rs new file mode 100644 index 0000000000000..cd1d64f11ce26 --- /dev/null +++ b/src/librustc_lld/build.rs @@ -0,0 +1,104 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate build_helper; +extern crate gcc; + +use std::env; +use std::path::PathBuf; +use std::process::Command; + +use build_helper::output; + +fn main() { + let target = env::var("TARGET").unwrap(); + let host = env::var("HOST").unwrap(); + let is_crossed = target != host; + + let llvm_config = env::var_os("LLVM_CONFIG") + .map(PathBuf::from) + .unwrap_or_else(|| { + if let Some(dir) = env::var_os("CARGO_TARGET_DIR") + .map(PathBuf::from) { + let to_test = dir.parent() + .unwrap() + .parent() + .unwrap() + .join(&target) + .join("llvm/bin/llvm-config"); + if Command::new(&to_test).output().is_ok() { + return to_test; + } + } + PathBuf::from("llvm-config") + }); + + let mut cmd = Command::new(&llvm_config); + cmd.arg("--cxxflags"); + let cxxflags = output(&mut cmd); + + let mut cfg = gcc::Config::new(); + for flag in cxxflags.split_whitespace() { + // Ignore flags like `-m64` when we're doing a cross build + if is_crossed && flag.starts_with("-m") { + continue; + } + cfg.flag(flag); + } + + cfg.file("../rustlld/RustWrapper.cpp") + .cpp(true) + .cpp_link_stdlib(None) + .compile("librustlld.a"); + + // If we're a cross-compile of LLVM then unfortunately we can't trust these + // ldflags (largely where all the LLVM libs are located). Currently just + // hack around this by replacing the host triple with the target and pray + // that those -L directories are the same! + let mut cmd = Command::new(&llvm_config); + cmd.arg("--ldflags"); + for lib in output(&mut cmd).split_whitespace() { + if lib.starts_with("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", &lib[9..]); + } else if is_crossed { + if lib.starts_with("-L") { + println!("cargo:rustc-link-search=native={}", + lib[2..].replace(&host, &target)); + } + } else if lib.starts_with("-l") { + println!("cargo:rustc-link-lib={}", &lib[2..]); + } else if lib.starts_with("-L") { + println!("cargo:rustc-link-search=native={}", &lib[2..]); + } + } + + // C++ runtime library + if !target.contains("msvc") { + if let Some(s) = env::var_os("LLVM_STATIC_STDCPP") { + assert!(!cxxflags.contains("stdlib=libc++")); + let path = PathBuf::from(s); + println!("cargo:rustc-link-search=native={}", + path.parent().unwrap().display()); + println!("cargo:rustc-link-lib=static=stdc++"); + } else if cxxflags.contains("stdlib=libc++") { + println!("cargo:rustc-link-lib=c++"); + } else { + println!("cargo:rustc-link-lib=stdc++"); + } + } + + // FIXME can we get these from llvm-config? + println!("cargo:rustc-link-lib=static=lldELF"); + println!("cargo:rustc-link-lib=static=lldConfig"); + println!("cargo:rustc-link-lib=static=LLVMOption"); + println!("cargo:rustc-link-lib=static=LLVMPasses"); + println!("cargo:rustc-link-lib=static=LLVMLTO"); + println!("cargo:rustc-link-lib=static=LLVMObjCARCOpts"); +} diff --git a/src/librustc_lld/ffi.rs b/src/librustc_lld/ffi.rs new file mode 100644 index 0000000000000..7fa18000b74be --- /dev/null +++ b/src/librustc_lld/ffi.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::os::raw::{c_char, c_uint}; + +#[linked_from = "rustlld"] // not quite true but good enough +extern { + pub fn LldRustElfLink(Args: *const *const c_char, NumArgs: c_uint)-> bool; +} diff --git a/src/librustc_lld/lib.rs b/src/librustc_lld/lib.rs new file mode 100644 index 0000000000000..2152ee705c888 --- /dev/null +++ b/src/librustc_lld/lib.rs @@ -0,0 +1,13 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(linked_from)] + +pub mod ffi; diff --git a/src/librustc_lld/src/lib.rs b/src/librustc_lld/src/lib.rs new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 38f9e7ab0c51c..e4c5b3b51cb92 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -21,8 +21,12 @@ rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_incremental = { path = "../librustc_incremental" } +rustc_lld = { path = "../librustc_lld", optional = true } rustc_llvm = { path = "../librustc_llvm" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } -syntax_pos = { path = "../libsyntax_pos" } \ No newline at end of file +syntax_pos = { path = "../libsyntax_pos" } + +[features] +lld = ["rustc_lld"] diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 288249a7d9934..05f07bed1e757 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -10,6 +10,8 @@ use super::archive::{ArchiveBuilder, ArchiveConfig}; use super::linker::Linker; +#[cfg(feature = "lld")] +use super::linker::LldLinker; use super::rpath::RPathConfig; use super::rpath; use super::msvc; @@ -29,6 +31,8 @@ use rustc::dep_graph::DepNode; use rustc::hir::svh::Svh; use rustc_back::tempdir::TempDir; use rustc_incremental::IncrementalHashesMap; +#[cfg(feature = "lld")] +use lld::ffi; use std::ascii; use std::char; @@ -350,10 +354,21 @@ fn link_binary_output(sess: &Session, config::CrateTypeStaticlib => { link_staticlib(sess, &objects, &out_filename, tmpdir.path()); } + #[cfg(not(feature = "lld"))] _ => { link_natively(sess, crate_type, &objects, &out_filename, trans, outputs, tmpdir.path()); } + #[cfg(feature = "lld")] + _ => { + if sess.opts.debugging_opts.use_lld { + link_natively_using_lld(sess, crate_type, &objects, &out_filename, + outputs, tmpdir.path()); + } else { + link_natively(sess, crate_type, &objects, &out_filename, trans, + outputs, tmpdir.path()); + } + } } out_filename @@ -603,6 +618,51 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path, } } +#[cfg(feature = "lld")] +fn link_natively_using_lld(sess: &Session, + crate_type: config::CrateType, + objects: &[PathBuf], + out_filename: &Path, + outputs: &OutputFilenames, + tmpdir: &Path) { + let mut lld = LldLinker::new(); + + let root = sess.target_filesearch(PathKind::Native).get_lib_path(); + lld.cmd_like_args(&sess.target.target.options.pre_lld_args); + + let pre_link_objects = if crate_type == config::CrateTypeExecutable { + &sess.target.target.options.pre_link_objects_exe + } else { + &sess.target.target.options.pre_link_objects_dll + }; + for obj in pre_link_objects { + lld.cmd_like_arg(root.join(obj)); + } + + link_args(&mut lld, sess, crate_type, tmpdir, + objects, out_filename, outputs); + lld.cmd_like_args(&sess.target.target.options.late_link_args); + for obj in &sess.target.target.options.post_link_objects { + lld.cmd_like_arg(root.join(obj)); + } + lld.cmd_like_args(&sess.target.target.options.post_lld_args); + + if sess.opts.debugging_opts.print_link_args { + println!("{:?}", lld.args()); + } + + // May have not found libraries in the right formats. + sess.abort_if_errors(); + + // Invoke the linker + time(sess.time_passes(), "running linker", || { + let args = lld.args().iter().map(|s| s.as_ptr()).collect::>(); + unsafe { + assert!(ffi::LldRustElfLink(args.as_ptr(), args.len() as u32)); + } + }); +} + // Create a dynamic library or executable // // This will invoke the system linker/cc to create the resulting file. This @@ -660,8 +720,8 @@ fn link_natively(sess: &Session, .unwrap_or_else(|_| { let mut x = "Non-UTF-8 output: ".to_string(); x.extend(s.iter() - .flat_map(|&b| ascii::escape_default(b)) - .map(|b| char::from_u32(b as u32).unwrap())); + .flat_map(|&b| ascii::escape_default(b)) + .map(|b| char::from_u32(b as u32).unwrap())); x }) } @@ -669,8 +729,8 @@ fn link_natively(sess: &Session, let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); sess.struct_err(&format!("linking with `{}` failed: {}", - pname, - prog.status)) + pname, + prog.status)) .note(&format!("{:?}", &cmd)) .note(&escape_string(&output[..])) .emit(); diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 58cad5c117f93..e24088f999f73 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -10,6 +10,8 @@ use std::collections::HashMap; use std::ffi::OsString; +#[cfg(feature = "lld")] +use std::ffi::{CString, OsStr}; use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufWriter}; @@ -94,6 +96,161 @@ pub trait Linker { fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType); } +#[cfg(feature = "lld")] +pub struct LldLinker { + args: Vec, +} + +#[cfg(feature = "lld")] +fn cstring(s: S) -> CString + where S: Into> +{ + CString::new(s).unwrap() +} + +#[cfg(feature = "lld")] +impl LldLinker { + pub fn new() -> Self { + // NOTE The first argument will be skipped, but we must set it to something. Using lld here + // matches the behavior of the `lld` tool. + LldLinker { args: vec![cstring("lld")] } + } + + pub fn cmd_like_arg(&mut self, arg: S) + where S: AsRef + { + self.args.push(cstring(arg.as_ref().to_string_lossy().into_owned())) + } + + pub fn cmd_like_args(&mut self, args: &[S]) + where S: AsRef + { + for arg in args { + self.cmd_like_arg(arg) + } + } + + pub fn args(&self) -> &[CString] { + &self.args + } +} + +#[cfg(feature = "lld")] +impl Linker for LldLinker { + fn link_dylib(&mut self, lib: &str) { + self.args.push(cstring("-l")); + self.args.push(cstring(lib)); + } + + fn link_staticlib(&mut self, lib: &str) { + self.args.push(cstring("-l")); + self.args.push(cstring(lib)); + } + + fn link_rlib(&mut self, lib: &Path) { + self.cmd_like_arg(lib); + } + + fn include_path(&mut self, path: &Path) { + self.args.push(cstring("-L")); + self.cmd_like_arg(path); + } + + fn framework_path(&mut self, _: &Path) { + // TODO + } + + fn output_filename(&mut self, path: &Path) { + self.args.push(cstring("-o")); + self.cmd_like_arg(path); + } + + fn add_object(&mut self, path: &Path) { + self.cmd_like_arg(path); + } + + fn position_independent_executable(&mut self) { + self.args.push(cstring("--pie")); + } + + fn args(&mut self, args: &[String]) { + self.args.extend(args.iter().cloned().map(cstring)) + } + + fn link_rust_dylib(&mut self, lib: &str, _path: &Path) { + self.args.push(cstring("-l")); + self.args.push(cstring(lib)); + } + + fn link_framework(&mut self, _: &str) { + // TODO + } + + fn link_whole_staticlib(&mut self, lib: &str, _: &[PathBuf]) { + // TODO OSX + self.whole_archives(); + self.args.push(cstring("-l")); + self.args.push(cstring(lib)); + self.no_whole_archives(); + } + + fn link_whole_rlib(&mut self, lib: &Path) { + // TODO OSX + self.whole_archives(); + self.cmd_like_arg(lib); + self.no_whole_archives(); + } + + fn gc_sections(&mut self, _: bool) { + self.args.push(cstring("--gc-sections")); + } + + fn optimize(&mut self) { + // TODO + } + + fn debuginfo(&mut self) { + // TODO fact check this + // Don't do anything special here for GNU-style linkers. + } + + fn no_default_libraries(&mut self) { + // NOTE lld doesn't pass any library by default + } + + fn build_dylib(&mut self, _: &Path) { + // TODO + } + + fn whole_archives(&mut self) { + // TODO take_hints? + // if !self.takes_hints() { return } + self.args.push(cstring("--whole-archive")); + } + + fn no_whole_archives(&mut self) { + // TODO take_hints? + // if !self.takes_hints() { return } + self.args.push(cstring("--no-whole-archive")); + } + + fn hint_static(&mut self) { + // TODO take_hints? + // if !self.takes_hints() { return } + self.args.push(cstring("--Bstatic")); + } + + fn hint_dynamic(&mut self) { + // TODO take_hints? + // if !self.takes_hints() { return } + self.args.push(cstring("--Bdynamic")); + } + + fn export_symbols(&mut self, _: &Path, _: CrateType) { + // TODO + } +} + pub struct GnuLinker<'a> { cmd: &'a mut Command, sess: &'a Session, diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 3e60369acbff3..1fa8a6eca2489 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -50,6 +50,8 @@ extern crate rustc_back; extern crate rustc_data_structures; extern crate rustc_incremental; pub extern crate rustc_llvm as llvm; +#[cfg(feature = "lld")] +pub extern crate rustc_lld as lld; extern crate rustc_platform_intrinsics as intrinsics; extern crate serialize; extern crate rustc_const_math; diff --git a/src/lld b/src/lld new file mode 160000 index 0000000000000..2fd49cfe85028 --- /dev/null +++ b/src/lld @@ -0,0 +1 @@ +Subproject commit 2fd49cfe85028e35870563269adbd553e0ad1691 diff --git a/src/rustc/Cargo.lock b/src/rustc/Cargo.lock index 3377fc43d8a60..acd4db5096f0d 100644 --- a/src/rustc/Cargo.lock +++ b/src/rustc/Cargo.lock @@ -205,6 +205,14 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "rustc_lld" +version = "0.0.0" +dependencies = [ + "build_helper 0.1.0", + "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc_llvm" version = "0.0.0" @@ -336,6 +344,7 @@ dependencies = [ "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", "rustc_incremental 0.0.0", + "rustc_lld 0.0.0", "rustc_llvm 0.0.0", "rustc_platform_intrinsics 0.0.0", "serialize 0.0.0", diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index 24499cb8f08c2..88857a3520262 100644 --- a/src/rustc/Cargo.toml +++ b/src/rustc/Cargo.toml @@ -31,3 +31,4 @@ rustdoc = { path = "../librustdoc" } [features] jemalloc = ["rustc_back/jemalloc"] +lld = ["rustc_driver/lld"] diff --git a/src/rustlld/RustWrapper.cpp b/src/rustlld/RustWrapper.cpp new file mode 100644 index 0000000000000..4b49e1ed845c2 --- /dev/null +++ b/src/rustlld/RustWrapper.cpp @@ -0,0 +1,26 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//===----------------------------------------------------------------------=== +// +// This file defines alternate interfaces to core functions that are more +// readily callable by Rust's FFI. +// +//===----------------------------------------------------------------------=== + +#include "llvm/ADT/ArrayRef.h" + +#include "lld/Driver/Driver.h" + +using namespace llvm; + +extern "C" bool LldRustElfLink(const char* Args[], unsigned NumArgs) { + return lld::elf::link(makeArrayRef(Args, NumArgs)); +} diff --git a/src/test/run-make/lld/Makefile b/src/test/run-make/lld/Makefile new file mode 100644 index 0000000000000..414a27ecea706 --- /dev/null +++ b/src/test/run-make/lld/Makefile @@ -0,0 +1,10 @@ +# Test that we can link, using the embedded lld, a "bare-metal" executable for a foreign +# architecture (ARM Cortex M, in this case) without relying on a external linker (like +# arm-none-eabi-gcc) or external C stuff (libraries or startup objects). + +# TODO this test should be skipped when lld support has not been built into rustc + +-include ../tools.mk + +all: + $(RUSTC) --target cortex-m3 -Z print-link-args -Z use-lld bare.rs diff --git a/src/test/run-make/lld/bare.rs b/src/test/run-make/lld/bare.rs new file mode 100644 index 0000000000000..777684b43a81e --- /dev/null +++ b/src/test/run-make/lld/bare.rs @@ -0,0 +1,34 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(asm)] +#![feature(lang_items)] +#![feature(no_core)] +#![no_core] +#![no_main] + +#[no_mangle] +pub fn _start() -> ! { + unsafe { + asm!("bkpt"); + } + + loop {} +} + +#[allow(private_no_mangle_fns)] +#[no_mangle] +fn __aeabi_unwind_cpp_pr0() {} + +#[lang = "copy"] +trait Copy {} + +#[lang = "sized"] +trait Sized {} diff --git a/src/test/run-make/lld/cortex-m3.json b/src/test/run-make/lld/cortex-m3.json new file mode 100644 index 0000000000000..355c5fe53dfce --- /dev/null +++ b/src/test/run-make/lld/cortex-m3.json @@ -0,0 +1,11 @@ +{ + "arch": "arm", + "cpu": "cortex-m3", + "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", + "executables": true, + "llvm-target": "thumbv7m-none-eabi", + "no-compiler-rt": true, + "os": "none", + "target-endian": "little", + "target-pointer-width": "32" +} diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 2839bbded1a5f..70f26d0e0a6c1 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -61,6 +61,7 @@ fn filter_dirs(path: &Path) -> bool { "src/libbacktrace", "src/compiler-rt", "src/rt/hoedown", + "src/rustlld", "src/rustllvm", "src/rust-installer", "src/liblibc", From 699454f0da04e85b2d47618eb33373d79540c6fd Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 13 Sep 2016 00:59:58 -0500 Subject: [PATCH 2/9] build lld as an external project --- src/bootstrap/native.rs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 04b159acf7300..5f7d6153102de 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -27,7 +27,7 @@ use cmake; use gcc; use Build; -use util::{cp_r, up_to_date}; +use util::up_to_date; /// Compile LLVM for `target`. pub fn llvm(build: &Build, target: &str) { @@ -75,22 +75,9 @@ pub fn llvm(build: &Build, target: &str) { .define("LLVM_ENABLE_LIBEDIT", "OFF") .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string()); - // FIXME figure out how to build lld as a external project - // if build.config.lld { - // cfg.define("LLVM_EXTERNAL_PROJECTS", "lld"); - // cfg.define("LLVM_EXTERNAL_LLD_SOURCE_DIR", "../lld"); - // } - - let src_lld = &build.src.join("src/lld"); - let src_llvm_tools_lld = &build.src.join("src/llvm/tools/lld"); - - if src_llvm_tools_lld.exists() { - fs::remove_dir_all(src_llvm_tools_lld).unwrap(); - } - if build.config.lld { - fs::create_dir(src_llvm_tools_lld).unwrap(); - cp_r(src_lld, src_llvm_tools_lld); + cfg.define("LLVM_EXTERNAL_LLD_SOURCE_DIR", build.src.join("src/lld")); + cfg.define("LLVM_EXTERNAL_PROJECTS", "lld"); } if target.starts_with("i686") { From bd326eced05732d20153ac5f89b9f372155027b8 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 13 Sep 2016 01:16:28 -0500 Subject: [PATCH 3/9] [DoNotMerge] turn on lld by default just to test this on the try bots --- configure | 2 +- src/bootstrap/config.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 3f24bf820b697..1d4b75edb4327 100755 --- a/configure +++ b/configure @@ -620,7 +620,7 @@ opt rustbuild 0 "use the rust and cargo based build system" opt codegen-tests 1 "run the src/test/codegen tests" opt option-checking 1 "complain about unrecognized options in this configure script" opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)" -opt lld 0 "Build and embed lld, the LLVM linker, into rustc" +opt lld 1 "Build and embed lld, the LLVM linker, into rustc" # Optimization and debugging options. These may be overridden by the release channel, etc. opt_nosave optimize 1 "build optimized rust code" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 55a7e5757f503..17675852a3073 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -165,6 +165,7 @@ struct TomlTarget { impl Config { pub fn parse(build: &str, file: Option) -> Config { let mut config = Config::default(); + config.lld = true; config.llvm_optimize = true; config.use_jemalloc = true; config.backtrace = true; From 904efeb9ed55dece38bc265ed432d91aa7030a7f Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 13 Sep 2016 22:49:16 -0500 Subject: [PATCH 4/9] skip cargo testing rustc_lld --- src/bootstrap/check.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 2b9d717cbd48d..08b88955363b9 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -308,6 +308,11 @@ pub fn krate(build: &Build, continue } + // FIXME(maybe) rustc_lld doesn't work right now but it doesn't have any tests anyway + if crate_name.contains("rustc_lld") { + continue + } + cargo.arg("-p").arg(crate_name); } From cb39a7b448281216b239dae709df06777603df5e Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 14 Sep 2016 00:16:41 -0500 Subject: [PATCH 5/9] use llvm-config components instead of directly using -l flags --- src/librustc_driver/Cargo.toml | 2 +- src/librustc_lld/build.rs | 33 ++++++++++++++++++++++----------- src/librustc_llvm/Cargo.toml | 1 + src/librustc_llvm/build.rs | 22 +++++++++++++--------- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 507dc5ff67316..057c521c2a632 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -37,4 +37,4 @@ syntax_pos = { path = "../libsyntax_pos" } proc_macro = { path = "../libproc_macro" } [features] -lld = ["rustc_trans/lld"] +lld = ["rustc_llvm/lld", "rustc_trans/lld"] diff --git a/src/librustc_lld/build.rs b/src/librustc_lld/build.rs index cd1d64f11ce26..54b01a03f7756 100644 --- a/src/librustc_lld/build.rs +++ b/src/librustc_lld/build.rs @@ -17,6 +17,9 @@ use std::process::Command; use build_helper::output; +// NOTE This pretty much looks the same as librustc_llvm build.rs. Refer to that file for an +// explanation of what this function does. + fn main() { let target = env::var("TARGET").unwrap(); let host = env::var("HOST").unwrap(); @@ -40,6 +43,8 @@ fn main() { PathBuf::from("llvm-config") }); + println!("cargo:rerun-if-changed={}", llvm_config.display()); + let mut cmd = Command::new(&llvm_config); cmd.arg("--cxxflags"); let cxxflags = output(&mut cmd); @@ -58,10 +63,6 @@ fn main() { .cpp_link_stdlib(None) .compile("librustlld.a"); - // If we're a cross-compile of LLVM then unfortunately we can't trust these - // ldflags (largely where all the LLVM libs are located). Currently just - // hack around this by replacing the host triple with the target and pray - // that those -L directories are the same! let mut cmd = Command::new(&llvm_config); cmd.arg("--ldflags"); for lib in output(&mut cmd).split_whitespace() { @@ -79,7 +80,6 @@ fn main() { } } - // C++ runtime library if !target.contains("msvc") { if let Some(s) = env::var_os("LLVM_STATIC_STDCPP") { assert!(!cxxflags.contains("stdlib=libc++")); @@ -94,11 +94,22 @@ fn main() { } } - // FIXME can we get these from llvm-config? - println!("cargo:rustc-link-lib=static=lldELF"); + // NOTE After this point comes LLD specific stuff + // + // We need to link to these libraries to be able to use lld functions via ffi + // These libraries depend on llvm libraries but we don't link this crate to those libraries + // because that can result in duplicate linking to static libraries, instead rustc_llvm will + // link to those libraries for us. + // + // To elaborate on this last point: which libraries we must link to come from the output of + // llvm-config. llvm-config maps "components" to -l flags. rustc_llvm is already using this + // method to figure out which -l flags we need to use llvm via ffi. If we do the same thing here + // we risk ending up static llvm libraries being linked up more than once in the final rustc + // binary -- and this last part can cause runtime failures of rustc like + // + // : CommandLine Error: Option 'color' registered more than once! + // LLVM ERROR: inconsistency in registered CommandLine options + // println!("cargo:rustc-link-lib=static=lldConfig"); - println!("cargo:rustc-link-lib=static=LLVMOption"); - println!("cargo:rustc-link-lib=static=LLVMPasses"); - println!("cargo:rustc-link-lib=static=LLVMLTO"); - println!("cargo:rustc-link-lib=static=LLVMObjCARCOpts"); + println!("cargo:rustc-link-lib=static=lldELF"); } diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index f97daa22ff662..5aaa32bb5d180 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -10,6 +10,7 @@ path = "lib.rs" crate-type = ["dylib"] [features] +lld = [] static-libstdcpp = [] [dependencies] diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index ac83d860b6e90..5fa5d3a55c090 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -70,20 +70,24 @@ fn main() { // FIXME: surely we don't need all these components, right? Stuff like mcjit // or interpreter the compiler itself never uses. - let required_components = &["ipo", - "bitreader", - "bitwriter", - "linker", - "asmparser", - "mcjit", - "interpreter", - "instrumentation"]; + let mut required_components = vec!["ipo", + "bitreader", + "bitwriter", + "linker", + "asmparser", + "mcjit", + "interpreter", + "instrumentation"]; + + if env::var_os("CARGO_FEATURE_LLD").is_some() { + required_components.extend(&["lto", "option", "passes"]); + } let components = output(Command::new(&llvm_config).arg("--components")); let mut components = components.split_whitespace().collect::>(); components.retain(|c| optional_components.contains(c) || required_components.contains(c)); - for component in required_components { + for component in &required_components { if !components.contains(component) { panic!("require llvm component {} but wasn't found", component); } From fa76b18143ecf28cb285171fb5f7e6bf2d293351 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 13 Sep 2016 22:23:30 -0500 Subject: [PATCH 6/9] lld-up should fix build on windows-gnu --- src/lld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lld b/src/lld index 2fd49cfe85028..9fc6ba504f93f 160000 --- a/src/lld +++ b/src/lld @@ -1 +1 @@ -Subproject commit 2fd49cfe85028e35870563269adbd553e0ad1691 +Subproject commit 9fc6ba504f93f99c8d67e3d50971c91d9f33f74d From fa0a31d884a4735288ea914be01e26e5f51a3af6 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 15 Sep 2016 12:43:00 -0500 Subject: [PATCH 7/9] link rustc_lld against rustc_llvm should hopefully fix linking the rustc_lld dylib on osx --- src/librustc_lld/Cargo.toml | 3 +++ src/librustc_lld/lib.rs | 4 ++++ src/rustc/Cargo.lock | 1 + 3 files changed, 8 insertions(+) diff --git a/src/librustc_lld/Cargo.toml b/src/librustc_lld/Cargo.toml index 1b62eebdd3fa3..88e23a0dcfe22 100644 --- a/src/librustc_lld/Cargo.toml +++ b/src/librustc_lld/Cargo.toml @@ -12,3 +12,6 @@ crate-type = ["dylib"] [build-dependencies] build_helper = { path = "../build_helper" } gcc = "0.3.27" + +[dependencies] +rustc_llvm = { path = "../librustc_llvm" } diff --git a/src/librustc_lld/lib.rs b/src/librustc_lld/lib.rs index 2152ee705c888..bf1ad583b4b63 100644 --- a/src/librustc_lld/lib.rs +++ b/src/librustc_lld/lib.rs @@ -9,5 +9,9 @@ // except according to those terms. #![feature(linked_from)] +#![feature(rustc_private)] + +// NOTE Used to "inherit" the static llvm libraries that rustc_llvm links to +extern crate rustc_llvm; pub mod ffi; diff --git a/src/rustc/Cargo.lock b/src/rustc/Cargo.lock index acd4db5096f0d..556d2e371b786 100644 --- a/src/rustc/Cargo.lock +++ b/src/rustc/Cargo.lock @@ -211,6 +211,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_llvm 0.0.0", ] [[package]] From 86c837770e96b8cd9c62bdfb26cb1cbb494f6b3c Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 15 Sep 2016 16:06:38 -0500 Subject: [PATCH 8/9] some tidy fixes --- src/librustc_lld/src/lib.rs | 0 src/tools/tidy/src/main.rs | 1 + 2 files changed, 1 insertion(+) delete mode 100644 src/librustc_lld/src/lib.rs diff --git a/src/librustc_lld/src/lib.rs b/src/librustc_lld/src/lib.rs deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 70f26d0e0a6c1..a4a6927dd20d1 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -57,6 +57,7 @@ fn main() { fn filter_dirs(path: &Path) -> bool { let skip = [ "src/jemalloc", + "src/lld", "src/llvm", "src/libbacktrace", "src/compiler-rt", From a4620cc466f391504b26d4cfc91c8b09f893cabc Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 15 Sep 2016 16:10:51 -0500 Subject: [PATCH 9/9] [RFC] temporarily disable -pie support --- src/librustc_trans/back/linker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index e24088f999f73..e2cb456238068 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -170,7 +170,7 @@ impl Linker for LldLinker { } fn position_independent_executable(&mut self) { - self.args.push(cstring("--pie")); + // TODO --pie support disabled. Raise a warning } fn args(&mut self, args: &[String]) {