@@ -12,6 +12,7 @@ use crate::{EarlyErrorHandler, Session};
12
12
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
13
13
use rustc_data_structures:: stable_hasher:: { StableOrd , ToStableHashKey } ;
14
14
use rustc_target:: abi:: Align ;
15
+ use rustc_target:: spec:: LinkSelfContainedComponents ;
15
16
use rustc_target:: spec:: { PanicStrategy , RelocModel , SanitizerSet , SplitDebuginfo } ;
16
17
use rustc_target:: spec:: { Target , TargetTriple , TargetWarnings , TARGETS } ;
17
18
@@ -232,75 +233,50 @@ pub struct LinkSelfContained {
232
233
/// Used for compatibility with the existing opt-in and target inference.
233
234
pub explicitly_set : Option < bool > ,
234
235
235
- /// The components that are enabled.
236
- components : LinkSelfContainedComponents ,
237
- }
238
-
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 = ( ) ;
236
+ /// The components that are enabled on the CLI, using the `+component` syntax or one of the
237
+ /// `true` shorcuts.
238
+ enabled_components : LinkSelfContainedComponents ,
260
239
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 ,
272
243
}
273
244
274
245
impl LinkSelfContained {
275
246
/// Incorporates an enabled or disabled component as specified on the CLI, if possible.
276
247
/// 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 < ( ) > {
278
249
// Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
279
250
// set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
280
251
// set in bulk with its historical values, then manually setting a component clears that
281
252
// `explicitly_set` state.
282
253
if let Some ( component_to_enable) = component. strip_prefix ( '+' ) {
283
254
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 ( ( ) )
286
258
} else if let Some ( component_to_disable) = component. strip_prefix ( '-' ) {
287
259
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 ( ( ) )
290
263
} else {
291
- Err ( ( ) )
264
+ None
292
265
}
293
266
}
294
267
295
268
/// Turns all components on or off and records that this was done explicitly for compatibility
296
269
/// purposes.
297
270
pub ( crate ) fn set_all_explicitly ( & mut self , enabled : bool ) {
298
271
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 ( ) ;
301
276
} else {
302
- LinkSelfContainedComponents :: empty ( )
303
- } ;
277
+ self . enabled_components = LinkSelfContainedComponents :: empty ( ) ;
278
+ self . disabled_components = LinkSelfContainedComponents :: all ( ) ;
279
+ }
304
280
}
305
281
306
282
/// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
@@ -314,13 +290,32 @@ impl LinkSelfContained {
314
290
/// components was set individually. This would also require the `-Zunstable-options` flag, to
315
291
/// be allowed.
316
292
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 ( ) ;
318
295
self . explicitly_set . is_none ( ) && any_component_set
319
296
}
320
297
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 )
308
+ }
309
+
310
+ /// Returns CLI inconsistencies to emit errors: individual components were both enabled and
311
+ /// disabled.
312
+ fn check_consistency ( & self ) -> Option < LinkSelfContainedComponents > {
313
+ if self . explicitly_set . is_some ( ) {
314
+ None
315
+ } else {
316
+ let common = self . enabled_components . intersection ( self . disabled_components ) ;
317
+ if common. is_empty ( ) { None } else { Some ( common) }
318
+ }
324
319
}
325
320
}
326
321
@@ -2758,9 +2753,8 @@ pub fn build_session_options(
2758
2753
}
2759
2754
2760
2755
// For testing purposes, until we have more feedback about these options: ensure `-Z
2761
- // unstable-options` is required when using the unstable `-C link-self-contained` options, like
2762
- // `-C link-self-contained=+linker`, and when using the unstable `-C linker-flavor` options, like
2763
- // `-C linker-flavor=gnu-lld-cc`.
2756
+ // unstable-options` is required when using the unstable `-C link-self-contained` and `-C
2757
+ // linker-flavor` options.
2764
2758
if !nightly_options:: is_unstable_enabled ( matches) {
2765
2759
let uses_unstable_self_contained_option =
2766
2760
cg. link_self_contained . are_unstable_variants_set ( ) ;
@@ -2782,6 +2776,19 @@ pub fn build_session_options(
2782
2776
}
2783
2777
}
2784
2778
2779
+ // Check `-C link-self-contained` for consistency: individual components cannot be both enabled
2780
+ // and disabled at the same time.
2781
+ if let Some ( erroneous_components) = cg. link_self_contained . check_consistency ( ) {
2782
+ let names: String = erroneous_components
2783
+ . into_iter ( )
2784
+ . map ( |c| c. as_str ( ) . unwrap ( ) )
2785
+ . intersperse ( ", " )
2786
+ . collect ( ) ;
2787
+ handler. early_error ( format ! (
2788
+ "some `-C link-self-contained` components were both enabled and disabled: {names}"
2789
+ ) ) ;
2790
+ }
2791
+
2785
2792
let prints = collect_print_requests ( handler, & mut cg, & mut unstable_opts, matches) ;
2786
2793
2787
2794
let cg = cg;
0 commit comments