@@ -1102,15 +1102,34 @@ fn build_base_args(
11021102 }
11031103 }
11041104
1105+ let use_embed_metadata = use_embed_metadata ( build_runner) ;
11051106 if unit. mode . is_check ( ) {
11061107 cmd. arg ( "--emit=dep-info,metadata" ) ;
1107- } else if !unit. requires_upstream_objects ( ) {
1108- // Always produce metadata files for rlib outputs. Metadata may be used
1109- // in this session for a pipelined compilation, or it may be used in a
1110- // future Cargo session as part of a pipelined compile.
1111- cmd. arg ( "--emit=dep-info,metadata,link" ) ;
1108+ } else if use_embed_metadata {
1109+ // Nightly rustc supports the -Zembed-metadata=no flag, which tells it to avoid including
1110+ // full metadata in rlib/dylib artifacts, to save space on disk. In this case, metadata
1111+ // will only be stored in .rmeta files.
1112+ // When we use this flag, we should also pass --emit=metadata to all artifacts that
1113+ // contain useful metadata (rlib/dylib/proc macros), so that a .rmeta file is actually
1114+ // generated. If we didn't do this, the full metadata would not get written anywhere.
1115+ // However, we do not want to pass --emit=metadata to artifacts that never produce useful
1116+ // metadata, such as binaries, because that would just unnecessarily create empty .rmeta
1117+ // files on disk.
1118+ if unit. benefits_from_split_metadata ( ) {
1119+ cmd. arg ( "--emit=dep-info,metadata,link" ) ;
1120+ cmd. args ( & [ "-Z" , "embed-metadata=no" ] ) ;
1121+ } else {
1122+ cmd. arg ( "--emit=dep-info,link" ) ;
1123+ }
11121124 } else {
1113- cmd. arg ( "--emit=dep-info,link" ) ;
1125+ // If we don't use -Zembed-metadata=no, we emit .rmeta files only for rlib outputs.
1126+ // This metadata may be used in this session for a pipelined compilation, or it may
1127+ // be used in a future Cargo session as part of a pipelined compile.
1128+ if !unit. requires_upstream_objects ( ) {
1129+ cmd. arg ( "--emit=dep-info,metadata,link" ) ;
1130+ } else {
1131+ cmd. arg ( "--emit=dep-info,link" ) ;
1132+ }
11141133 }
11151134
11161135 let prefer_dynamic = ( unit. target . for_host ( ) && !unit. target . is_custom_build ( ) )
@@ -1609,6 +1628,8 @@ pub fn extern_args(
16091628 let mut result = Vec :: new ( ) ;
16101629 let deps = build_runner. unit_deps ( unit) ;
16111630
1631+ let use_embed_metadata = use_embed_metadata ( build_runner) ;
1632+
16121633 // Closure to add one dependency to `result`.
16131634 let mut link_to =
16141635 |dep : & UnitDep , extern_crate_name : InternedString , noprelude : bool | -> CargoResult < ( ) > {
@@ -1658,6 +1679,12 @@ pub fn extern_args(
16581679 if output. flavor == FileFlavor :: Linkable {
16591680 pass ( & output. path ) ;
16601681 }
1682+ // If we use -Zembed-metadata=no, we also need to pass the path to the
1683+ // corresponding .rmeta file to the linkable artifact, because the
1684+ // normal dependency (rlib) doesn't contain the full metadata.
1685+ else if use_embed_metadata && output. flavor == FileFlavor :: Rmeta {
1686+ pass ( & output. path ) ;
1687+ }
16611688 }
16621689 }
16631690 Ok ( ( ) )
@@ -1684,6 +1711,11 @@ fn envify(s: &str) -> String {
16841711 . collect ( )
16851712}
16861713
1714+ /// Returns true if -Zembed-metadata=no mode should be used when compiling Rust artifacts.
1715+ fn use_embed_metadata ( build_runner : & BuildRunner < ' _ , ' _ > ) -> bool {
1716+ build_runner. bcx . gctx . nightly_features_allowed
1717+ }
1718+
16871719/// Configuration of the display of messages emitted by the compiler,
16881720/// e.g. diagnostics, warnings, errors, and message caching.
16891721struct OutputOptions {
0 commit comments