From 12bc8434ec1eddb3103a8ad37d88fae57d81bbc3 Mon Sep 17 00:00:00 2001 From: "Kirill A. Korinsky" Date: Mon, 13 Dec 2021 13:37:12 +0100 Subject: [PATCH] Introduce `RUSTC_STATIC_CLANG_RT_PATH` and `RUSTC_STATIC_UNWIND_PATH` envs The goal of this envirements variable is easy statically link `libclang_rt` or `libunwind` into rust. It also introduces a way to easy extend rust build in a way which allows to inject more static builds for some rare system if it required. It haven't been documented because it seems as very deep hack and the user who needs it will discover this hack by reading sources ;) --- Cargo.lock | 2 ++ compiler/rustc_llvm/build.rs | 4 +++- library/std/Cargo.toml | 3 +++ library/std/build.rs | 4 ++++ library/unwind/Cargo.toml | 1 + library/unwind/build.rs | 6 ++++++ src/build_helper/lib.rs | 22 ++++++++++++++++++++++ 7 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 3cee22dedee72..978cc25f96b72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4995,6 +4995,7 @@ version = "0.0.0" dependencies = [ "addr2line", "alloc", + "build_helper", "cfg-if 0.1.10", "compiler_builtins", "core", @@ -5662,6 +5663,7 @@ dependencies = [ name = "unwind" version = "0.0.0" dependencies = [ + "build_helper", "cc", "cfg-if 0.1.10", "compiler_builtins", diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 3b6808d693f21..838567663b51e 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -2,7 +2,7 @@ use std::env; use std::path::{Path, PathBuf}; use std::process::Command; -use build_helper::{output, tracked_env_var_os}; +use build_helper::{maybe_static_library, output, tracked_env_var_os}; fn detect_llvm_link() -> (&'static str, &'static str) { // Force the link mode we want, preferring static by default, but @@ -307,4 +307,6 @@ fn main() { if target.contains("windows-gnu") { println!("cargo:rustc-link-lib=static:-bundle=pthread"); } + + maybe_static_library("RUSTC_STATIC_CLANG_RT_PATH", "clang_rt"); } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f711174832142..e3ed5e85c4091 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -84,3 +84,6 @@ heap_size = 0x8000000 name = "stdbenches" path = "benches/lib.rs" test = true + +[build-dependencies] +build_helper = { path = "../../src/build_helper" } diff --git a/library/std/build.rs b/library/std/build.rs index 43168e77296ab..d8edd77232e68 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -1,5 +1,7 @@ use std::env; +use build_helper::maybe_static_library; + fn main() { println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").expect("TARGET was not set"); @@ -47,4 +49,6 @@ fn main() { } println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap()); println!("cargo:rustc-cfg=backtrace_in_libstd"); + + maybe_static_library("RUSTC_STATIC_CLANG_RT_PATH", "clang_rt"); } diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 1941f2b5a0026..310dd2584f204 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -20,6 +20,7 @@ compiler_builtins = "0.1.0" cfg-if = "0.1.8" [build-dependencies] +build_helper = { path = "../../src/build_helper" } cc = "1.0.69" [features] diff --git a/library/unwind/build.rs b/library/unwind/build.rs index a3f5224151d94..931f7c53ed588 100644 --- a/library/unwind/build.rs +++ b/library/unwind/build.rs @@ -1,9 +1,15 @@ use std::env; +use build_helper::maybe_static_library; + fn main() { println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").expect("TARGET was not set"); + if maybe_static_library("RUSTC_STATIC_UNWIND_PATH", "unwind") { + return; + } + if target.contains("android") { let build = cc::Build::new(); diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index b1ec072f3f8aa..adf3489c2c3a2 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -203,3 +203,25 @@ fn fail(s: &str) -> ! { println!("\n\n{}\n\n", s); std::process::exit(1); } + +/// if you need for some reason to statically inject some library, like clang_rt +/// here a good place. Anyway, you should use only thin .a file on macOS. +/// You may extract it like: +/// lipo -thin x86_64 -output libclang_rt.a /path/to/llvm/lib/../libclang_rt.osx.a +/// +/// It returns true, when it had injected static library. +pub fn maybe_static_library(env_path_name: &str, library_name: &str) -> bool { + println!("cargo:rerun-if-env-changed={}", env_path_name); + + if let Ok(path) = env::var(env_path_name) { + let target = env::var("TARGET").expect("TARGET was not set"); + println!("cargo:rerun-if-env-changed=TARGET"); + + println!("cargo:rustc-link-search=native={}", path); + println!("cargo:rustc-link-search=native={}/{}", path, target); + println!("cargo:rustc-link-lib=static={}", library_name); + return true; + } + + return false; +}