use LinkSelfContained
for -C link-self-contained
This commit is contained in:
parent
5d91c1ced4
commit
0fb80715bb
4 changed files with 91 additions and 4 deletions
|
@ -1688,7 +1688,7 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
|
||||||
/// instead of being found somewhere on the host system.
|
/// instead of being found somewhere on the host system.
|
||||||
/// We only provide such support for a very limited number of targets.
|
/// We only provide such support for a very limited number of targets.
|
||||||
fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
|
fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
|
||||||
if let Some(self_contained) = sess.opts.cg.link_self_contained {
|
if let Some(self_contained) = sess.opts.cg.link_self_contained.explicitly_set {
|
||||||
if sess.target.link_self_contained == LinkSelfContainedDefault::False {
|
if sess.target.link_self_contained == LinkSelfContainedDefault::False {
|
||||||
sess.emit_err(errors::UnsupportedLinkSelfContained);
|
sess.emit_err(errors::UnsupportedLinkSelfContained);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use rustc_session::config::rustc_optgroups;
|
||||||
use rustc_session::config::DebugInfo;
|
use rustc_session::config::DebugInfo;
|
||||||
use rustc_session::config::Input;
|
use rustc_session::config::Input;
|
||||||
use rustc_session::config::InstrumentXRay;
|
use rustc_session::config::InstrumentXRay;
|
||||||
|
use rustc_session::config::LinkSelfContained;
|
||||||
use rustc_session::config::TraitSolver;
|
use rustc_session::config::TraitSolver;
|
||||||
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
|
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
|
||||||
use rustc_session::config::{
|
use rustc_session::config::{
|
||||||
|
@ -579,7 +580,7 @@ fn test_codegen_options_tracking_hash() {
|
||||||
untracked!(incremental, Some(String::from("abc")));
|
untracked!(incremental, Some(String::from("abc")));
|
||||||
// `link_arg` is omitted because it just forwards to `link_args`.
|
// `link_arg` is omitted because it just forwards to `link_args`.
|
||||||
untracked!(link_args, vec![String::from("abc"), String::from("def")]);
|
untracked!(link_args, vec![String::from("abc"), String::from("def")]);
|
||||||
untracked!(link_self_contained, Some(true));
|
untracked!(link_self_contained, LinkSelfContained::on());
|
||||||
untracked!(linker, Some(PathBuf::from("linker")));
|
untracked!(linker, Some(PathBuf::from("linker")));
|
||||||
untracked!(linker_flavor, Some(LinkerFlavorCli::Gcc));
|
untracked!(linker_flavor, Some(LinkerFlavorCli::Gcc));
|
||||||
untracked!(no_stack_check, true);
|
untracked!(no_stack_check, true);
|
||||||
|
|
|
@ -253,6 +253,62 @@ bitflags::bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for LinkSelfContainedComponents {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(match s {
|
||||||
|
"crto" => LinkSelfContainedComponents::CRT_OBJECTS,
|
||||||
|
"libc" => LinkSelfContainedComponents::LIBC,
|
||||||
|
"unwind" => LinkSelfContainedComponents::UNWIND,
|
||||||
|
"linker" => LinkSelfContainedComponents::LINKER,
|
||||||
|
"sanitizers" => LinkSelfContainedComponents::SANITIZERS,
|
||||||
|
"mingw" => LinkSelfContainedComponents::MINGW,
|
||||||
|
_ => return Err(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LinkSelfContained {
|
||||||
|
/// Incorporates an enabled or disabled component as specified on the CLI, if possible.
|
||||||
|
/// For example: `+linker`, and `-crto`.
|
||||||
|
pub(crate) fn handle_cli_component(&mut self, component: &str) -> Result<(), ()> {
|
||||||
|
// Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
|
||||||
|
// set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
|
||||||
|
// set in bulk with its historical values, then manually setting a component clears that
|
||||||
|
// `explicitly_set` state.
|
||||||
|
if let Some(component_to_enable) = component.strip_prefix("+") {
|
||||||
|
self.explicitly_set = None;
|
||||||
|
self.components.insert(component_to_enable.parse()?);
|
||||||
|
Ok(())
|
||||||
|
} else if let Some(component_to_disable) = component.strip_prefix("-") {
|
||||||
|
self.explicitly_set = None;
|
||||||
|
self.components.remove(component_to_disable.parse()?);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns all components on or off and records that this was done explicitly for compatibility
|
||||||
|
/// purposes.
|
||||||
|
pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
|
||||||
|
self.explicitly_set = Some(enabled);
|
||||||
|
self.components = if enabled {
|
||||||
|
LinkSelfContainedComponents::all()
|
||||||
|
} else {
|
||||||
|
LinkSelfContainedComponents::empty()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
|
||||||
|
pub fn on() -> Self {
|
||||||
|
let mut on = LinkSelfContained::default();
|
||||||
|
on.set_all_explicitly(true);
|
||||||
|
on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Used with `-Z assert-incr-state`.
|
/// Used with `-Z assert-incr-state`.
|
||||||
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
||||||
pub enum IncrementalStateAssertion {
|
pub enum IncrementalStateAssertion {
|
||||||
|
|
|
@ -410,6 +410,8 @@ mod desc {
|
||||||
pub const parse_split_dwarf_kind: &str =
|
pub const parse_split_dwarf_kind: &str =
|
||||||
"one of supported split dwarf modes (`split` or `single`)";
|
"one of supported split dwarf modes (`split` or `single`)";
|
||||||
pub const parse_gcc_ld: &str = "one of: no value, `lld`";
|
pub const parse_gcc_ld: &str = "one of: no value, `lld`";
|
||||||
|
pub const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
|
||||||
|
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
|
||||||
pub const parse_stack_protector: &str =
|
pub const parse_stack_protector: &str =
|
||||||
"one of (`none` (default), `basic`, `strong`, or `all`)";
|
"one of (`none` (default), `basic`, `strong`, or `all`)";
|
||||||
pub const parse_branch_protection: &str =
|
pub const parse_branch_protection: &str =
|
||||||
|
@ -1122,6 +1124,34 @@ mod parse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn parse_link_self_contained(slot: &mut LinkSelfContained, v: Option<&str>) -> bool {
|
||||||
|
// Whenever `-C link-self-contained` is passed without a value, it's an opt-in
|
||||||
|
// just like `parse_opt_bool`, the historical value of this flag.
|
||||||
|
//
|
||||||
|
// 1. Parse historical single bool values
|
||||||
|
let s = v.unwrap_or("y");
|
||||||
|
match s {
|
||||||
|
"y" | "yes" | "on" => {
|
||||||
|
slot.set_all_explicitly(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
"n" | "no" | "off" => {
|
||||||
|
slot.set_all_explicitly(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Parse a list of enabled and disabled components.
|
||||||
|
for comp in s.split(",") {
|
||||||
|
if slot.handle_cli_component(comp).is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
|
pub(crate) fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
|
||||||
match v {
|
match v {
|
||||||
Some("command") => *slot = Some(WasiExecModel::Command),
|
Some("command") => *slot = Some(WasiExecModel::Command),
|
||||||
|
@ -1265,9 +1295,9 @@ options! {
|
||||||
#[rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field")]
|
#[rustc_lint_opt_deny_field_access("use `Session::link_dead_code` instead of this field")]
|
||||||
link_dead_code: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
link_dead_code: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||||
"keep dead code at link time (useful for code coverage) (default: no)"),
|
"keep dead code at link time (useful for code coverage) (default: no)"),
|
||||||
link_self_contained: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
|
link_self_contained: LinkSelfContained = (LinkSelfContained::default(), parse_link_self_contained, [UNTRACKED],
|
||||||
"control whether to link Rust provided C objects/libraries or rely
|
"control whether to link Rust provided C objects/libraries or rely
|
||||||
on C toolchain installed in the system"),
|
on a C toolchain or linker installed in the system"),
|
||||||
linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
|
linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
|
||||||
"system linker to link outputs with"),
|
"system linker to link outputs with"),
|
||||||
linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
|
linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue