Skip to content
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

Strip unexpected debuginfo from libLLVM.so and librustc_driver.so when not requesting any debuginfo #114305

Merged
merged 5 commits into from
Aug 4, 2023
Merged
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
25 changes: 23 additions & 2 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::builder::crate_description;
use crate::builder::Cargo;
use crate::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath};
use crate::cache::{Interned, INTERNER};
use crate::config::{LlvmLibunwind, RustcLto, TargetSelection};
use crate::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection};
use crate::dist;
use crate::llvm;
use crate::tool::SourceType;
Expand Down Expand Up @@ -883,16 +883,37 @@ impl Step for Rustc {
compiler.host,
target,
);
let stamp = librustc_stamp(builder, compiler, target);
run_cargo(
builder,
cargo,
vec![],
&librustc_stamp(builder, compiler, target),
&stamp,
vec![],
false,
true, // Only ship rustc_driver.so and .rmeta files, not all intermediate .rlib files.
);

// When building `librustc_driver.so` (like `libLLVM.so`) on linux, it can contain
// unexpected debuginfo from dependencies, for example from the C++ standard library used in
// our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with
// debuginfo (via the debuginfo level of the executables using it): strip this debuginfo
// away after the fact.
// FIXME: to make things simpler for now, limit this to the host and target where we know
// `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
// cross-compiling. Expand this to other appropriate targets in the future.
if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None
&& builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None
&& target == "x86_64-unknown-linux-gnu"
&& target == builder.config.build
{
let target_root_dir = stamp.parent().unwrap();
let rustc_driver = target_root_dir.join("librustc_driver.so");
if rustc_driver.exists() {
output(Command::new("strip").arg("--strip-debug").arg(rustc_driver));
}
}

builder.ensure(RustcLink::from_rustc(
self,
builder.compiler(compiler.stage, builder.config.build),
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub enum DryRun {
UserSelected,
}

#[derive(Copy, Clone, Default)]
#[derive(Copy, Clone, Default, PartialEq, Eq)]
pub enum DebuginfoLevel {
#[default]
None,
Expand Down
47 changes: 39 additions & 8 deletions src/bootstrap/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,25 +491,56 @@ 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 unexpected debuginfo:
// some can come from the C++ standard library. Unless we're explicitly requesting LLVM to
// be built with debuginfo, strip it away after the fact, to make dist artifacts smaller.
// FIXME: to make things simpler for now, limit this to the host and target where we know
// `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
// cross-compiling. Expand this to other appropriate targets in the future.
if builder.llvm_link_shared()
&& builder.config.llvm_optimize
&& !builder.config.llvm_release_debuginfo
&& target == "x86_64-unknown-linux-gnu"
&& target == builder.config.build
{
// 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() {
output(Command::new("strip").arg("--strip-debug").arg(path));
}
};
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