@@ -549,7 +549,7 @@ impl LocalFingerprint {
549
549
// unit has never been compiled!
550
550
LocalFingerprint :: CheckDepInfo { dep_info } => {
551
551
let dep_info = target_root. join ( dep_info) ;
552
- if let Some ( paths) = parse_dep_info ( pkg_root, & dep_info) ? {
552
+ if let Some ( paths) = parse_dep_info ( pkg_root, target_root , & dep_info) ? {
553
553
Ok ( find_stale_file ( & dep_info, paths. iter ( ) ) )
554
554
} else {
555
555
Ok ( Some ( StaleFile :: Missing ( dep_info) ) )
@@ -1408,15 +1408,30 @@ fn log_compare(unit: &Unit<'_>, compare: &CargoResult<()>) {
1408
1408
}
1409
1409
1410
1410
// Parse the dep-info into a list of paths
1411
- pub fn parse_dep_info ( pkg_root : & Path , dep_info : & Path ) -> CargoResult < Option < Vec < PathBuf > > > {
1411
+ pub fn parse_dep_info (
1412
+ pkg_root : & Path ,
1413
+ target_root : & Path ,
1414
+ dep_info : & Path ,
1415
+ ) -> CargoResult < Option < Vec < PathBuf > > > {
1412
1416
let data = match paths:: read_bytes ( dep_info) {
1413
1417
Ok ( data) => data,
1414
1418
Err ( _) => return Ok ( None ) ,
1415
1419
} ;
1416
1420
let paths = data
1417
1421
. split ( |& x| x == 0 )
1418
1422
. filter ( |x| !x. is_empty ( ) )
1419
- . map ( |p| util:: bytes2path ( p) . map ( |p| pkg_root. join ( p) ) )
1423
+ . map ( |p| {
1424
+ let ty = match DepInfoPathType :: from_byte ( p[ 0 ] ) {
1425
+ Some ( ty) => ty,
1426
+ None => return Err ( internal ( "dep-info invalid" ) ) ,
1427
+ } ;
1428
+ let path = util:: bytes2path ( & p[ 1 ..] ) ?;
1429
+ match ty {
1430
+ DepInfoPathType :: PackageRootRelative => Ok ( pkg_root. join ( path) ) ,
1431
+ // N.B. path might be absolute here in which case the join will have no effect
1432
+ DepInfoPathType :: TargetRootRelative => Ok ( target_root. join ( path) ) ,
1433
+ }
1434
+ } )
1420
1435
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
1421
1436
if paths. is_empty ( ) {
1422
1437
Ok ( None )
@@ -1503,6 +1518,25 @@ fn filename<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> String {
1503
1518
format ! ( "{}{}-{}" , flavor, kind, file_stem)
1504
1519
}
1505
1520
1521
+ #[ repr( u8 ) ]
1522
+ enum DepInfoPathType {
1523
+ // src/, e.g. src/lib.rs
1524
+ PackageRootRelative = 1 ,
1525
+ // target/debug/deps/lib...
1526
+ // or an absolute path /.../sysroot/...
1527
+ TargetRootRelative = 2 ,
1528
+ }
1529
+
1530
+ impl DepInfoPathType {
1531
+ fn from_byte ( b : u8 ) -> Option < DepInfoPathType > {
1532
+ match b {
1533
+ 1 => Some ( DepInfoPathType :: PackageRootRelative ) ,
1534
+ 2 => Some ( DepInfoPathType :: TargetRootRelative ) ,
1535
+ _ => None ,
1536
+ }
1537
+ }
1538
+ }
1539
+
1506
1540
/// Parses the dep-info file coming out of rustc into a Cargo-specific format.
1507
1541
///
1508
1542
/// This function will parse `rustc_dep_info` as a makefile-style dep info to
@@ -1522,8 +1556,9 @@ fn filename<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> String {
1522
1556
pub fn translate_dep_info (
1523
1557
rustc_dep_info : & Path ,
1524
1558
cargo_dep_info : & Path ,
1525
- pkg_root : & Path ,
1526
1559
rustc_cwd : & Path ,
1560
+ pkg_root : & Path ,
1561
+ target_root : & Path ,
1527
1562
) -> CargoResult < ( ) > {
1528
1563
let target = parse_rustc_dep_info ( rustc_dep_info) ?;
1529
1564
let deps = & target
@@ -1533,9 +1568,20 @@ pub fn translate_dep_info(
1533
1568
1534
1569
let mut new_contents = Vec :: new ( ) ;
1535
1570
for file in deps {
1536
- let absolute = rustc_cwd. join ( file) ;
1537
- let path = absolute. strip_prefix ( pkg_root) . unwrap_or ( & absolute) ;
1538
- new_contents. extend ( util:: path2bytes ( path) ?) ;
1571
+ let file = rustc_cwd. join ( file) ;
1572
+ let ( ty, path) = if let Ok ( stripped) = file. strip_prefix ( pkg_root) {
1573
+ ( DepInfoPathType :: PackageRootRelative , stripped)
1574
+ } else if let Ok ( stripped) = file. strip_prefix ( target_root) {
1575
+ ( DepInfoPathType :: TargetRootRelative , stripped)
1576
+ } else {
1577
+ // It's definitely not target root relative, but this is an absolute path (since it was
1578
+ // joined to rustc_cwd) and as such re-joining it later to the target root will have no
1579
+ // effect.
1580
+ assert ! ( file. is_absolute( ) , "{:?} is absolute" , file) ;
1581
+ ( DepInfoPathType :: TargetRootRelative , & * file)
1582
+ } ;
1583
+ new_contents. push ( ty as u8 ) ;
1584
+ new_contents. extend ( util:: path2bytes ( & path) ?) ;
1539
1585
new_contents. push ( 0 ) ;
1540
1586
}
1541
1587
paths:: write ( cargo_dep_info, & new_contents) ?;
0 commit comments