@@ -2,11 +2,11 @@ use super::job::{Freshness, Job, Work};
2
2
use super :: { fingerprint, Context , LinkType , Unit } ;
3
3
use crate :: core:: compiler:: context:: Metadata ;
4
4
use crate :: core:: compiler:: job_queue:: JobState ;
5
- use crate :: core:: { profiles:: ProfileRoot , PackageId } ;
5
+ use crate :: core:: { profiles:: ProfileRoot , PackageId , Target } ;
6
6
use crate :: util:: errors:: CargoResult ;
7
7
use crate :: util:: machine_message:: { self , Message } ;
8
8
use crate :: util:: { internal, profile} ;
9
- use anyhow:: Context as _;
9
+ use anyhow:: { bail , Context as _} ;
10
10
use cargo_platform:: Cfg ;
11
11
use cargo_util:: paths;
12
12
use std:: collections:: hash_map:: { Entry , HashMap } ;
@@ -296,6 +296,9 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
296
296
297
297
let extra_link_arg = cx. bcx . config . cli_unstable ( ) . extra_link_arg ;
298
298
let nightly_features_allowed = cx. bcx . config . nightly_features_allowed ;
299
+ let targets: Vec < Target > = unit. pkg . targets ( ) . iter ( ) . cloned ( ) . collect ( ) ;
300
+ // Need a separate copy for the fresh closure.
301
+ let targets_fresh = targets. clone ( ) ;
299
302
300
303
// Prepare the unit of "dirty work" which will actually run the custom build
301
304
// command.
@@ -405,6 +408,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
405
408
& script_out_dir,
406
409
extra_link_arg,
407
410
nightly_features_allowed,
411
+ & targets,
408
412
) ?;
409
413
410
414
if json_messages {
@@ -432,6 +436,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
432
436
& script_out_dir,
433
437
extra_link_arg,
434
438
nightly_features_allowed,
439
+ & targets_fresh,
435
440
) ?,
436
441
} ;
437
442
@@ -484,6 +489,7 @@ impl BuildOutput {
484
489
script_out_dir : & Path ,
485
490
extra_link_arg : bool ,
486
491
nightly_features_allowed : bool ,
492
+ targets : & [ Target ] ,
487
493
) -> CargoResult < BuildOutput > {
488
494
let contents = paths:: read_bytes ( path) ?;
489
495
BuildOutput :: parse (
@@ -494,6 +500,7 @@ impl BuildOutput {
494
500
script_out_dir,
495
501
extra_link_arg,
496
502
nightly_features_allowed,
503
+ targets,
497
504
)
498
505
}
499
506
@@ -509,6 +516,7 @@ impl BuildOutput {
509
516
script_out_dir : & Path ,
510
517
extra_link_arg : bool ,
511
518
nightly_features_allowed : bool ,
519
+ targets : & [ Target ] ,
512
520
) -> CargoResult < BuildOutput > {
513
521
let mut library_paths = Vec :: new ( ) ;
514
522
let mut library_links = Vec :: new ( ) ;
@@ -543,7 +551,7 @@ impl BuildOutput {
543
551
let ( key, value) = match ( key, value) {
544
552
( Some ( a) , Some ( b) ) => ( a, b. trim_end ( ) ) ,
545
553
// Line started with `cargo:` but didn't match `key=value`.
546
- _ => anyhow :: bail!( "Wrong output in {}: `{}`" , whence, line) ,
554
+ _ => bail ! ( "Wrong output in {}: `{}`" , whence, line) ,
547
555
} ;
548
556
549
557
// This will rewrite paths if the target directory has been moved.
@@ -552,7 +560,7 @@ impl BuildOutput {
552
560
script_out_dir. to_str ( ) . unwrap ( ) ,
553
561
) ;
554
562
555
- // Keep in sync with TargetConfig::new .
563
+ // Keep in sync with TargetConfig::parse_links_overrides .
556
564
match key {
557
565
"rustc-flags" => {
558
566
let ( paths, links) = BuildOutput :: parse_rustc_flags ( & value, & whence) ?;
@@ -562,29 +570,61 @@ impl BuildOutput {
562
570
"rustc-link-lib" => library_links. push ( value. to_string ( ) ) ,
563
571
"rustc-link-search" => library_paths. push ( PathBuf :: from ( value) ) ,
564
572
"rustc-link-arg-cdylib" | "rustc-cdylib-link-arg" => {
573
+ if !targets. iter ( ) . any ( |target| target. is_cdylib ( ) ) {
574
+ bail ! (
575
+ "invalid instruction `cargo:{}` from {}\n \
576
+ The package {} does not have a cdylib target.",
577
+ key,
578
+ whence,
579
+ pkg_descr
580
+ ) ;
581
+ }
565
582
linker_args. push ( ( LinkType :: Cdylib , value) )
566
583
}
567
584
"rustc-link-arg-bins" => {
568
585
if extra_link_arg {
586
+ if !targets. iter ( ) . any ( |target| target. is_bin ( ) ) {
587
+ bail ! (
588
+ "invalid instruction `cargo:{}` from {}\n \
589
+ The package {} does not have a bin target.",
590
+ key,
591
+ whence,
592
+ pkg_descr
593
+ ) ;
594
+ }
569
595
linker_args. push ( ( LinkType :: Bin , value) ) ;
570
596
} else {
571
597
warnings. push ( format ! ( "cargo:{} requires -Zextra-link-arg flag" , key) ) ;
572
598
}
573
599
}
574
600
"rustc-link-arg-bin" => {
575
601
if extra_link_arg {
576
- let parts = value. splitn ( 2 , "=" ) . collect :: < Vec < _ > > ( ) ;
577
- if parts. len ( ) == 2 {
578
- linker_args. push ( (
579
- LinkType :: SingleBin ( parts[ 0 ] . to_string ( ) ) ,
580
- parts[ 1 ] . to_string ( ) ,
581
- ) ) ;
582
- } else {
583
- warnings. push ( format ! (
584
- "cargo:{} has invalid syntax: expected `cargo:{}=BIN=ARG`" ,
585
- key, key
586
- ) ) ;
602
+ let mut parts = value. splitn ( 2 , '=' ) ;
603
+ let bin_name = parts. next ( ) . unwrap ( ) . to_string ( ) ;
604
+ let arg = parts. next ( ) . ok_or_else ( || {
605
+ anyhow:: format_err!(
606
+ "invalid instruction `cargo:{}={}` from {}\n \
607
+ The instruction should have the form cargo:{}=BIN=ARG",
608
+ key,
609
+ value,
610
+ whence,
611
+ key
612
+ )
613
+ } ) ?;
614
+ if !targets
615
+ . iter ( )
616
+ . any ( |target| target. is_bin ( ) && target. name ( ) == bin_name)
617
+ {
618
+ bail ! (
619
+ "invalid instruction `cargo:{}` from {}\n \
620
+ The package {} does not have a bin target with the name `{}`.",
621
+ key,
622
+ whence,
623
+ pkg_descr,
624
+ bin_name
625
+ ) ;
587
626
}
627
+ linker_args. push ( ( LinkType :: SingleBin ( bin_name) , arg. to_string ( ) ) ) ;
588
628
} else {
589
629
warnings. push ( format ! ( "cargo:{} requires -Zextra-link-arg flag" , key) ) ;
590
630
}
@@ -632,7 +672,7 @@ impl BuildOutput {
632
672
} else {
633
673
// Setting RUSTC_BOOTSTRAP would change the behavior of the crate.
634
674
// Abort with an error.
635
- anyhow :: bail!( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
675
+ bail ! ( "Cannot set `RUSTC_BOOTSTRAP={}` from {}.\n \
636
676
note: Crates cannot set `RUSTC_BOOTSTRAP` themselves, as doing so would subvert the stability guarantees of Rust for your project.\n \
637
677
help: If you're sure you want to do this in your project, set the environment variable `RUSTC_BOOTSTRAP={}` before running cargo instead.",
638
678
val,
@@ -683,7 +723,7 @@ impl BuildOutput {
683
723
if value. is_empty ( ) {
684
724
value = match flags_iter. next ( ) {
685
725
Some ( v) => v,
686
- None => anyhow :: bail! {
726
+ None => bail ! {
687
727
"Flag in rustc-flags has no value in {}: {}" ,
688
728
whence,
689
729
value
@@ -699,7 +739,7 @@ impl BuildOutput {
699
739
_ => unreachable ! ( ) ,
700
740
} ;
701
741
} else {
702
- anyhow :: bail!(
742
+ bail ! (
703
743
"Only `-l` and `-L` flags are allowed in {}: `{}`" ,
704
744
whence,
705
745
value
@@ -715,7 +755,7 @@ impl BuildOutput {
715
755
let val = iter. next ( ) ;
716
756
match ( name, val) {
717
757
( Some ( n) , Some ( v) ) => Ok ( ( n. to_owned ( ) , v. to_owned ( ) ) ) ,
718
- _ => anyhow :: bail!( "Variable rustc-env has no value in {}: {}" , whence, value) ,
758
+ _ => bail ! ( "Variable rustc-env has no value in {}: {}" , whence, value) ,
719
759
}
720
760
}
721
761
}
@@ -900,6 +940,7 @@ fn prev_build_output(cx: &mut Context<'_, '_>, unit: &Unit) -> (Option<BuildOutp
900
940
& script_out_dir,
901
941
extra_link_arg,
902
942
cx. bcx . config . nightly_features_allowed ,
943
+ unit. pkg . targets ( ) ,
903
944
)
904
945
. ok ( ) ,
905
946
prev_script_out_dir,
0 commit comments