mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-16 14:40:37 +00:00

instead of a mix of git and quilt patches Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
328 lines
12 KiB
Diff
328 lines
12 KiB
Diff
Description: Support linking against system clang libs
|
|
Note: the above PR only covers the compiler_builtins crate, rustc itself also
|
|
needs patching as per below once that is accepted.
|
|
Forwarded: https://github.com/rust-lang-nursery/compiler-builtins/pull/296
|
|
--- a/vendor/compiler_builtins/Cargo.toml
|
|
+++ b/vendor/compiler_builtins/Cargo.toml
|
|
@@ -43,7 +43,13 @@
|
|
optional = true
|
|
|
|
[features]
|
|
-c = ["cc"]
|
|
+c-vendor = ["cc"]
|
|
+
|
|
+# Link against system clang_rt.* libraries.
|
|
+# LLVM_CONFIG or CLANG (more reliable) must be set.
|
|
+c-system = []
|
|
+
|
|
+c = ["c-vendor"]
|
|
compiler-builtins = []
|
|
default = ["compiler-builtins"]
|
|
mangled-names = []
|
|
--- a/vendor/compiler_builtins/build.rs
|
|
+++ b/vendor/compiler_builtins/build.rs
|
|
@@ -37,7 +37,7 @@
|
|
// mangling names though we assume that we're also in test mode so we don't
|
|
// build anything and we rely on the upstream implementation of compiler-rt
|
|
// functions
|
|
- if !cfg!(feature = "mangled-names") && cfg!(feature = "c") {
|
|
+ if !cfg!(feature = "mangled-names") && cfg!(any(feature = "c-vendor", feature = "c-system")) {
|
|
// Don't use a C compiler for these targets:
|
|
//
|
|
// * wasm32 - clang 8 for wasm is somewhat hard to come by and it's
|
|
@@ -47,8 +47,10 @@
|
|
// compiler nor is cc-rs ready for compilation to riscv (at this
|
|
// time). This can probably be removed in the future
|
|
if !target.contains("wasm32") && !target.contains("nvptx") && !target.starts_with("riscv") {
|
|
- #[cfg(feature = "c")]
|
|
- c::compile(&llvm_target);
|
|
+ #[cfg(feature = "c-vendor")]
|
|
+ c_vendor::compile(&llvm_target);
|
|
+ #[cfg(feature = "c-system")]
|
|
+ c_system::compile(&llvm_target);
|
|
}
|
|
}
|
|
|
|
@@ -70,17 +72,14 @@
|
|
}
|
|
}
|
|
|
|
-#[cfg(feature = "c")]
|
|
-mod c {
|
|
- extern crate cc;
|
|
-
|
|
+#[cfg(any(feature = "c-vendor", feature = "c-system"))]
|
|
+mod sources {
|
|
use std::collections::BTreeMap;
|
|
use std::env;
|
|
- use std::path::PathBuf;
|
|
|
|
- struct Sources {
|
|
+ pub struct Sources {
|
|
// SYMBOL -> PATH TO SOURCE
|
|
- map: BTreeMap<&'static str, &'static str>,
|
|
+ pub map: BTreeMap<&'static str, &'static str>,
|
|
}
|
|
|
|
impl Sources {
|
|
@@ -117,39 +116,11 @@
|
|
}
|
|
}
|
|
|
|
- /// Compile intrinsics from the compiler-rt C source code
|
|
- pub fn compile(llvm_target: &[&str]) {
|
|
+ pub fn get_sources(llvm_target: &[&str]) -> Sources {
|
|
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
|
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
|
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
|
let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
|
|
- let cfg = &mut cc::Build::new();
|
|
-
|
|
- cfg.warnings(false);
|
|
-
|
|
- if target_env == "msvc" {
|
|
- // Don't pull in extra libraries on MSVC
|
|
- cfg.flag("/Zl");
|
|
-
|
|
- // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
|
|
- cfg.define("__func__", Some("__FUNCTION__"));
|
|
- } else {
|
|
- // Turn off various features of gcc and such, mostly copying
|
|
- // compiler-rt's build system already
|
|
- cfg.flag("-fno-builtin");
|
|
- cfg.flag("-fvisibility=hidden");
|
|
- cfg.flag("-ffreestanding");
|
|
- // Avoid the following warning appearing once **per file**:
|
|
- // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument]
|
|
- //
|
|
- // Note that compiler-rt's build system also checks
|
|
- //
|
|
- // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)`
|
|
- //
|
|
- // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19.
|
|
- cfg.flag_if_supported("-fomit-frame-pointer");
|
|
- cfg.define("VISIBILITY_HIDDEN", None);
|
|
- }
|
|
|
|
let mut sources = Sources::new();
|
|
sources.extend(&[
|
|
@@ -411,6 +382,48 @@
|
|
sources.remove(&["__aeabi_cdcmp", "__aeabi_cfcmp"]);
|
|
}
|
|
|
|
+ sources
|
|
+ }
|
|
+}
|
|
+
|
|
+#[cfg(feature = "c-vendor")]
|
|
+mod c_vendor {
|
|
+ extern crate cc;
|
|
+
|
|
+ use std::env;
|
|
+ use std::path::PathBuf;
|
|
+ use sources;
|
|
+
|
|
+ /// Compile intrinsics from the compiler-rt C source code
|
|
+ pub fn compile(llvm_target: &[&str]) {
|
|
+ let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
|
|
+ let cfg = &mut cc::Build::new();
|
|
+ cfg.warnings(false);
|
|
+
|
|
+ if target_env == "msvc" {
|
|
+ // Don't pull in extra libraries on MSVC
|
|
+ cfg.flag("/Zl");
|
|
+
|
|
+ // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
|
|
+ cfg.define("__func__", Some("__FUNCTION__"));
|
|
+ } else {
|
|
+ // Turn off various features of gcc and such, mostly copying
|
|
+ // compiler-rt's build system already
|
|
+ cfg.flag("-fno-builtin");
|
|
+ cfg.flag("-fvisibility=hidden");
|
|
+ cfg.flag("-ffreestanding");
|
|
+ // Avoid the following warning appearing once **per file**:
|
|
+ // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument]
|
|
+ //
|
|
+ // Note that compiler-rt's build system also checks
|
|
+ //
|
|
+ // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)`
|
|
+ //
|
|
+ // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19.
|
|
+ cfg.flag_if_supported("-fomit-frame-pointer");
|
|
+ cfg.define("VISIBILITY_HIDDEN", None);
|
|
+ }
|
|
+
|
|
// When compiling the C code we require the user to tell us where the
|
|
// source code is, and this is largely done so when we're compiling as
|
|
// part of rust-lang/rust we can use the same llvm-project repository as
|
|
@@ -423,6 +436,7 @@
|
|
panic!("RUST_COMPILER_RT_ROOT={} does not exist", root.display());
|
|
}
|
|
|
|
+ let sources = sources::get_sources(llvm_target);
|
|
let src_dir = root.join("lib/builtins");
|
|
for (sym, src) in sources.map.iter() {
|
|
let src = src_dir.join(src);
|
|
@@ -434,3 +448,103 @@
|
|
cfg.compile("libcompiler-rt.a");
|
|
}
|
|
}
|
|
+
|
|
+#[cfg(feature = "c-system")]
|
|
+mod c_system {
|
|
+ use std::env;
|
|
+ use std::process::{Command, Output};
|
|
+ use std::str;
|
|
+ use std::path::Path;
|
|
+ use sources;
|
|
+
|
|
+ fn success_output(err: &str, cmd: &mut Command) -> Output {
|
|
+ let output = cmd.output().expect(err);
|
|
+ let status = output.status;
|
|
+ if !status.success() {
|
|
+ panic!("{}: {:?}", err, status.code());
|
|
+ }
|
|
+ output
|
|
+ }
|
|
+
|
|
+ // This can be obtained by adding the line:
|
|
+ // message(STATUS "All builtin supported architectures: ${ALL_BUILTIN_SUPPORTED_ARCH}")
|
|
+ // to the bottom of compiler-rt/cmake/builtin-config-ix.cmake, then running
|
|
+ // cmake and looking at the output.
|
|
+ const ALL_SUPPORTED_ARCHES : &'static str = "i386;x86_64;arm;armhf;armv6m;armv7m;armv7em;armv7;armv7s;armv7k;aarch64;hexagon;mips;mipsel;mips64;mips64el;powerpc64;powerpc64le;riscv32;riscv64;wasm32;wasm64";
|
|
+
|
|
+ // This function recreates the logic of getArchNameForCompilerRTLib,
|
|
+ // defined in clang/lib/Driver/ToolChain.cpp.
|
|
+ fn get_arch_name_for_compiler_rtlib() -> String {
|
|
+ let target = env::var("TARGET").unwrap();
|
|
+ let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
|
+ let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
|
+ let r = match target_arch.as_str() {
|
|
+ "arm" => if target.ends_with("eabihf") && target_os != "windows" {
|
|
+ "armhf"
|
|
+ } else {
|
|
+ "arm"
|
|
+ },
|
|
+ "x86" => if target_os == "android" {
|
|
+ "i686"
|
|
+ } else {
|
|
+ "i386"
|
|
+ },
|
|
+ _ => target_arch.as_str(),
|
|
+ };
|
|
+ r.to_string()
|
|
+ }
|
|
+
|
|
+ /// Link against system clang runtime libraries
|
|
+ pub fn compile(llvm_target: &[&str]) {
|
|
+ let target = env::var("TARGET").unwrap();
|
|
+ let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
|
+ let compiler_rt_arch = get_arch_name_for_compiler_rtlib();
|
|
+
|
|
+ if ALL_SUPPORTED_ARCHES.split(";").find(|x| *x == compiler_rt_arch) == None {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if let Ok(clang) = env::var("CLANG") {
|
|
+ let output = success_output(
|
|
+ "failed to find clang's compiler-rt",
|
|
+ Command::new(clang)
|
|
+ .arg(format!("--target={}", target))
|
|
+ .arg("--rtlib=compiler-rt")
|
|
+ .arg("--print-libgcc-file-name"),
|
|
+ );
|
|
+ let fullpath = Path::new(str::from_utf8(&output.stdout).unwrap());
|
|
+ let libpath = fullpath.parent().unwrap().display();
|
|
+ let libname = fullpath
|
|
+ .file_stem()
|
|
+ .unwrap()
|
|
+ .to_str()
|
|
+ .unwrap()
|
|
+ .trim_start_matches("lib");
|
|
+ println!("cargo:rustc-link-search=native={}", libpath);
|
|
+ println!("cargo:rustc-link-lib=static={}", libname);
|
|
+ } else if let Ok(llvm_config) = env::var("LLVM_CONFIG") {
|
|
+ // fallback if clang is not installed
|
|
+ let (subpath, libname) = match target_os.as_str() {
|
|
+ "linux" => ("linux", format!("clang_rt.builtins-{}", &compiler_rt_arch)),
|
|
+ "macos" => ("darwin", "clang_rt.builtins_osx_dynamic".to_string()),
|
|
+ _ => panic!("unsupported target os: {}", target_os),
|
|
+ };
|
|
+ let cmd = format!("ls -1d $({} --libdir)/clang/*/lib/{}", llvm_config, subpath);
|
|
+ let output = success_output(
|
|
+ "failed to find clang's lib dir",
|
|
+ Command::new("sh").args(&["-ec", &cmd]),
|
|
+ );
|
|
+ for search_dir in str::from_utf8(&output.stdout).unwrap().lines() {
|
|
+ println!("cargo:rustc-link-search=native={}", search_dir);
|
|
+ }
|
|
+ println!("cargo:rustc-link-lib=static={}", libname);
|
|
+ } else {
|
|
+ panic!("neither CLANG nor LLVM_CONFIG could be read");
|
|
+ }
|
|
+
|
|
+ let sources = sources::get_sources(llvm_target);
|
|
+ for (sym, _src) in sources.map.iter() {
|
|
+ println!("cargo:rustc-cfg={}=\"optimized-c\"", sym);
|
|
+ }
|
|
+ }
|
|
+}
|
|
--- a/src/bootstrap/compile.rs
|
|
+++ b/src/bootstrap/compile.rs
|
|
@@ -213,6 +213,7 @@
|
|
emscripten: false,
|
|
});
|
|
cargo.env("LLVM_CONFIG", llvm_config);
|
|
+ cargo.env("RUSTC_BUILD_SANITIZERS", "1");
|
|
}
|
|
|
|
cargo.arg("--features").arg(features)
|
|
--- a/src/librustc_asan/build.rs
|
|
+++ b/src/librustc_asan/build.rs
|
|
@@ -4,6 +4,9 @@
|
|
use cmake::Config;
|
|
|
|
fn main() {
|
|
+ if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
|
|
+ return;
|
|
+ }
|
|
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
|
|
build_helper::restore_library_path();
|
|
|
|
--- a/src/librustc_lsan/build.rs
|
|
+++ b/src/librustc_lsan/build.rs
|
|
@@ -4,6 +4,9 @@
|
|
use cmake::Config;
|
|
|
|
fn main() {
|
|
+ if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
|
|
+ return;
|
|
+ }
|
|
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
|
|
build_helper::restore_library_path();
|
|
|
|
--- a/src/librustc_msan/build.rs
|
|
+++ b/src/librustc_msan/build.rs
|
|
@@ -4,6 +4,9 @@
|
|
use cmake::Config;
|
|
|
|
fn main() {
|
|
+ if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
|
|
+ return;
|
|
+ }
|
|
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
|
|
build_helper::restore_library_path();
|
|
|
|
--- a/src/librustc_tsan/build.rs
|
|
+++ b/src/librustc_tsan/build.rs
|
|
@@ -4,6 +4,9 @@
|
|
use cmake::Config;
|
|
|
|
fn main() {
|
|
+ if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
|
|
+ return;
|
|
+ }
|
|
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
|
|
build_helper::restore_library_path();
|
|
|