@@ -188,6 +188,8 @@ pub struct ParsedArguments {
188188 color_mode : ColorMode ,
189189 /// Whether `--json` was passed to this invocation.
190190 has_json : bool ,
191+ /// A `--target` parameter that specifies a path to a JSON file.
192+ target_json : Option < PathBuf > ,
191193}
192194
193195/// A struct on which to hang a `Compilation` impl.
@@ -1081,6 +1083,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
10811083 let mut has_json = false ;
10821084 let mut profile = None ;
10831085 let mut gcno = false ;
1086+ let mut target_json = None ;
10841087
10851088 for arg in ArgsIter :: new ( arguments. iter ( ) . cloned ( ) , & ARGS [ ..] ) {
10861089 let arg = try_or_cannot_cache ! ( arg, "argument parse" ) ;
@@ -1167,7 +1170,8 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
11671170 }
11681171 Some ( PassThrough ( _) ) => ( ) ,
11691172 Some ( Target ( target) ) => match target {
1170- ArgTarget :: Path ( _) | ArgTarget :: Unsure ( _) => cannot_cache ! ( "target" ) ,
1173+ ArgTarget :: Path ( json_path) => target_json = Some ( json_path. to_owned ( ) ) ,
1174+ ArgTarget :: Unsure ( _) => cannot_cache ! ( "target unsure" ) ,
11711175 ArgTarget :: Name ( _) => ( ) ,
11721176 } ,
11731177 None => {
@@ -1297,6 +1301,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
12971301 emit,
12981302 color_mode,
12991303 has_json,
1304+ target_json,
13001305 } )
13011306}
13021307
@@ -1339,6 +1344,7 @@ where
13391344 has_json,
13401345 profile,
13411346 gcno,
1347+ target_json,
13421348 ..
13431349 } ,
13441350 } = * self ;
@@ -1394,11 +1400,33 @@ where
13941400 let abs_staticlibs = staticlibs. iter ( ) . map ( |s| cwd. join ( s) ) . collect :: < Vec < _ > > ( ) ;
13951401 let staticlib_hashes = hash_all_archives ( & abs_staticlibs, pool) ;
13961402
1397- let ( ( source_files, source_hashes, mut env_deps) , extern_hashes, staticlib_hashes) = futures:: try_join!(
1403+ // Hash the content of the specified target json file, if any.
1404+ let mut target_json_files = Vec :: new ( ) ;
1405+ if let Some ( path) = & target_json {
1406+ trace ! (
1407+ "[{}]: hashing target json file {}" ,
1408+ crate_name,
1409+ path. display( )
1410+ ) ;
1411+ let abs_target_json = cwd. join ( path) ;
1412+ target_json_files. push ( abs_target_json) ;
1413+ }
1414+
1415+ let target_json_hash = hash_all ( & target_json_files, pool) ;
1416+
1417+ // Perform all hashing operations on the files.
1418+ let (
1419+ ( source_files, source_hashes, mut env_deps) ,
1420+ extern_hashes,
1421+ staticlib_hashes,
1422+ target_json_hash,
1423+ ) = futures:: try_join!(
13981424 source_files_and_hashes_and_env_deps,
13991425 extern_hashes,
1400- staticlib_hashes
1426+ staticlib_hashes,
1427+ target_json_hash
14011428 ) ?;
1429+
14021430 // If you change any of the inputs to the hash, you should change `CACHE_VERSION`.
14031431 let mut m = Digest :: new ( ) ;
14041432 // Hash inputs:
@@ -1424,6 +1452,10 @@ where
14241452 // in those paths (rlibs and static libs used in the compilation) are used as hash
14251453 // inputs below.
14261454 . filter ( |& ( arg, _) | !( arg == "--extern" || arg == "-L" || arg == "--out-dir" ) )
1455+ // We also exclude `--target` if it specifies a path to a .json file. The file content
1456+ // is used as hash input below.
1457+ // If `--target` specifies a string, it continues to be hashed as part of the arguments.
1458+ . filter ( |& ( arg, _) | target_json. is_none ( ) || arg != "--target" )
14271459 // A few argument types were not passed in a deterministic order
14281460 // by older versions of cargo: --extern, -L, --cfg. We'll filter the rest of those
14291461 // out, sort them, and append them to the rest of the arguments.
@@ -1441,14 +1473,16 @@ where
14411473 // 4. The digest of all source files (this includes src file from cmdline).
14421474 // 5. The digest of all files listed on the commandline (self.externs).
14431475 // 6. The digest of all static libraries listed on the commandline (self.staticlibs).
1476+ // 7. The digest of the content of the target json file specified via `--target` (if any).
14441477 for h in source_hashes
14451478 . into_iter ( )
14461479 . chain ( extern_hashes)
14471480 . chain ( staticlib_hashes)
1481+ . chain ( target_json_hash)
14481482 {
14491483 m. update ( h. as_bytes ( ) ) ;
14501484 }
1451- // 7 . Environment variables: Hash all environment variables listed in the rustc dep-info
1485+ // 8 . Environment variables: Hash all environment variables listed in the rustc dep-info
14521486 // output. Additionally also has all environment variables starting with `CARGO_`,
14531487 // since those are not listed in dep-info but affect cacheability.
14541488 env_deps. sort ( ) ;
@@ -1482,9 +1516,9 @@ where
14821516 m. update ( b"=" ) ;
14831517 val. hash ( & mut HashToDigest { digest : & mut m } ) ;
14841518 }
1485- // 8 . The cwd of the compile. This will wind up in the rlib.
1519+ // 9 . The cwd of the compile. This will wind up in the rlib.
14861520 cwd. hash ( & mut HashToDigest { digest : & mut m } ) ;
1487- // 9 . The version of the compiler.
1521+ // 10 . The version of the compiler.
14881522 version. hash ( & mut HashToDigest { digest : & mut m } ) ;
14891523
14901524 // Turn arguments into a simple Vec<OsString> to calculate outputs.
@@ -3391,6 +3425,7 @@ proc_macro false
33913425 has_json : false ,
33923426 profile : None ,
33933427 gcno : None ,
3428+ target_json : None ,
33943429 } ,
33953430 } ) ;
33963431 let creator = new_creator ( ) ;
@@ -3763,4 +3798,47 @@ proc_macro false
37633798
37643799 assert_eq ! ( h. gcno, Some ( "foo-a1b6419f8321841f.gcno" . into( ) ) ) ;
37653800 }
3801+
3802+ #[ test]
3803+ fn test_parse_target ( ) {
3804+ // Parse a --target argument that is a string (not a path to a .json file).
3805+ let h = parses ! (
3806+ "--crate-name" ,
3807+ "foo" ,
3808+ "--crate-type" ,
3809+ "lib" ,
3810+ "./src/lib.rs" ,
3811+ "--emit=dep-info,link" ,
3812+ "--out-dir" ,
3813+ "/out" ,
3814+ "--target" ,
3815+ "string"
3816+ ) ;
3817+ assert ! ( h. arguments. contains( & Argument :: WithValue (
3818+ "--target" ,
3819+ ArgData :: Target ( ArgTarget :: Name ( "string" . to_owned( ) ) ) ,
3820+ ArgDisposition :: Separated
3821+ ) ) ) ;
3822+ assert ! ( h. target_json. is_none( ) ) ;
3823+
3824+ // Parse a --target argument that is a path.
3825+ let h = parses ! (
3826+ "--crate-name" ,
3827+ "foo" ,
3828+ "--crate-type" ,
3829+ "lib" ,
3830+ "./src/lib.rs" ,
3831+ "--emit=dep-info,link" ,
3832+ "--out-dir" ,
3833+ "/out" ,
3834+ "--target" ,
3835+ "/path/to/target.json"
3836+ ) ;
3837+ assert ! ( h. arguments. contains( & Argument :: WithValue (
3838+ "--target" ,
3839+ ArgData :: Target ( ArgTarget :: Path ( PathBuf :: from( "/path/to/target.json" ) ) ) ,
3840+ ArgDisposition :: Separated
3841+ ) ) ) ;
3842+ assert_eq ! ( h. target_json, Some ( PathBuf :: from( "/path/to/target.json" ) ) ) ;
3843+ }
37663844}
0 commit comments