Auto merge of #71825 - contrun:cg-option-strip, r=petrochenkov

add codegen option strip

closes https://github.com/rust-lang/rust/issues/71757

I don't know if the flags added here works for all linkers. I only tested on my Linux pc. I also don't know what is the best for emlinker, PtxLinker, MsvcLinker. The option for WasmLd is copied from https://aransentin.github.io/cwasm/.
This commit is contained in:
bors 2020-05-10 20:48:40 +00:00
commit aeb473803d
5 changed files with 80 additions and 37 deletions

View File

@ -1500,8 +1500,8 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
cmd.optimize();
// OBJECT-FILES-NO, AUDIT-ORDER
// Pass debuginfo flags down to the linker.
cmd.debuginfo();
// Pass debuginfo and strip flags down to the linker.
cmd.debuginfo(sess.opts.debugging_opts.strip);
// OBJECT-FILES-NO, AUDIT-ORDER
// We want to prevent the compiler from accidentally leaking in any system libraries,

View File

@ -14,7 +14,7 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::ty::TyCtxt;
use rustc_serialize::{json, Encoder};
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel};
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::spec::{LinkerFlavor, LldFlavor};
@ -122,7 +122,7 @@ pub trait Linker {
fn optimize(&mut self);
fn pgo_gen(&mut self);
fn control_flow_guard(&mut self);
fn debuginfo(&mut self);
fn debuginfo(&mut self, strip: Strip);
fn no_default_libraries(&mut self);
fn build_dylib(&mut self, out_filename: &Path);
fn build_static_executable(&mut self);
@ -392,15 +392,16 @@ impl<'a> Linker for GccLinker<'a> {
self.sess.warn("Windows Control Flow Guard is not supported by this linker.");
}
fn debuginfo(&mut self) {
if let DebugInfo::None = self.sess.opts.debuginfo {
// If we are building without debuginfo enabled and we were called with
// `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
// found when linking to get rid of symbols from libstd.
if self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
self.linker_arg("-S");
fn debuginfo(&mut self, strip: Strip) {
match strip {
Strip::None => {}
Strip::Debuginfo => {
self.linker_arg("--strip-debug");
}
};
Strip::Symbols => {
self.linker_arg("--strip-all");
}
}
}
fn no_default_libraries(&mut self) {
@ -686,29 +687,37 @@ impl<'a> Linker for MsvcLinker<'a> {
self.cmd.arg("/guard:cf");
}
fn debuginfo(&mut self) {
// This will cause the Microsoft linker to generate a PDB file
// from the CodeView line tables in the object files.
self.cmd.arg("/DEBUG");
fn debuginfo(&mut self, strip: Strip) {
match strip {
Strip::None => {
// This will cause the Microsoft linker to generate a PDB file
// from the CodeView line tables in the object files.
self.cmd.arg("/DEBUG");
// This will cause the Microsoft linker to embed .natvis info into the PDB file
let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
for entry in natvis_dir {
match entry {
Ok(entry) => {
let path = entry.path();
if path.extension() == Some("natvis".as_ref()) {
let mut arg = OsString::from("/NATVIS:");
arg.push(path);
self.cmd.arg(arg);
// This will cause the Microsoft linker to embed .natvis info into the PDB file
let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
for entry in natvis_dir {
match entry {
Ok(entry) => {
let path = entry.path();
if path.extension() == Some("natvis".as_ref()) {
let mut arg = OsString::from("/NATVIS:");
arg.push(path);
self.cmd.arg(arg);
}
}
Err(err) => {
self.sess
.warn(&format!("error enumerating natvis directory: {}", err));
}
}
}
Err(err) => {
self.sess.warn(&format!("error enumerating natvis directory: {}", err));
}
}
}
Strip::Debuginfo | Strip::Symbols => {
self.cmd.arg("/DEBUG:NONE");
}
}
}
@ -889,7 +898,7 @@ impl<'a> Linker for EmLinker<'a> {
self.sess.warn("Windows Control Flow Guard is not supported by this linker.");
}
fn debuginfo(&mut self) {
fn debuginfo(&mut self, _strip: Strip) {
// Preserve names or generate source maps depending on debug info
self.cmd.arg(match self.sess.opts.debuginfo {
DebugInfo::None => "-g0",
@ -1081,7 +1090,17 @@ impl<'a> Linker for WasmLd<'a> {
fn pgo_gen(&mut self) {}
fn debuginfo(&mut self) {}
fn debuginfo(&mut self, strip: Strip) {
match strip {
Strip::None => {}
Strip::Debuginfo => {
self.cmd.arg("--strip-debug");
}
Strip::Symbols => {
self.cmd.arg("--strip-all");
}
}
}
fn control_flow_guard(&mut self) {
self.sess.warn("Windows Control Flow Guard is not supported by this linker.");
@ -1184,7 +1203,7 @@ impl<'a> Linker for PtxLinker<'a> {
self.cmd.arg("-L").arg(path);
}
fn debuginfo(&mut self) {
fn debuginfo(&mut self, _strip: Strip) {
self.cmd.arg("--debug");
}

View File

@ -3,6 +3,7 @@ use crate::interface::parse_cfgspecs;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_middle::middle::cstore;
use rustc_session::config::Strip;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes};
use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
@ -500,6 +501,7 @@ fn test_debugging_options_tracking_hash() {
untracked!(self_profile, SwitchWithOptPath::Enabled(None));
untracked!(self_profile_events, Some(vec![String::new()]));
untracked!(span_free_formats, true);
untracked!(strip, Strip::None);
untracked!(terminal_width, Some(80));
untracked!(threads, 99);
untracked!(time, true);
@ -564,7 +566,6 @@ fn test_debugging_options_tracking_hash() {
tracked!(share_generics, Some(true));
tracked!(show_span, Some(String::from("abc")));
tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1));
tracked!(strip_debuginfo_if_disabled, true);
tracked!(symbol_mangling_version, SymbolManglingVersion::V0);
tracked!(teach, true);
tracked!(thinlto, Some(true));

View File

@ -69,6 +69,19 @@ impl FromStr for Sanitizer {
}
}
/// The different settings that the `-Z strip` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum Strip {
/// Do not strip at all.
None,
/// Strip debuginfo.
Debuginfo,
/// Strip all symbols.
Symbols,
}
/// The different settings that the `-Z control_flow_guard` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum CFGuard {

View File

@ -253,6 +253,7 @@ macro_rules! options {
pub const parse_sanitizer_list: &str = "comma separated list of sanitizers";
pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
pub const parse_cfguard: &str = "either `disabled`, `nochecks`, or `checks`";
pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of();
pub const parse_optimization_fuel: &str = "crate=integer";
pub const parse_unpretty: &str = "`string` or `string=string`";
@ -491,6 +492,16 @@ macro_rules! options {
}
}
fn parse_strip(slot: &mut Strip, v: Option<&str>) -> bool {
match v {
Some("none") => *slot = Strip::None,
Some("debuginfo") => *slot = Strip::Debuginfo,
Some("symbols") => *slot = Strip::Symbols,
_ => return false,
}
true
}
fn parse_cfguard(slot: &mut CFGuard, v: Option<&str>) -> bool {
match v {
Some("disabled") => *slot = CFGuard::Disabled,
@ -964,9 +975,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"exclude spans when debug-printing compiler state (default: no)"),
src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
"hash algorithm of source files in debug info (`md5`, or `sha1`)"),
strip_debuginfo_if_disabled: bool = (false, parse_bool, [TRACKED],
"tell the linker to strip debuginfo when building without debuginfo enabled \
(default: no)"),
strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
"tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy,
parse_symbol_mangling_version, [TRACKED],
"which mangling version to use for symbol names"),