@@ -199,6 +199,142 @@ impl LinkerPluginLto {
199199 }
200200}
201201
202+ /// The different values `-C link-self-contained` can take.
203+ ///
204+ /// They are fine-grained, and control the behavior of:
205+ /// - linking to our own CRT objects (the historical default)
206+ /// - using a linker we distribute
207+ ///
208+ /// Since this flag historically targeted the CRT use-case, the defaults haven't changed, but there
209+ /// are new values so that users can choose that behavior in combination with the linker use-case.
210+ ///
211+ /// For example:
212+ /// - the absence of the `-C link-self-contained` was the historical default, and therefore this
213+ /// default value still targets `auto` (`LinkSelfContainedCrt::Auto`).
214+ /// - `-C link-self-contained=linker` turns on the linker, while keeping the default CRT behavior.
215+ /// - explicitly turning on the CRT linking can be done as the historical `-C link-self-contained=y`,
216+ /// or the fine-grained `-C link-self-contained=crt`
217+ /// - turning both on can be done with `-C link-self-contained=all`
218+ ///
219+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
220+ pub struct LinkSelfContained {
221+ pub crt : LinkSelfContainedCrt ,
222+ pub linker : LinkSelfContainedLinker ,
223+ }
224+
225+ impl LinkSelfContained {
226+ /// Explicitly turns off the self-contained linker facet, becoming an opt-out that is the
227+ /// historically stable `-C link-self-contained=y` behavior.
228+ fn crt_only ( ) -> Self {
229+ LinkSelfContained { crt : LinkSelfContainedCrt :: On , linker : LinkSelfContainedLinker :: Off }
230+ }
231+
232+ /// Keeps stable behavior only turning the self-contained CRT linking on.
233+ fn on ( ) -> Self {
234+ LinkSelfContained :: crt_only ( )
235+ }
236+
237+ fn off ( ) -> Self {
238+ LinkSelfContained { crt : LinkSelfContainedCrt :: Off , linker : LinkSelfContainedLinker :: Off }
239+ }
240+
241+ /// Explicitly turns off the self-contained linker facet, becoming an opt-out that is the
242+ /// historically stable default, target-defined, behavior.
243+ ///
244+ /// The current default.
245+ fn auto ( ) -> Self {
246+ LinkSelfContained { crt : LinkSelfContainedCrt :: Auto , linker : LinkSelfContainedLinker :: Off }
247+ }
248+
249+ fn linker ( ) -> Self {
250+ LinkSelfContained { crt : LinkSelfContainedCrt :: Auto , linker : LinkSelfContainedLinker :: On }
251+ }
252+
253+ fn all ( ) -> Self {
254+ LinkSelfContained { crt : LinkSelfContainedCrt :: On , linker : LinkSelfContainedLinker :: On }
255+ }
256+ }
257+
258+ impl Default for LinkSelfContained {
259+ fn default ( ) -> Self {
260+ LinkSelfContained :: auto ( )
261+ }
262+ }
263+
264+ impl FromStr for LinkSelfContained {
265+ type Err = ( ) ;
266+
267+ fn from_str ( s : & str ) -> Result < Self , ( ) > {
268+ // TMP: do we also need "linker_only", crt:off and linker:on ? Except in rare targets, this
269+ // use-case should be taken care of by "linker" for crt:auto linker:on.
270+
271+ Ok ( match s {
272+ // Historical value parsing: a bool option
273+ "no" | "n" | "off" => LinkSelfContained :: off ( ) ,
274+ "yes" | "y" | "on" => LinkSelfContained :: on ( ) ,
275+
276+ // New fine-grained facets
277+ "crt" => {
278+ // This is the same as `-C link-self-contained=y`, but allows to possibly change
279+ // that while keeping the current only turning on self-contained CRT linking. Also
280+ // makes an explicit value to opt into only a single facet.
281+ LinkSelfContained :: crt_only ( )
282+ }
283+ "auto" => LinkSelfContained :: auto ( ) ,
284+ "linker" => LinkSelfContained :: linker ( ) ,
285+
286+ // Composite of both
287+ "all" => LinkSelfContained :: all ( ) ,
288+ _ => return Err ( ( ) ) ,
289+ } )
290+ }
291+ }
292+
293+ /// Historically, `-C link-self-contained` was mainly about linking to our own CRT objects. This has
294+ /// been extracted to a few dedicated values, while keeping the existing stable values as-is: the
295+ /// default value, or opt-in for the whole flag are still these CRT-related values.
296+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
297+ pub enum LinkSelfContainedCrt {
298+ /// The historical default value, when `-C link-self-contained` was not specified.The
299+ /// self-contained linking behavior is target-defined in this case.
300+ Auto ,
301+
302+ /// The historical value for `-C link-self-contained=y`.
303+ On ,
304+
305+ /// When self-contained linking is explicitly turned off, with `-C link-self-contained=n`
306+ Off ,
307+ }
308+
309+ impl LinkSelfContainedCrt {
310+ pub fn is_explicitly_set ( & self ) -> Option < bool > {
311+ match self {
312+ LinkSelfContainedCrt :: On => Some ( true ) ,
313+ LinkSelfContainedCrt :: Off => Some ( false ) ,
314+ LinkSelfContainedCrt :: Auto => None ,
315+ }
316+ }
317+ }
318+
319+ /// The different linker-related options for `-C link-self-contained`, to choose between
320+ /// using system-installed linkers, or one present in the rust distribution.
321+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
322+ pub enum LinkSelfContainedLinker {
323+ /// Whenever `-C link-self-contained=linker` is present. This opts in to using
324+ /// a linker we distribute (e.g. `rust-lld`).
325+ On ,
326+
327+ /// The default case: when `-C link-self-contained=linker` is absent, and when self-contained
328+ /// linking is explicitly turned off, with `-C link-self-contained=n`.
329+ Off ,
330+ }
331+
332+ impl LinkSelfContainedLinker {
333+ pub fn is_on ( & self ) -> bool {
334+ * self == LinkSelfContainedLinker :: On
335+ }
336+ }
337+
202338/// The different settings that can be enabled via the `-Z location-detail` flag.
203339#[ derive( Clone , PartialEq , Hash , Debug ) ]
204340pub struct LocationDetail {
0 commit comments