Skip to content

Allow stripping debuginfo from LLVM's shared library #114259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ changelog-seen = 2
# Indicates whether an LLVM Release build should include debug info
#release-debuginfo = false

# When building LLVM as a dynamically linked library, and not explicitly
# requesting debuginfo, strips the debuginfo it could contain (most often coming
# from the C++ standard library).
#strip-debuginfo = false

# Indicates whether the LLVM assertions are enabled or not
# NOTE: When assertions are disabled, bugs in the integration between rustc and LLVM can lead to
# unsoundness (segfaults, etc.) in the rustc process itself, not just in the generated code.
Expand Down
23 changes: 23 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ pub struct Config {
pub llvm_optimize: bool,
pub llvm_thin_lto: bool,
pub llvm_release_debuginfo: bool,
pub llvm_strip_debuginfo: bool,
pub llvm_static_stdcpp: bool,
/// `None` if `llvm_from_ci` is true and we haven't yet downloaded llvm.
#[cfg(not(test))]
Expand Down Expand Up @@ -823,6 +824,7 @@ define_config! {
optimize: Option<bool> = "optimize",
thin_lto: Option<bool> = "thin-lto",
release_debuginfo: Option<bool> = "release-debuginfo",
strip_debuginfo: Option<bool> = "strip-debuginfo",
assertions: Option<bool> = "assertions",
tests: Option<bool> = "tests",
plugins: Option<bool> = "plugins",
Expand Down Expand Up @@ -1511,6 +1513,7 @@ impl Config {
config.llvm_clang = llvm.clang.unwrap_or(false);
config.llvm_enable_warnings = llvm.enable_warnings.unwrap_or(false);
config.llvm_build_config = llvm.build_config.clone().unwrap_or(Default::default());
config.llvm_strip_debuginfo = llvm.strip_debuginfo.unwrap_or(false);

let asserts = llvm_assertions.unwrap_or(false);
config.llvm_from_ci = match llvm.download_ci_llvm {
Expand Down Expand Up @@ -1552,6 +1555,7 @@ impl Config {
check_ci_llvm!(llvm.clang);
check_ci_llvm!(llvm.build_config);
check_ci_llvm!(llvm.plugins);
check_ci_llvm!(llvm.strip_debuginfo);
}

// NOTE: can never be hit when downloading from CI, since we call `check_ci_llvm!(thin_lto)` above.
Expand All @@ -1561,6 +1565,25 @@ impl Config {
// the link step) with each stage.
config.llvm_link_shared.set(Some(true));
}

// Stripping LLVM's debuginfo is only accepted when:
// - using a shared library
// - not explicitly requesting debuginfo
if config.llvm_strip_debuginfo {
if config.llvm_release_debuginfo {
panic!(
"enabling `llvm.strip-debuginfo` is incompatible \
with setting `llvm.release-debuginfo`"
);
}
let llvm_link_shared = config.llvm_link_shared.get().unwrap_or(false);
if !llvm_link_shared {
panic!(
"enabling `llvm.strip-debuginfo` is incompatible \
with statically linking LLVM"
);
}
}
} else {
config.llvm_from_ci =
config.channel == "dev" && crate::llvm::is_ci_llvm_available(&config, false);
Expand Down
44 changes: 36 additions & 8 deletions src/bootstrap/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,25 +491,53 @@ impl Step for Llvm {

cfg.build();

// When building LLVM with LLVM_LINK_LLVM_DYLIB for macOS, an unversioned
// libLLVM.dylib will be built. However, llvm-config will still look
// for a versioned path like libLLVM-14.dylib. Manually create a symbolic
// link to make llvm-config happy.
if builder.llvm_link_shared() && target.contains("apple-darwin") {
// Helper to find the name of LLVM's shared library on darwin and linux.
let find_llvm_lib_name = |extension| {
let mut cmd = Command::new(&res.llvm_config);
let version = output(cmd.arg("--version"));
let major = version.split('.').next().unwrap();
let lib_name = match llvm_version_suffix {
Some(s) => format!("libLLVM-{major}{s}.dylib"),
None => format!("libLLVM-{major}.dylib"),
let lib_name = match &llvm_version_suffix {
Some(version_suffix) => format!("libLLVM-{major}{version_suffix}.{extension}"),
None => format!("libLLVM-{major}.{extension}"),
};
lib_name
};

// When building LLVM with LLVM_LINK_LLVM_DYLIB for macOS, an unversioned
// libLLVM.dylib will be built. However, llvm-config will still look
// for a versioned path like libLLVM-14.dylib. Manually create a symbolic
// link to make llvm-config happy.
if builder.llvm_link_shared() && target.contains("apple-darwin") {
let lib_name = find_llvm_lib_name("dylib");
let lib_llvm = out_dir.join("build").join("lib").join(lib_name);
if !lib_llvm.exists() {
t!(builder.symlink_file("libLLVM.dylib", &lib_llvm));
}
}

// When building LLVM as a shared library on linux, it can contain debuginfo even when
// `llvm.release-debuginfo` is false: some debuginfo can come from the C++ standard library.
// If we're asked to do so, strip this debuginfo away.
if builder.llvm_link_shared()
&& target.contains("linux")
&& builder.config.llvm_strip_debuginfo
{
// Find the name of the LLVM shared library that we just built.
let lib_name = find_llvm_lib_name("so");

// If the shared library exists in LLVM's `/build/lib/` or `/lib/` folders, strip its
// debuginfo. Note: `output` will propagate any errors here.
let strip_if_possible = |path: PathBuf| {
if path.exists() {
let mut cmd = Command::new("strip");
cmd.arg("--strip-debug").arg(path);
output(&mut cmd);
}
};
strip_if_possible(out_dir.join("lib").join(&lib_name));
strip_if_possible(out_dir.join("build").join("lib").join(&lib_name));
}

t!(stamp.write());

res
Expand Down
1 change: 1 addition & 0 deletions src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ ENV RUST_CONFIGURE_ARGS \
--set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \
--set llvm.thin-lto=true \
--set llvm.ninja=false \
--set llvm.strip-debuginfo=true \
--set rust.jemalloc \
--set rust.use-lld=true \
--set rust.lto=thin
Expand Down