@@ -158,6 +158,8 @@ pub struct ParsedArguments {
158158 crate_name : String ,
159159 /// The crate types that will be generated
160160 crate_types : CrateTypes ,
161+ /// The hash pased to -Cextra-filename
162+ extra_filename : Option < String > ,
161163 /// If dependency info is being emitted, the name of the dep info file.
162164 dep_info : Option < PathBuf > ,
163165 /// If profile info is being emitted, the path of the profile.
@@ -1251,7 +1253,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
12511253 // Figure out the dep-info filename, if emitting dep-info.
12521254 let dep_info = if emit. contains ( "dep-info" ) {
12531255 let mut dep_info = crate_name. clone ( ) ;
1254- if let Some ( extra_filename) = extra_filename. clone ( ) {
1256+ if let Some ( extra_filename) = extra_filename. as_ref ( ) {
12551257 dep_info. push_str ( & extra_filename[ ..] ) ;
12561258 }
12571259 dep_info. push_str ( ".d" ) ;
@@ -1266,7 +1268,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
12661268 // Figure out the gcno filename, if producing gcno files with `-Zprofile`.
12671269 let gcno = if gcno && emit. contains ( "link" ) {
12681270 let mut gcno = crate_name. clone ( ) ;
1269- if let Some ( extra_filename) = extra_filename {
1271+ if let Some ( extra_filename) = extra_filename. as_ref ( ) {
12701272 gcno. push_str ( & extra_filename[ ..] ) ;
12711273 }
12721274 gcno. push_str ( ".gcno" ) ;
@@ -1309,6 +1311,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
13091311 crate_link_paths,
13101312 staticlibs,
13111313 crate_name,
1314+ extra_filename,
13121315 dep_info : dep_info. map ( |s| s. into ( ) ) ,
13131316 profile : profile. map ( |s| s. into ( ) ) ,
13141317 gcno : gcno. map ( |s| s. into ( ) ) ,
@@ -1455,15 +1458,25 @@ where
14551458 let ( mut sortables, rest) : ( Vec < _ > , Vec < _ > ) = os_string_arguments
14561459 . iter ( )
14571460 // We exclude a few arguments from the hash:
1458- // -L, --extern, --out-dir, --diagnostic-width
1461+ // -L, --extern, --out-dir, --diagnostic-width, -Cprefer-dynamic, -Cextra-filename
14591462 // These contain paths which aren't relevant to the output, and the compiler inputs
14601463 // in those paths (rlibs and static libs used in the compilation) are used as hash
1461- // inputs below.
1462- . filter ( |& ( arg, _) | {
1464+ // inputs below. -Cextra-filename is okay to exclude from the hash because we remove
1465+ // the extra component from the cache keys below (`remove_extra_filename`)
1466+ . filter ( |& ( arg, value) | {
14631467 !( arg == "--extern"
14641468 || arg == "-L"
14651469 || arg == "--out-dir"
1466- || arg == "--diagnostic-width" )
1470+ || arg == "--diagnostic-width"
1471+ || ( arg == "-C" && value == & Some ( OsString :: from ( "prefer-dynamic" ) ) )
1472+ || ( arg == "-C"
1473+ && value
1474+ . as_ref ( )
1475+ . is_some_and ( |v| v. starts_with ( "extra-filename" ) ) ) )
1476+ // prefer-dynamic never affects staticlibs or rlib
1477+ // see https://github.com/rust-lang/rust/blob/master/compiler/rustc_metadata/src/dependency_format.rs
1478+ // note that the unstable `staticlib-prefer-dynamic` affects staticlibs but it
1479+ // is an independent flag
14671480 } )
14681481 // We also exclude `--target` if it specifies a path to a .json file. The file content
14691482 // is used as hash input below.
@@ -1597,6 +1610,19 @@ where
15971610 }
15981611 }
15991612
1613+ let remove_extra_filename = |p : String | {
1614+ if let Some ( extra) = self . parsed_args . extra_filename . as_ref ( ) {
1615+ if let Some ( ( pre_ext, ext) ) = p. rsplit_once ( "." ) {
1616+ if pre_ext. ends_with ( extra) {
1617+ let pre_extra_filename = & pre_ext[ 0 ..( pre_ext. len ( ) - extra. len ( ) ) ] ;
1618+ return format ! ( "{}.{}" , pre_extra_filename, ext) ;
1619+ }
1620+ }
1621+ }
1622+
1623+ p
1624+ } ;
1625+
16001626 // Convert output files into a map of basename -> full
16011627 // path, and remove some unneeded / non-existing ones,
16021628 // see https://github.com/rust-lang/rust/pull/68799.
@@ -1605,7 +1631,7 @@ where
16051631 . map ( |o| {
16061632 let p = self . parsed_args . output_dir . join ( & o) ;
16071633 (
1608- o ,
1634+ remove_extra_filename ( o ) ,
16091635 ArtifactDescriptor {
16101636 path : p,
16111637 optional : false ,
@@ -1616,7 +1642,7 @@ where
16161642 let dep_info = if let Some ( dep_info) = & self . parsed_args . dep_info {
16171643 let p = self . parsed_args . output_dir . join ( dep_info) ;
16181644 outputs. insert (
1619- dep_info. to_string_lossy ( ) . into_owned ( ) ,
1645+ remove_extra_filename ( dep_info. to_string_lossy ( ) . into_owned ( ) ) ,
16201646 ArtifactDescriptor {
16211647 path : p. clone ( ) ,
16221648 optional : false ,
@@ -1639,7 +1665,7 @@ where
16391665 if let Some ( gcno) = & self . parsed_args . gcno {
16401666 let p = self . parsed_args . output_dir . join ( gcno) ;
16411667 outputs. insert (
1642- gcno. to_string_lossy ( ) . into_owned ( ) ,
1668+ remove_extra_filename ( gcno. to_string_lossy ( ) . into_owned ( ) ) ,
16431669 ArtifactDescriptor {
16441670 path : p,
16451671 optional : true ,
@@ -2857,6 +2883,7 @@ LLVM version: 15.0.2
28572883 ) ;
28582884 assert_eq ! ( h. output_dir. to_str( ) , Some ( "/foo/target/debug/deps" ) ) ;
28592885 assert_eq ! ( h. crate_name, "foo" ) ;
2886+ assert_eq ! ( h. extra_filename, Some ( "-d6ae26f5bcfb7733" . to_string( ) ) ) ;
28602887 assert_eq ! (
28612888 h. dep_info. unwrap( ) . to_str( ) . unwrap( ) ,
28622889 "foo-d6ae26f5bcfb7733.d"
@@ -3471,6 +3498,7 @@ proc_macro false
34713498 rlib : true ,
34723499 staticlib : false ,
34733500 } ,
3501+ extra_filename : None ,
34743502 dep_info : None ,
34753503 emit,
34763504 color_mode : ColorMode :: Auto ,
@@ -3741,7 +3769,11 @@ proc_macro false
37413769 "--crate-type" ,
37423770 "lib" ,
37433771 "-L" ,
3744- "y=y"
3772+ "y=y" ,
3773+ "-C" ,
3774+ "prefer-dynamic" ,
3775+ "-C" ,
3776+ "extra-filename=abcdabcdabcd"
37453777 ] ,
37463778 & [ ] ,
37473779 nothing,
0 commit comments