rustc/debian/patches-unused/u-allow-system-compiler-rt.patch
Fabian Grünbichler fa6ca259c4 switch to gbp pq and topics for patches
instead of a mix of git and quilt patches

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-06-14 14:50:14 +02:00

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();