@@ -1131,13 +1131,31 @@ fn build_base_args(
11311131
11321132 if unit. mode . is_check ( ) {
11331133 cmd. arg ( "--emit=dep-info,metadata" ) ;
1134- } else if !unit. requires_upstream_objects ( ) {
1135- // Always produce metadata files for rlib outputs. Metadata may be used
1136- // in this session for a pipelined compilation, or it may be used in a
1137- // future Cargo session as part of a pipelined compile.
1138- cmd. arg ( "--emit=dep-info,metadata,link" ) ;
1134+ } else if build_runner. bcx . gctx . cli_unstable ( ) . no_embed_metadata {
1135+ // Nightly rustc supports the -Zembed-metadata=no flag, which tells it to avoid including
1136+ // full metadata in rlib/dylib artifacts, to save space on disk. In this case, metadata
1137+ // will only be stored in .rmeta files.
1138+ // When we use this flag, we should also pass --emit=metadata to all artifacts that
1139+ // contain useful metadata (rlib/dylib/proc macros), so that a .rmeta file is actually
1140+ // generated. If we didn't do this, the full metadata would not get written anywhere.
1141+ // However, we do not want to pass --emit=metadata to artifacts that never produce useful
1142+ // metadata, such as binaries, because that would just unnecessarily create empty .rmeta
1143+ // files on disk.
1144+ if unit. benefits_from_no_embed_metadata ( ) {
1145+ cmd. arg ( "--emit=dep-info,metadata,link" ) ;
1146+ cmd. args ( & [ "-Z" , "embed-metadata=no" ] ) ;
1147+ } else {
1148+ cmd. arg ( "--emit=dep-info,link" ) ;
1149+ }
11391150 } else {
1140- cmd. arg ( "--emit=dep-info,link" ) ;
1151+ // If we don't use -Zembed-metadata=no, we emit .rmeta files only for rlib outputs.
1152+ // This metadata may be used in this session for a pipelined compilation, or it may
1153+ // be used in a future Cargo session as part of a pipelined compile.
1154+ if !unit. requires_upstream_objects ( ) {
1155+ cmd. arg ( "--emit=dep-info,metadata,link" ) ;
1156+ } else {
1157+ cmd. arg ( "--emit=dep-info,link" ) ;
1158+ }
11411159 }
11421160
11431161 let prefer_dynamic = ( unit. target . for_host ( ) && !unit. target . is_custom_build ( ) )
@@ -1636,6 +1654,8 @@ pub fn extern_args(
16361654 let mut result = Vec :: new ( ) ;
16371655 let deps = build_runner. unit_deps ( unit) ;
16381656
1657+ let no_embed_metadata = build_runner. bcx . gctx . cli_unstable ( ) . no_embed_metadata ;
1658+
16391659 // Closure to add one dependency to `result`.
16401660 let mut link_to =
16411661 |dep : & UnitDep , extern_crate_name : InternedString , noprelude : bool | -> CargoResult < ( ) > {
@@ -1685,6 +1705,12 @@ pub fn extern_args(
16851705 if output. flavor == FileFlavor :: Linkable {
16861706 pass ( & output. path ) ;
16871707 }
1708+ // If we use -Zembed-metadata=no, we also need to pass the path to the
1709+ // corresponding .rmeta file to the linkable artifact, because the
1710+ // normal dependency (rlib) doesn't contain the full metadata.
1711+ else if no_embed_metadata && output. flavor == FileFlavor :: Rmeta {
1712+ pass ( & output. path ) ;
1713+ }
16881714 }
16891715 }
16901716 Ok ( ( ) )
0 commit comments