summaryrefslogtreecommitdiffstats
path: root/debian/patches/u-allow-system-compiler-rt.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/u-allow-system-compiler-rt.patch')
-rw-r--r--debian/patches/u-allow-system-compiler-rt.patch327
1 files changed, 327 insertions, 0 deletions
diff --git a/debian/patches/u-allow-system-compiler-rt.patch b/debian/patches/u-allow-system-compiler-rt.patch
new file mode 100644
index 000000000..3bd874a5c
--- /dev/null
+++ b/debian/patches/u-allow-system-compiler-rt.patch
@@ -0,0 +1,327 @@
+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();
+