@@ -28,6 +28,7 @@ pub struct BuildOutput {
28
28
/// Metadata to pass to the immediate dependencies
29
29
pub metadata : Vec < ( String , String ) > ,
30
30
/// Paths to trigger a rerun of this build script.
31
+ /// May be absolute or relative paths (relative to package root).
31
32
pub rerun_if_changed : Vec < PathBuf > ,
32
33
/// Environment variables which, when changed, will cause a rebuild.
33
34
pub rerun_if_env_changed : Vec < String > ,
@@ -129,8 +130,8 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
129
130
. iter ( )
130
131
. find ( |d| !d. mode . is_run_custom_build ( ) && d. target . is_custom_build ( ) )
131
132
. expect ( "running a script not depending on an actual script" ) ;
132
- let script_output = cx. files ( ) . build_script_dir ( build_script_unit) ;
133
- let build_output = cx. files ( ) . build_script_out_dir ( unit) ;
133
+ let script_dir = cx. files ( ) . build_script_dir ( build_script_unit) ;
134
+ let script_out_dir = cx. files ( ) . build_script_out_dir ( unit) ;
134
135
let build_plan = bcx. build_config . build_plan ;
135
136
let invocation_name = unit. buildkey ( ) ;
136
137
@@ -139,7 +140,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
139
140
}
140
141
141
142
// Building the command to execute
142
- let to_exec = script_output . join ( unit. target . name ( ) ) ;
143
+ let to_exec = script_dir . join ( unit. target . name ( ) ) ;
143
144
144
145
// Start preparing the process to execute, starting out with some
145
146
// environment variables. Note that the profile-related environment
@@ -151,7 +152,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
151
152
let to_exec = to_exec. into_os_string ( ) ;
152
153
let mut cmd = cx. compilation . host_process ( to_exec, unit. pkg ) ?;
153
154
let debug = unit. profile . debuginfo . unwrap_or ( 0 ) != 0 ;
154
- cmd. env ( "OUT_DIR" , & build_output )
155
+ cmd. env ( "OUT_DIR" , & script_out_dir )
155
156
. env ( "CARGO_MANIFEST_DIR" , unit. pkg . root ( ) )
156
157
. env ( "NUM_JOBS" , & bcx. jobs ( ) . to_string ( ) )
157
158
. env (
@@ -241,19 +242,19 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
241
242
let build_state = Arc :: clone ( & cx. build_state ) ;
242
243
let id = unit. pkg . package_id ( ) . clone ( ) ;
243
244
let ( output_file, err_file, root_output_file) = {
244
- let build_output_parent = build_output . parent ( ) . unwrap ( ) ;
245
+ let build_output_parent = script_out_dir . parent ( ) . unwrap ( ) ;
245
246
let output_file = build_output_parent. join ( "output" ) ;
246
247
let err_file = build_output_parent. join ( "stderr" ) ;
247
248
let root_output_file = build_output_parent. join ( "root-output" ) ;
248
249
( output_file, err_file, root_output_file)
249
250
} ;
250
- let root_output = cx. files ( ) . target_root ( ) . to_path_buf ( ) ;
251
+ let host_target_root = cx. files ( ) . target_root ( ) . to_path_buf ( ) ;
251
252
let all = (
252
253
id. clone ( ) ,
253
254
pkg_name. clone ( ) ,
254
255
Arc :: clone ( & build_state) ,
255
256
output_file. clone ( ) ,
256
- root_output . clone ( ) ,
257
+ script_out_dir . clone ( ) ,
257
258
) ;
258
259
let build_scripts = super :: load_build_deps ( cx, unit) ;
259
260
let kind = unit. kind ;
@@ -262,16 +263,17 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
262
263
263
264
// Check to see if the build script has already run, and if it has keep
264
265
// track of whether it has told us about some explicit dependencies
265
- let prev_root_output = paths:: read_bytes ( & root_output_file)
266
+ let prev_script_out_dir = paths:: read_bytes ( & root_output_file)
266
267
. and_then ( |bytes| util:: bytes2path ( & bytes) )
267
- . unwrap_or_else ( |_| cmd. get_cwd ( ) . unwrap ( ) . to_path_buf ( ) ) ;
268
+ . unwrap_or_else ( |_| script_out_dir. clone ( ) ) ;
269
+
268
270
let prev_output =
269
- BuildOutput :: parse_file ( & output_file, & pkg_name, & prev_root_output , & root_output ) . ok ( ) ;
271
+ BuildOutput :: parse_file ( & output_file, & pkg_name, & prev_script_out_dir , & script_out_dir ) . ok ( ) ;
270
272
let deps = BuildDeps :: new ( & output_file, prev_output. as_ref ( ) ) ;
271
273
cx. build_explicit_deps . insert ( * unit, deps) ;
272
274
273
- fs:: create_dir_all ( & script_output ) ?;
274
- fs:: create_dir_all ( & build_output ) ?;
275
+ fs:: create_dir_all ( & script_dir ) ?;
276
+ fs:: create_dir_all ( & script_out_dir ) ?;
275
277
276
278
// Prepare the unit of "dirty work" which will actually run the custom build
277
279
// command.
@@ -283,8 +285,8 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
283
285
//
284
286
// If we have an old build directory, then just move it into place,
285
287
// otherwise create it!
286
- if fs:: metadata ( & build_output ) . is_err ( ) {
287
- fs:: create_dir ( & build_output ) . chain_err ( || {
288
+ if fs:: metadata ( & script_out_dir ) . is_err ( ) {
289
+ fs:: create_dir ( & script_out_dir ) . chain_err ( || {
288
290
internal (
289
291
"failed to create script output directory for \
290
292
build command",
@@ -316,7 +318,7 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
316
318
}
317
319
}
318
320
if let Some ( build_scripts) = build_scripts {
319
- super :: add_plugin_deps ( & mut cmd, & build_state, & build_scripts, & root_output ) ?;
321
+ super :: add_plugin_deps ( & mut cmd, & build_state, & build_scripts, & host_target_root ) ?;
320
322
}
321
323
}
322
324
@@ -348,9 +350,9 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
348
350
// well.
349
351
paths:: write ( & output_file, & output. stdout ) ?;
350
352
paths:: write ( & err_file, & output. stderr ) ?;
351
- paths:: write ( & root_output_file, util:: path2bytes ( & root_output ) ?) ?;
353
+ paths:: write ( & root_output_file, util:: path2bytes ( & script_out_dir ) ?) ?;
352
354
let parsed_output =
353
- BuildOutput :: parse ( & output. stdout , & pkg_name, & root_output , & root_output ) ?;
355
+ BuildOutput :: parse ( & output. stdout , & pkg_name, & script_out_dir , & script_out_dir ) ?;
354
356
355
357
if json_messages {
356
358
emit_build_output ( & parsed_output, & id) ;
@@ -364,11 +366,11 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
364
366
// itself to run when we actually end up just discarding what we calculated
365
367
// above.
366
368
let fresh = Work :: new ( move |_tx| {
367
- let ( id, pkg_name, build_state, output_file, root_output ) = all;
369
+ let ( id, pkg_name, build_state, output_file, script_out_dir ) = all;
368
370
let output = match prev_output {
369
371
Some ( output) => output,
370
372
None => {
371
- BuildOutput :: parse_file ( & output_file, & pkg_name, & prev_root_output , & root_output ) ?
373
+ BuildOutput :: parse_file ( & output_file, & pkg_name, & prev_script_out_dir , & script_out_dir ) ?
372
374
}
373
375
} ;
374
376
@@ -406,20 +408,20 @@ impl BuildOutput {
406
408
pub fn parse_file (
407
409
path : & Path ,
408
410
pkg_name : & str ,
409
- root_output_when_generated : & Path ,
410
- root_output : & Path ,
411
+ script_out_dir_when_generated : & Path ,
412
+ script_out_dir : & Path ,
411
413
) -> CargoResult < BuildOutput > {
412
414
let contents = paths:: read_bytes ( path) ?;
413
- BuildOutput :: parse ( & contents, pkg_name, root_output_when_generated , root_output )
415
+ BuildOutput :: parse ( & contents, pkg_name, script_out_dir_when_generated , script_out_dir )
414
416
}
415
417
416
418
// Parses the output of a script.
417
419
// The `pkg_name` is used for error messages.
418
420
pub fn parse (
419
421
input : & [ u8 ] ,
420
422
pkg_name : & str ,
421
- root_output_when_generated : & Path ,
422
- root_output : & Path ,
423
+ script_out_dir_when_generated : & Path ,
424
+ script_out_dir : & Path ,
423
425
) -> CargoResult < BuildOutput > {
424
426
let mut library_paths = Vec :: new ( ) ;
425
427
let mut library_links = Vec :: new ( ) ;
@@ -456,23 +458,24 @@ impl BuildOutput {
456
458
_ => bail ! ( "Wrong output in {}: `{}`" , whence, line) ,
457
459
} ;
458
460
459
- let path = |val : & str | match Path :: new ( val) . strip_prefix ( root_output_when_generated) {
460
- Ok ( path) => root_output. join ( path) ,
461
- Err ( _) => PathBuf :: from ( val) ,
462
- } ;
461
+ // This will rewrite paths if the target directory has been moved.
462
+ let value = value. replace (
463
+ script_out_dir_when_generated. to_str ( ) . unwrap ( ) ,
464
+ script_out_dir. to_str ( ) . unwrap ( ) ,
465
+ ) ;
463
466
464
467
match key {
465
468
"rustc-flags" => {
466
- let ( paths, links) = BuildOutput :: parse_rustc_flags ( value, & whence) ?;
469
+ let ( paths, links) = BuildOutput :: parse_rustc_flags ( & value, & whence) ?;
467
470
library_links. extend ( links. into_iter ( ) ) ;
468
471
library_paths. extend ( paths. into_iter ( ) ) ;
469
472
}
470
473
"rustc-link-lib" => library_links. push ( value. to_string ( ) ) ,
471
- "rustc-link-search" => library_paths. push ( path ( value) ) ,
474
+ "rustc-link-search" => library_paths. push ( PathBuf :: from ( value) ) ,
472
475
"rustc-cfg" => cfgs. push ( value. to_string ( ) ) ,
473
- "rustc-env" => env. push ( BuildOutput :: parse_rustc_env ( value, & whence) ?) ,
476
+ "rustc-env" => env. push ( BuildOutput :: parse_rustc_env ( & value, & whence) ?) ,
474
477
"warning" => warnings. push ( value. to_string ( ) ) ,
475
- "rerun-if-changed" => rerun_if_changed. push ( path ( value) ) ,
478
+ "rerun-if-changed" => rerun_if_changed. push ( PathBuf :: from ( value) ) ,
476
479
"rerun-if-env-changed" => rerun_if_env_changed. push ( value. to_string ( ) ) ,
477
480
_ => metadata. push ( ( key. to_string ( ) , value. to_string ( ) ) ) ,
478
481
}
0 commit comments