@@ -7,7 +7,7 @@ use std::sync::{Mutex, Arc};
7
7
use core:: PackageId ;
8
8
use util:: { Freshness , Cfg } ;
9
9
use util:: errors:: { CargoResult , CargoResultExt , CargoError } ;
10
- use util:: { internal, profile, paths} ;
10
+ use util:: { self , internal, profile, paths} ;
11
11
use util:: machine_message;
12
12
13
13
use super :: job:: Work ;
@@ -27,7 +27,7 @@ pub struct BuildOutput {
27
27
/// Metadata to pass to the immediate dependencies
28
28
pub metadata : Vec < ( String , String ) > ,
29
29
/// Paths to trigger a rerun of this build script.
30
- pub rerun_if_changed : Vec < String > ,
30
+ pub rerun_if_changed : Vec < PathBuf > ,
31
31
/// Environment variables which, when changed, will cause a rebuild.
32
32
pub rerun_if_env_changed : Vec < String > ,
33
33
/// Warnings generated by this build,
@@ -65,7 +65,7 @@ pub struct BuildScripts {
65
65
66
66
pub struct BuildDeps {
67
67
pub build_script_output : PathBuf ,
68
- pub rerun_if_changed : Vec < String > ,
68
+ pub rerun_if_changed : Vec < PathBuf > ,
69
69
pub rerun_if_env_changed : Vec < String > ,
70
70
}
71
71
@@ -178,29 +178,37 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
178
178
let pkg_name = unit. pkg . to_string ( ) ;
179
179
let build_state = Arc :: clone ( & cx. build_state ) ;
180
180
let id = unit. pkg . package_id ( ) . clone ( ) ;
181
- let ( output_file, err_file) = {
181
+ let ( output_file, err_file, root_output_file ) = {
182
182
let build_output_parent = build_output. parent ( ) . unwrap ( ) ;
183
183
let output_file = build_output_parent. join ( "output" ) ;
184
184
let err_file = build_output_parent. join ( "stderr" ) ;
185
- ( output_file, err_file)
185
+ let root_output_file = build_output_parent. join ( "root-output" ) ;
186
+ ( output_file, err_file, root_output_file)
186
187
} ;
188
+ let root_output = cx. target_root ( ) . to_path_buf ( ) ;
187
189
let all = ( id. clone ( ) , pkg_name. clone ( ) , Arc :: clone ( & build_state) ,
188
- output_file. clone ( ) ) ;
190
+ output_file. clone ( ) , root_output . clone ( ) ) ;
189
191
let build_scripts = super :: load_build_deps ( cx, unit) ;
190
192
let kind = unit. kind ;
191
193
let json_messages = cx. build_config . json_messages ;
192
194
193
195
// Check to see if the build script has already run, and if it has keep
194
196
// track of whether it has told us about some explicit dependencies
195
- let prev_output = BuildOutput :: parse_file ( & output_file, & pkg_name) . ok ( ) ;
197
+ let prev_root_output = paths:: read_bytes ( & root_output_file)
198
+ . and_then ( |bytes| util:: bytes2path ( & bytes) )
199
+ . unwrap_or ( cmd. get_cwd ( ) . unwrap ( ) . to_path_buf ( ) ) ;
200
+ let prev_output = BuildOutput :: parse_file (
201
+ & output_file,
202
+ & pkg_name,
203
+ & prev_root_output,
204
+ & root_output,
205
+ ) . ok ( ) ;
196
206
let deps = BuildDeps :: new ( & output_file, prev_output. as_ref ( ) ) ;
197
207
cx. build_explicit_deps . insert ( * unit, deps) ;
198
208
199
209
fs:: create_dir_all ( & script_output) ?;
200
210
fs:: create_dir_all ( & build_output) ?;
201
211
202
- let root_output = cx. target_root ( ) . to_path_buf ( ) ;
203
-
204
212
// Prepare the unit of "dirty work" which will actually run the custom build
205
213
// command.
206
214
//
@@ -266,7 +274,13 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
266
274
// well.
267
275
paths:: write ( & output_file, & output. stdout ) ?;
268
276
paths:: write ( & err_file, & output. stderr ) ?;
269
- let parsed_output = BuildOutput :: parse ( & output. stdout , & pkg_name) ?;
277
+ paths:: write ( & root_output_file, & util:: path2bytes ( & root_output) ?) ?;
278
+ let parsed_output = BuildOutput :: parse (
279
+ & output. stdout ,
280
+ & pkg_name,
281
+ & root_output,
282
+ & root_output,
283
+ ) ?;
270
284
271
285
if json_messages {
272
286
let library_paths = parsed_output. library_paths . iter ( ) . map ( |l| {
@@ -289,10 +303,17 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
289
303
// itself to run when we actually end up just discarding what we calculated
290
304
// above.
291
305
let fresh = Work :: new ( move |_tx| {
292
- let ( id, pkg_name, build_state, output_file) = all;
306
+ let ( id, pkg_name, build_state, output_file, root_output ) = all;
293
307
let output = match prev_output {
294
308
Some ( output) => output,
295
- None => BuildOutput :: parse_file ( & output_file, & pkg_name) ?,
309
+ None => {
310
+ BuildOutput :: parse_file (
311
+ & output_file,
312
+ & pkg_name,
313
+ & prev_root_output,
314
+ & root_output,
315
+ ) ?
316
+ }
296
317
} ;
297
318
build_state. insert ( id, kind, output) ;
298
319
Ok ( ( ) )
@@ -321,14 +342,20 @@ impl BuildState {
321
342
}
322
343
323
344
impl BuildOutput {
324
- pub fn parse_file ( path : & Path , pkg_name : & str ) -> CargoResult < BuildOutput > {
345
+ pub fn parse_file ( path : & Path ,
346
+ pkg_name : & str ,
347
+ root_output_when_generated : & Path ,
348
+ root_output : & Path ) -> CargoResult < BuildOutput > {
325
349
let contents = paths:: read_bytes ( path) ?;
326
- BuildOutput :: parse ( & contents, pkg_name)
350
+ BuildOutput :: parse ( & contents, pkg_name, root_output_when_generated , root_output )
327
351
}
328
352
329
353
// Parses the output of a script.
330
354
// The `pkg_name` is used for error messages.
331
- pub fn parse ( input : & [ u8 ] , pkg_name : & str ) -> CargoResult < BuildOutput > {
355
+ pub fn parse ( input : & [ u8 ] ,
356
+ pkg_name : & str ,
357
+ root_output_when_generated : & Path ,
358
+ root_output : & Path ) -> CargoResult < BuildOutput > {
332
359
let mut library_paths = Vec :: new ( ) ;
333
360
let mut library_links = Vec :: new ( ) ;
334
361
let mut cfgs = Vec :: new ( ) ;
@@ -364,6 +391,13 @@ impl BuildOutput {
364
391
_ => bail ! ( "Wrong output in {}: `{}`" , whence, line) ,
365
392
} ;
366
393
394
+ let path = |val : & str | {
395
+ match Path :: new ( val) . strip_prefix ( root_output_when_generated) {
396
+ Ok ( path) => root_output. join ( path) ,
397
+ Err ( _) => PathBuf :: from ( val) ,
398
+ }
399
+ } ;
400
+
367
401
match key {
368
402
"rustc-flags" => {
369
403
let ( paths, links) =
@@ -372,11 +406,11 @@ impl BuildOutput {
372
406
library_paths. extend ( paths. into_iter ( ) ) ;
373
407
}
374
408
"rustc-link-lib" => library_links. push ( value. to_string ( ) ) ,
375
- "rustc-link-search" => library_paths. push ( PathBuf :: from ( value) ) ,
409
+ "rustc-link-search" => library_paths. push ( path ( value) ) ,
376
410
"rustc-cfg" => cfgs. push ( value. to_string ( ) ) ,
377
411
"rustc-env" => env. push ( BuildOutput :: parse_rustc_env ( value, & whence) ?) ,
378
412
"warning" => warnings. push ( value. to_string ( ) ) ,
379
- "rerun-if-changed" => rerun_if_changed. push ( value . to_string ( ) ) ,
413
+ "rerun-if-changed" => rerun_if_changed. push ( path ( value ) ) ,
380
414
"rerun-if-env-changed" => rerun_if_env_changed. push ( value. to_string ( ) ) ,
381
415
_ => metadata. push ( ( key. to_string ( ) , value. to_string ( ) ) ) ,
382
416
}
0 commit comments