@@ -159,6 +159,8 @@ pub struct ParsedArguments {
159159 crate_name : String ,
160160 /// The crate types that will be generated
161161 crate_types : CrateTypes ,
162+ /// The hash pased to -Cextra-filename
163+ extra_filename : Option < String > ,
162164 /// If dependency info is being emitted, the name of the dep info file.
163165 dep_info : Option < PathBuf > ,
164166 /// If profile info is being emitted, the path of the profile.
@@ -1252,7 +1254,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
12521254 // Figure out the dep-info filename, if emitting dep-info.
12531255 let dep_info = if emit. contains ( "dep-info" ) {
12541256 let mut dep_info = crate_name. clone ( ) ;
1255- if let Some ( extra_filename) = extra_filename. clone ( ) {
1257+ if let Some ( extra_filename) = extra_filename. as_ref ( ) {
12561258 dep_info. push_str ( & extra_filename[ ..] ) ;
12571259 }
12581260 dep_info. push_str ( ".d" ) ;
@@ -1267,7 +1269,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
12671269 // Figure out the gcno filename, if producing gcno files with `-Zprofile`.
12681270 let gcno = if gcno && emit. contains ( "link" ) {
12691271 let mut gcno = crate_name. clone ( ) ;
1270- if let Some ( extra_filename) = extra_filename {
1272+ if let Some ( extra_filename) = extra_filename. as_ref ( ) {
12711273 gcno. push_str ( & extra_filename[ ..] ) ;
12721274 }
12731275 gcno. push_str ( ".gcno" ) ;
@@ -1310,6 +1312,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
13101312 crate_link_paths,
13111313 staticlibs,
13121314 crate_name,
1315+ extra_filename,
13131316 dep_info : dep_info. map ( |s| s. into ( ) ) ,
13141317 profile : profile. map ( |s| s. into ( ) ) ,
13151318 gcno : gcno. map ( |s| s. into ( ) ) ,
@@ -1456,15 +1459,25 @@ where
14561459 let ( mut sortables, rest) : ( Vec < _ > , Vec < _ > ) = os_string_arguments
14571460 . iter ( )
14581461 // We exclude a few arguments from the hash:
1459- // -L, --extern, --out-dir, --diagnostic-width
1462+ // -L, --extern, --out-dir, --diagnostic-width, -Cprefer-dynamic, -Cextra-filename
14601463 // These contain paths which aren't relevant to the output, and the compiler inputs
14611464 // in those paths (rlibs and static libs used in the compilation) are used as hash
1462- // inputs below.
1463- . filter ( |& ( arg, _) | {
1465+ // inputs below. -Cextra-filename is okay to exclude from the hash because we remove
1466+ // the extra component from the cache keys below (`remove_extra_filename`)
1467+ . filter ( |& ( arg, value) | {
14641468 !( arg == "--extern"
14651469 || arg == "-L"
14661470 || arg == "--out-dir"
1467- || arg == "--diagnostic-width" )
1471+ || arg == "--diagnostic-width"
1472+ || ( arg == "-C" && value == & Some ( OsString :: from ( "prefer-dynamic" ) ) )
1473+ || ( arg == "-C"
1474+ && value
1475+ . as_ref ( )
1476+ . is_some_and ( |v| v. starts_with ( "extra-filename" ) ) ) )
1477+ // prefer-dynamic never affects staticlibs or rlib
1478+ // see https://github.com/rust-lang/rust/blob/master/compiler/rustc_metadata/src/dependency_format.rs
1479+ // note that the unstable `staticlib-prefer-dynamic` affects staticlibs but it
1480+ // is an independent flag
14681481 } )
14691482 // We also exclude `--target` if it specifies a path to a .json file. The file content
14701483 // is used as hash input below.
@@ -1598,6 +1611,19 @@ where
15981611 }
15991612 }
16001613
1614+ let remove_extra_filename = |p : String | {
1615+ if let Some ( extra) = self . parsed_args . extra_filename . as_ref ( ) {
1616+ if let Some ( ( pre_ext, ext) ) = p. rsplit_once ( "." ) {
1617+ if pre_ext. ends_with ( extra) {
1618+ let pre_extra_filename = & pre_ext[ 0 ..( pre_ext. len ( ) - extra. len ( ) ) ] ;
1619+ return format ! ( "{}.{}" , pre_extra_filename, ext) ;
1620+ }
1621+ }
1622+ }
1623+
1624+ p
1625+ } ;
1626+
16011627 // Convert output files into a map of basename -> full
16021628 // path, and remove some unneeded / non-existing ones,
16031629 // see https://github.com/rust-lang/rust/pull/68799.
@@ -1606,7 +1632,7 @@ where
16061632 . map ( |o| {
16071633 let p = self . parsed_args . output_dir . join ( & o) ;
16081634 (
1609- o ,
1635+ remove_extra_filename ( o ) ,
16101636 ArtifactDescriptor {
16111637 path : p,
16121638 optional : false ,
@@ -1617,7 +1643,7 @@ where
16171643 let dep_info = if let Some ( dep_info) = & self . parsed_args . dep_info {
16181644 let p = self . parsed_args . output_dir . join ( dep_info) ;
16191645 outputs. insert (
1620- dep_info. to_string_lossy ( ) . into_owned ( ) ,
1646+ remove_extra_filename ( dep_info. to_string_lossy ( ) . into_owned ( ) ) ,
16211647 ArtifactDescriptor {
16221648 path : p. clone ( ) ,
16231649 optional : false ,
@@ -1640,7 +1666,7 @@ where
16401666 if let Some ( gcno) = & self . parsed_args . gcno {
16411667 let p = self . parsed_args . output_dir . join ( gcno) ;
16421668 outputs. insert (
1643- gcno. to_string_lossy ( ) . into_owned ( ) ,
1669+ remove_extra_filename ( gcno. to_string_lossy ( ) . into_owned ( ) ) ,
16441670 ArtifactDescriptor {
16451671 path : p,
16461672 optional : true ,
@@ -2858,6 +2884,7 @@ LLVM version: 15.0.2
28582884 ) ;
28592885 assert_eq ! ( h. output_dir. to_str( ) , Some ( "/foo/target/debug/deps" ) ) ;
28602886 assert_eq ! ( h. crate_name, "foo" ) ;
2887+ assert_eq ! ( h. extra_filename, Some ( "-d6ae26f5bcfb7733" . to_string( ) ) ) ;
28612888 assert_eq ! (
28622889 h. dep_info. unwrap( ) . to_str( ) . unwrap( ) ,
28632890 "foo-d6ae26f5bcfb7733.d"
@@ -3472,6 +3499,7 @@ proc_macro false
34723499 rlib : true ,
34733500 staticlib : false ,
34743501 } ,
3502+ extra_filename : None ,
34753503 dep_info : None ,
34763504 emit,
34773505 color_mode : ColorMode :: Auto ,
@@ -3742,7 +3770,11 @@ proc_macro false
37423770 "--crate-type" ,
37433771 "lib" ,
37443772 "-L" ,
3745- "y=y"
3773+ "y=y" ,
3774+ "-C" ,
3775+ "prefer-dynamic" ,
3776+ "-C" ,
3777+ "extra-filename=abcdabcdabcd"
37463778 ] ,
37473779 & [ ] ,
37483780 nothing,
0 commit comments