Skip to content

Commit dad50d7

Browse files
committed
implement self-contained linking with lld via linker features
Until necessary, the linker features are inferred from the linker flavor. This is done to reduce churn on all of the targets until we're very certain the design matches our expectations.
1 parent 07f22cc commit dad50d7

File tree

1 file changed

+49
-12
lines changed
  • compiler/rustc_codegen_ssa/src/back

1 file changed

+49
-12
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+49-12
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ use rustc_session::utils::NativeLibKind;
2222
use rustc_session::{filesearch, Session};
2323
use rustc_span::symbol::Symbol;
2424
use rustc_target::spec::crt_objects::CrtObjects;
25-
use rustc_target::spec::LinkSelfContainedComponents;
2625
use rustc_target::spec::LinkSelfContainedDefault;
2726
use rustc_target::spec::LinkerFlavorCli;
2827
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld, PanicStrategy};
28+
use rustc_target::spec::{LinkSelfContainedComponents, LinkerFeatures};
2929
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
3030

3131
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
@@ -741,6 +741,8 @@ fn link_natively(
741741
info!("preparing {:?} to {:?}", crate_type, out_filename);
742742
let (linker_path, flavor) = linker_and_flavor(sess);
743743
let self_contained_components = self_contained_components(sess, crate_type);
744+
let linker_features = linker_features(sess, flavor);
745+
744746
let mut cmd = linker_with_args(
745747
&linker_path,
746748
flavor,
@@ -751,6 +753,7 @@ fn link_natively(
751753
out_filename,
752754
codegen_results,
753755
self_contained_components,
756+
linker_features,
754757
)?;
755758

756759
linker::disable_localization(&mut cmd);
@@ -1816,6 +1819,40 @@ fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfC
18161819
}
18171820
}
18181821

1822+
/// Returns the set of linker features that are:
1823+
/// - enabled on the CLI, or by the current target
1824+
/// - and, are not disabled on the CLI
1825+
fn linker_features(sess: &Session, flavor: LinkerFlavor) -> LinkerFeatures {
1826+
// Note: currently, both the linker flavors and linker features model the same functionality:
1827+
// they can only contain whether the linker is used via a C/C++ compiler, and whether the linker
1828+
// used is lld.
1829+
//
1830+
// While linker features are unstable, and in order to reduce churn on the many target specs
1831+
// (e.g. by adding linker features there, and removing the cc/lld components from the flavors)
1832+
// we currently *infer* the target's linker features from the linker flavor itself.
1833+
//
1834+
// For stabilization, and/or when linker features gain additional components that are not
1835+
// modeled by the current linker flavors, the refactoring mentioned above may need to be done.
1836+
let mut linker_features_target = LinkerFeatures::empty();
1837+
if flavor.uses_cc() {
1838+
linker_features_target.insert(LinkerFeatures::CC);
1839+
}
1840+
if flavor.uses_lld() {
1841+
linker_features_target.insert(LinkerFeatures::LLD);
1842+
}
1843+
1844+
// Now we merge the features enabled on the CLI and the target, and remove the ones disabled on
1845+
// the CLI.
1846+
let linker_features_cli = &sess.opts.unstable_opts.linker_features;
1847+
debug!(
1848+
"linker features - target: {:?}, enabled on CLI: {:?}, disabled on CLI: {:?}",
1849+
linker_features_target, linker_features_cli.enabled, linker_features_cli.disabled
1850+
);
1851+
let linker_features =
1852+
(linker_features_cli.enabled | linker_features_target) - linker_features_cli.disabled;
1853+
linker_features
1854+
}
1855+
18191856
/// Add pre-link object files defined by the target spec.
18201857
fn add_pre_link_objects(
18211858
cmd: &mut dyn Linker,
@@ -2114,6 +2151,7 @@ fn linker_with_args(
21142151
out_filename: &Path,
21152152
codegen_results: &CodegenResults,
21162153
self_contained_components: LinkSelfContainedComponents,
2154+
linker_features: LinkerFeatures,
21172155
) -> Result<Command, ErrorGuaranteed> {
21182156
let self_contained_crt_objects = self_contained_components.is_crt_objects_enabled();
21192157
let cmd = &mut *super::linker::get_linker(
@@ -2301,6 +2339,7 @@ fn linker_with_args(
23012339
codegen_results,
23022340
out_filename,
23032341
tmpdir,
2342+
linker_features,
23042343
);
23052344

23062345
// Can be used for arbitrary order-independent options.
@@ -2334,9 +2373,10 @@ fn add_order_independent_options(
23342373
codegen_results: &CodegenResults,
23352374
out_filename: &Path,
23362375
tmpdir: &Path,
2376+
linker_features: LinkerFeatures,
23372377
) {
23382378
// Take care of the flavors and CLI options requesting the `lld` linker.
2339-
add_lld_args(cmd, sess, flavor, self_contained_components);
2379+
add_lld_args(cmd, sess, flavor, self_contained_components, linker_features);
23402380

23412381
add_apple_sdk(cmd, sess, flavor);
23422382

@@ -3053,24 +3093,21 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
30533093
}
30543094
}
30553095

3056-
/// When using the linker flavors opting in to `lld`, add the necessary paths and arguments to
3057-
/// invoke it:
3096+
/// When using the linker flavors (or linker feature) opting in to `lld`, add the necessary paths
3097+
/// and arguments to invoke it:
30583098
/// - when the self-contained linker flag is active: the build of `lld` distributed with rustc,
30593099
/// - or any `lld` available to `cc`.
3100+
#[instrument(level = "debug", skip(cmd, sess))]
30603101
fn add_lld_args(
30613102
cmd: &mut dyn Linker,
30623103
sess: &Session,
30633104
flavor: LinkerFlavor,
30643105
self_contained_components: LinkSelfContainedComponents,
3106+
linker_features: LinkerFeatures,
30653107
) {
3066-
debug!(
3067-
"add_lld_args requested, flavor: '{:?}', target self-contained components: {:?}",
3068-
flavor, self_contained_components,
3069-
);
3070-
3071-
// If the flavor doesn't use a C/C++ compiler to invoke the linker, or doesn't opt in to `lld`,
3072-
// we don't need to do anything.
3073-
if !(flavor.uses_cc() && flavor.uses_lld()) {
3108+
// If we're not using a C/C++ compiler to invoke the linker, or don't opt in to `lld`, we don't
3109+
// need to do anything.
3110+
if !(linker_features.is_cc_enabled() && linker_features.is_lld_enabled()) {
30743111
return;
30753112
}
30763113

0 commit comments

Comments
 (0)