Skip to content

Commit 3adfc22

Browse files
committed
wip
1 parent 677d1f5 commit 3adfc22

File tree

14 files changed

+314
-95
lines changed

14 files changed

+314
-95
lines changed

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -4391,7 +4391,6 @@ dependencies = [
43914391
name = "rustc_session"
43924392
version = "0.0.0"
43934393
dependencies = [
4394-
"bitflags 1.3.2",
43954394
"getopts",
43964395
"libc",
43974396
"rustc_ast",

compiler/rustc_codegen_ssa/src/back/link.rs

+33-10
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use rustc_session::utils::NativeLibKind;
2222
/// need out of the shared crate context before we get rid of it.
2323
use rustc_session::{filesearch, Session};
2424
use rustc_span::symbol::Symbol;
25-
use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
25+
use rustc_target::spec::crt_objects::CrtObjects;
26+
use rustc_target::spec::LinkSelfContained;
2627
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld, PanicStrategy};
2728
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
2829

@@ -1709,21 +1710,37 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
17091710
/// instead of being found somewhere on the host system.
17101711
/// We only provide such support for a very limited number of targets.
17111712
fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
1713+
// Emit an error if the user requested self-contained mode on the CLI but the target explicitly
1714+
// refuses it.
17121715
if let Some(self_contained) = sess.opts.cg.link_self_contained.explicitly_set {
1713-
if sess.target.link_self_contained == LinkSelfContainedDefault::False {
1716+
if sess.target.link_self_contained.is_disabled() {
17141717
sess.emit_err(errors::UnsupportedLinkSelfContained);
17151718
}
17161719
return self_contained;
17171720
}
17181721

17191722
match sess.target.link_self_contained {
1720-
LinkSelfContainedDefault::False => false,
1721-
LinkSelfContainedDefault::True => true,
1723+
LinkSelfContained::True => true,
1724+
LinkSelfContained::False => false,
1725+
LinkSelfContained::WithComponents(components) => {
1726+
if components.is_all() {
1727+
true
1728+
} else if components.is_empty() {
1729+
false
1730+
} else {
1731+
// FIXME: Currently no target makes use of individual components to mean
1732+
// self-contained linking is fully enabled, in the sense of what the code downstream
1733+
// from here expects. Until components are handled a bit more deeply, we can
1734+
// consider that it's disabled and remain backwards compatible.
1735+
false
1736+
}
1737+
}
1738+
17221739
// FIXME: Find a better heuristic for "native musl toolchain is available",
17231740
// based on host and linker path, for example.
17241741
// (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
1725-
LinkSelfContainedDefault::Musl => sess.crt_static(Some(crate_type)),
1726-
LinkSelfContainedDefault::Mingw => {
1742+
LinkSelfContained::InferredForMusl => sess.crt_static(Some(crate_type)),
1743+
LinkSelfContained::InferredForMingw => {
17271744
sess.host == sess.target
17281745
&& sess.target.vendor != "uwp"
17291746
&& detect_self_contained_mingw(&sess)
@@ -2992,9 +3009,15 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
29923009
}
29933010

29943011
// 1. Implement the "self-contained" part of this feature by adding rustc distribution
2995-
// directories to the tool's search path.
2996-
let self_contained_linker = sess.opts.cg.link_self_contained.linker() || unstable_use_lld;
2997-
if self_contained_linker {
3012+
// directories to the tool's search path, depending on a mix between what users can specify on
3013+
// the CLI, and what the target spec enables (as it can't disable components):
3014+
// - if the self-contained linker is enabled on the CLI or by the target spec (or by the
3015+
// unstable CLI flag that will be removed eventually),
3016+
// - and if the self-contained linker is not disabled on the CLI.
3017+
let self_contained_linker = sess.target.options.link_self_contained.is_linker_enabled()
3018+
|| sess.opts.cg.link_self_contained.is_linker_enabled()
3019+
|| unstable_use_lld;
3020+
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
29983021
for path in sess.get_tools_search_paths(false) {
29993022
cmd.arg({
30003023
let mut arg = OsString::from("-B");
@@ -3005,7 +3028,7 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
30053028
}
30063029

30073030
// 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of
3008-
// `lld` as the linker.
3031+
// `lld` as the linker.
30093032
cmd.arg("-fuse-ld=lld");
30103033

30113034
if !flavor.is_gnu() {

compiler/rustc_session/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ version = "0.0.0"
44
edition = "2021"
55

66
[dependencies]
7-
bitflags = "1.2.1"
87
getopts = "0.2"
98
rustc_macros = { path = "../rustc_macros" }
109
tracing = "0.1"

compiler/rustc_session/src/config.rs

+34-50
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::{EarlyErrorHandler, Session};
1212
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1313
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
1414
use rustc_target::abi::Align;
15+
use rustc_target::spec::LinkSelfContainedComponents;
1516
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
1617
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
1718

@@ -232,75 +233,50 @@ pub struct LinkSelfContained {
232233
/// Used for compatibility with the existing opt-in and target inference.
233234
pub explicitly_set: Option<bool>,
234235

235-
/// The components that are enabled.
236-
components: LinkSelfContainedComponents,
237-
}
236+
/// The components that are enabled on the CLI, using the `+component` syntax or one of the
237+
/// `true` shorcuts.
238+
enabled_components: LinkSelfContainedComponents,
238239

239-
bitflags::bitflags! {
240-
#[derive(Default)]
241-
/// The `-C link-self-contained` components that can individually be enabled or disabled.
242-
pub struct LinkSelfContainedComponents: u8 {
243-
/// CRT objects (e.g. on `windows-gnu`, `musl`, `wasi` targets)
244-
const CRT_OBJECTS = 1 << 0;
245-
/// libc static library (e.g. on `musl`, `wasi` targets)
246-
const LIBC = 1 << 1;
247-
/// libgcc/libunwind (e.g. on `windows-gnu`, `fuchsia`, `fortanix`, `gnullvm` targets)
248-
const UNWIND = 1 << 2;
249-
/// Linker, dlltool, and their necessary libraries (e.g. on `windows-gnu` and for `rust-lld`)
250-
const LINKER = 1 << 3;
251-
/// Sanitizer runtime libraries
252-
const SANITIZERS = 1 << 4;
253-
/// Other MinGW libs and Windows import libs
254-
const MINGW = 1 << 5;
255-
}
256-
}
257-
258-
impl FromStr for LinkSelfContainedComponents {
259-
type Err = ();
260-
261-
fn from_str(s: &str) -> Result<Self, Self::Err> {
262-
Ok(match s {
263-
"crto" => LinkSelfContainedComponents::CRT_OBJECTS,
264-
"libc" => LinkSelfContainedComponents::LIBC,
265-
"unwind" => LinkSelfContainedComponents::UNWIND,
266-
"linker" => LinkSelfContainedComponents::LINKER,
267-
"sanitizers" => LinkSelfContainedComponents::SANITIZERS,
268-
"mingw" => LinkSelfContainedComponents::MINGW,
269-
_ => return Err(()),
270-
})
271-
}
240+
/// The components that are disabled on the CLI, using the `-component` syntax or one of the
241+
/// `false` shortcuts.
242+
disabled_components: LinkSelfContainedComponents,
272243
}
273244

274245
impl LinkSelfContained {
275246
/// Incorporates an enabled or disabled component as specified on the CLI, if possible.
276247
/// For example: `+linker`, and `-crto`.
277-
pub(crate) fn handle_cli_component(&mut self, component: &str) -> Result<(), ()> {
248+
pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
278249
// Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
279250
// set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
280251
// set in bulk with its historical values, then manually setting a component clears that
281252
// `explicitly_set` state.
282253
if let Some(component_to_enable) = component.strip_prefix('+') {
283254
self.explicitly_set = None;
284-
self.components.insert(component_to_enable.parse()?);
285-
Ok(())
255+
self.enabled_components
256+
.insert(LinkSelfContainedComponents::from_str(component_to_enable)?);
257+
Some(())
286258
} else if let Some(component_to_disable) = component.strip_prefix('-') {
287259
self.explicitly_set = None;
288-
self.components.remove(component_to_disable.parse()?);
289-
Ok(())
260+
self.disabled_components
261+
.insert(LinkSelfContainedComponents::from_str(component_to_disable)?);
262+
Some(())
290263
} else {
291-
Err(())
264+
None
292265
}
293266
}
294267

295268
/// Turns all components on or off and records that this was done explicitly for compatibility
296269
/// purposes.
297270
pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
298271
self.explicitly_set = Some(enabled);
299-
self.components = if enabled {
300-
LinkSelfContainedComponents::all()
272+
273+
if enabled {
274+
self.enabled_components = LinkSelfContainedComponents::all();
275+
self.disabled_components = LinkSelfContainedComponents::empty();
301276
} else {
302-
LinkSelfContainedComponents::empty()
303-
};
277+
self.enabled_components = LinkSelfContainedComponents::empty();
278+
self.disabled_components = LinkSelfContainedComponents::all();
279+
}
304280
}
305281

306282
/// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
@@ -314,13 +290,21 @@ impl LinkSelfContained {
314290
/// components was set individually. This would also require the `-Zunstable-options` flag, to
315291
/// be allowed.
316292
fn are_unstable_variants_set(&self) -> bool {
317-
let any_component_set = !self.components.is_empty();
293+
let any_component_set =
294+
!self.enabled_components.is_empty() || !self.disabled_components.is_empty();
318295
self.explicitly_set.is_none() && any_component_set
319296
}
320297

321-
/// Returns whether the self-contained linker component is enabled.
322-
pub fn linker(&self) -> bool {
323-
self.components.contains(LinkSelfContainedComponents::LINKER)
298+
/// Returns whether the self-contained linker component was enabled on the CLI, using the
299+
/// `-C link-self-contained=+linker` syntax, or one of the `true` shorcuts.
300+
pub fn is_linker_enabled(&self) -> bool {
301+
self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
302+
}
303+
304+
/// Returns whether the self-contained linker component was disabled on the CLI, using the
305+
/// `-C link-self-contained=-linker` syntax, or one of the `false` shorcuts.
306+
pub fn is_linker_disabled(&self) -> bool {
307+
self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
324308
}
325309
}
326310

compiler/rustc_session/src/options.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ mod parse {
11601160

11611161
// 2. Parse a list of enabled and disabled components.
11621162
for comp in s.split(',') {
1163-
if slot.handle_cli_component(comp).is_err() {
1163+
if slot.handle_cli_component(comp).is_none() {
11641164
return false;
11651165
}
11661166
}

compiler/rustc_target/src/spec/crt_objects.rs

-13
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
//! but not gcc's. As a result rustc cannot link with C++ static libraries (#36710)
4141
//! when linking in self-contained mode.
4242
43-
use crate::json::{Json, ToJson};
4443
use crate::spec::LinkOutputKind;
4544
use std::borrow::Cow;
4645
use std::collections::BTreeMap;
@@ -147,15 +146,3 @@ impl FromStr for LinkSelfContainedDefault {
147146
})
148147
}
149148
}
150-
151-
impl ToJson for LinkSelfContainedDefault {
152-
fn to_json(&self) -> Json {
153-
match *self {
154-
LinkSelfContainedDefault::False => "false",
155-
LinkSelfContainedDefault::True => "true",
156-
LinkSelfContainedDefault::Musl => "musl",
157-
LinkSelfContainedDefault::Mingw => "mingw",
158-
}
159-
.to_json()
160-
}
161-
}

compiler/rustc_target/src/spec/linux_musl_base.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::spec::crt_objects::{self, LinkSelfContainedDefault};
1+
use crate::spec::crt_objects;
2+
use crate::spec::LinkSelfContained;
23
use crate::spec::TargetOptions;
34

45
pub fn opts() -> TargetOptions {
@@ -7,7 +8,7 @@ pub fn opts() -> TargetOptions {
78
base.env = "musl".into();
89
base.pre_link_objects_self_contained = crt_objects::pre_musl_self_contained();
910
base.post_link_objects_self_contained = crt_objects::post_musl_self_contained();
10-
base.link_self_contained = LinkSelfContainedDefault::Musl;
11+
base.link_self_contained = LinkSelfContained::InferredForMusl;
1112

1213
// These targets statically link libc by default
1314
base.crt_static_default = true;

0 commit comments

Comments
 (0)