1
1
use std:: collections:: HashSet ;
2
- use std:: io:: { Write , BufWriter } ;
3
- use std:: fs:: File ;
2
+ use std:: io:: { Write , BufWriter , ErrorKind } ;
3
+ use std:: fs:: { self , File } ;
4
4
use std:: path:: { Path , PathBuf } ;
5
5
6
6
use ops:: { Context , Unit } ;
@@ -22,17 +22,20 @@ fn render_filename<P: AsRef<Path>>(path: P, basedir: Option<&str>) -> CargoResul
22
22
fn add_deps_for_unit < ' a , ' b > ( deps : & mut HashSet < PathBuf > , context : & mut Context < ' a , ' b > ,
23
23
unit : & Unit < ' a > , visited : & mut HashSet < Unit < ' a > > ) -> CargoResult < ( ) >
24
24
{
25
- if visited. contains ( unit) {
25
+ if ! visited. insert ( unit. clone ( ) ) {
26
26
return Ok ( ( ) ) ;
27
27
}
28
- visited. insert ( unit. clone ( ) ) ;
29
28
30
29
// Add dependencies from rustc dep-info output (stored in fingerprint directory)
31
30
let dep_info_loc = fingerprint:: dep_info_loc ( context, unit) ;
32
31
if let Some ( paths) = fingerprint:: parse_dep_info ( & dep_info_loc) ? {
33
32
for path in paths {
34
33
deps. insert ( path) ;
35
34
}
35
+ } else {
36
+ debug ! ( "can't find dep_info for {:?} {:?}" ,
37
+ unit. pkg. package_id( ) , unit. profile) ;
38
+ return Err ( internal ( "dep_info missing" ) ) ;
36
39
}
37
40
38
41
// Add rerun-if-changed dependencies
@@ -56,18 +59,32 @@ fn add_deps_for_unit<'a, 'b>(deps: &mut HashSet<PathBuf>, context: &mut Context<
56
59
pub fn output_depinfo < ' a , ' b > ( context : & mut Context < ' a , ' b > , unit : & Unit < ' a > ) -> CargoResult < ( ) > {
57
60
let mut deps = HashSet :: new ( ) ;
58
61
let mut visited = HashSet :: new ( ) ;
59
- add_deps_for_unit ( & mut deps, context, unit, & mut visited) ? ;
62
+ let success = add_deps_for_unit ( & mut deps, context, unit, & mut visited) . is_ok ( ) ;
60
63
let basedir = None ; // TODO
61
64
for ( _filename, link_dst, _linkable) in context. target_filenames ( unit) ? {
62
65
if let Some ( link_dst) = link_dst {
63
66
let output_path = link_dst. with_extension ( "d" ) ;
64
- let target_fn = render_filename ( link_dst, basedir) ?;
65
- let mut outfile = BufWriter :: new ( File :: create ( output_path) ?) ;
66
- write ! ( outfile, "{}:" , target_fn) ?;
67
- for dep in & deps {
68
- write ! ( outfile, " {}" , render_filename( dep, basedir) ?) ?;
67
+ if success {
68
+ let mut outfile = BufWriter :: new ( File :: create ( output_path) ?) ;
69
+ let target_fn = render_filename ( link_dst, basedir) ?;
70
+ write ! ( outfile, "{}:" , target_fn) ?;
71
+ for dep in & deps {
72
+ write ! ( outfile, " {}" , render_filename( dep, basedir) ?) ?;
73
+ }
74
+ writeln ! ( outfile, "" ) ?;
75
+ } else {
76
+ // dep-info generation failed, so delete output file. This will usually
77
+ // cause the build system to always rerun the build rule, which is correct
78
+ // if inefficient.
79
+ match fs:: remove_file ( output_path) {
80
+ Err ( err) => {
81
+ if err. kind ( ) != ErrorKind :: NotFound {
82
+ return Err ( err. into ( ) ) ;
83
+ }
84
+ }
85
+ _ => ( )
86
+ }
69
87
}
70
- writeln ! ( outfile, "" ) ?;
71
88
}
72
89
}
73
90
Ok ( ( ) )
0 commit comments