@@ -573,17 +573,23 @@ fn output_err_info(cmd: &ProcessBuilder, stdout: &str, stderr: &str) -> String {
573
573
/// - the `CARGO_ENCODED_RUSTFLAGS` environment variable
574
574
/// - the `RUSTFLAGS` environment variable
575
575
///
576
- /// then if this was not found
576
+ /// then if none of those were found
577
577
///
578
578
/// - `target.*.rustflags` from the config (.cargo/config)
579
579
/// - `target.cfg(..).rustflags` from the config
580
+ /// - `host.*.rustflags` from the config if compiling a host artifact or without `--target`
580
581
///
581
- /// then if neither of these were found
582
+ /// then if none of those were found
582
583
///
583
584
/// - `build.rustflags` from the config
584
585
///
585
- /// Note that if a `target` is specified, no args will be passed to host code (plugins, build
586
- /// scripts, ...), even if it is the same as the target.
586
+ /// The behavior differs slightly when cross-compiling (or, specifically, when `--target` is
587
+ /// provided) for artifacts that are always built for the host (plugins, build scripts, ...).
588
+ /// For those artifacts, the behavior depends on `target-applies-to-host`. In the default
589
+ /// configuration (where `target-applies-to-host` is unset), and if `target-applies-to-host =
590
+ /// false`, host artifacts _only_ respect `host.*.rustflags`, and no other configuration sources.
591
+ /// If `target-applies-to-host = true`, host artifacts also respect `target.<host triple>`, and if
592
+ /// `<target triple> == <host triple>` `RUSTFLAGS` and `CARGO_ENCODED_RUSTFLAGS`.
587
593
fn env_args (
588
594
config : & Config ,
589
595
requested_kinds : & [ CompileKind ] ,
@@ -592,49 +598,67 @@ fn env_args(
592
598
kind : CompileKind ,
593
599
name : & str ,
594
600
) -> CargoResult < Vec < String > > {
595
- // We *want* to apply RUSTFLAGS only to builds for the
596
- // requested target architecture, and not to things like build
597
- // scripts and plugins, which may be for an entirely different
598
- // architecture. Cargo's present architecture makes it quite
599
- // hard to only apply flags to things that are not build
600
- // scripts and plugins though, so we do something more hacky
601
- // instead to avoid applying the same RUSTFLAGS to multiple targets
602
- // arches:
601
+ let target_applies_to_host = config. target_applies_to_host ( ) ?;
602
+
603
+ // Include untargeted configuration sources (like `RUSTFLAGS`) if
603
604
//
604
- // 1) If --target is not specified we just apply RUSTFLAGS to
605
- // all builds; they are all going to have the same target.
605
+ // - we're compiling artifacts for the target platform; or
606
+ // - we're not cross-compiling; or
607
+ // - we're compiling host artifacts, the requested target matches the host, and the user has
608
+ // requested that the host pick up target configurations.
606
609
//
607
- // 2) If --target *is* specified then we only apply RUSTFLAGS
608
- // to compilation units with the Target kind, which indicates
609
- // it was chosen by the --target flag.
610
+ // The rationale for the third condition is that `RUSTFLAGS` is intended to affect compilation
611
+ // for the target, and `target-applies-to-host` makes it so that the host is affected by its
612
+ // target's config, so if `--target <host triple>` then `RUSTFLAGS` should also apply to the
613
+ // host.
614
+ let include_generic = !kind. is_host ( )
615
+ || requested_kinds == [ CompileKind :: Host ]
616
+ || ( target_applies_to_host == Some ( true )
617
+ && requested_kinds == [ CompileKind :: Target ( CompileTarget :: new ( host_triple) ?) ] ) ;
618
+ // Include targeted configuration sources (like `target.*.rustflags`) if
610
619
//
611
- // This means that, e.g., even if the specified --target is the
612
- // same as the host, build scripts in plugins won't get
613
- // RUSTFLAGS.
614
- if requested_kinds != [ CompileKind :: Host ] && kind. is_host ( ) {
615
- // This is probably a build script or plugin and we're
616
- // compiling with --target. In this scenario there are
617
- // no rustflags we can apply.
618
- return Ok ( Vec :: new ( ) ) ;
619
- }
620
-
621
- // First try CARGO_ENCODED_RUSTFLAGS from the environment.
622
- // Prefer this over RUSTFLAGS since it's less prone to encoding errors.
623
- if let Ok ( a) = env:: var ( format ! ( "CARGO_ENCODED_{}" , name) ) {
624
- if a. is_empty ( ) {
625
- return Ok ( Vec :: new ( ) ) ;
620
+ // - we're compiling artifacts for the target platform; or
621
+ // - we're not cross-compiling; or
622
+ // - we're compiling host artifacts and the user has requested that the host pick up target
623
+ // configurations.
624
+ //
625
+ // The middle condition here may seem counter-intuitive. If `target-applies-to-host-kind` is
626
+ // disabled, then `target.*.rustflags` should arguably not apply to host artifacts. However,
627
+ // this is likely surprising to users who set `target.<host triple>.rustflags` and run `cargo
628
+ // build` (with no `--target`). So, we respect `target.<host triple>`.rustflags` when
629
+ // `--target` _isn't_ supplied, which arguably matches the mental model established by
630
+ // respecting `RUSTFLAGS` when `--target` isn't supplied.
631
+ let include_for_target = !kind. is_host ( )
632
+ || requested_kinds == [ CompileKind :: Host ]
633
+ || target_applies_to_host == Some ( true ) ;
634
+ // Include host-based configuration sources (like `host.*.rustflags`) if
635
+ //
636
+ // - we're compiling host artifacts; or
637
+ // - we're not cross-compiling
638
+ //
639
+ // Note that we do _not_ read `host.*.rustflags` just because the host's target is the same as
640
+ // the requested target, as that's the whole point of the `host` section in the first place.
641
+ let include_for_host = kind. is_host ( ) || requested_kinds == [ CompileKind :: Host ] ;
642
+
643
+ if include_generic {
644
+ // First try CARGO_ENCODED_RUSTFLAGS from the environment.
645
+ // Prefer this over RUSTFLAGS since it's less prone to encoding errors.
646
+ if let Ok ( a) = env:: var ( format ! ( "CARGO_ENCODED_{}" , name) ) {
647
+ if a. is_empty ( ) {
648
+ return Ok ( Vec :: new ( ) ) ;
649
+ }
650
+ return Ok ( a. split ( '\x1f' ) . map ( str:: to_string) . collect ( ) ) ;
626
651
}
627
- return Ok ( a. split ( '\x1f' ) . map ( str:: to_string) . collect ( ) ) ;
628
- }
629
652
630
- // Then try RUSTFLAGS from the environment
631
- if let Ok ( a) = env:: var ( name) {
632
- let args = a
633
- . split ( ' ' )
634
- . map ( str:: trim)
635
- . filter ( |s| !s. is_empty ( ) )
636
- . map ( str:: to_string) ;
637
- return Ok ( args. collect ( ) ) ;
653
+ // Then try RUSTFLAGS from the environment
654
+ if let Ok ( a) = env:: var ( name) {
655
+ let args = a
656
+ . split ( ' ' )
657
+ . map ( str:: trim)
658
+ . filter ( |s| !s. is_empty ( ) )
659
+ . map ( str:: to_string) ;
660
+ return Ok ( args. collect ( ) ) ;
661
+ }
638
662
}
639
663
640
664
let mut rustflags = Vec :: new ( ) ;
@@ -643,44 +667,55 @@ fn env_args(
643
667
. chars ( )
644
668
. flat_map ( |c| c. to_lowercase ( ) )
645
669
. collect :: < String > ( ) ;
646
- // Then the target.*.rustflags value...
647
- let target = match & kind {
648
- CompileKind :: Host => host_triple,
649
- CompileKind :: Target ( target) => target. short_name ( ) ,
650
- } ;
651
- let key = format ! ( "target.{}.{}" , target, name) ;
652
- if let Some ( args) = config. get :: < Option < StringList > > ( & key) ? {
653
- rustflags. extend ( args. as_slice ( ) . iter ( ) . cloned ( ) ) ;
670
+ if include_for_target {
671
+ // Then the target.*.rustflags value...
672
+ let target = match & kind {
673
+ CompileKind :: Host => host_triple,
674
+ CompileKind :: Target ( target) => target. short_name ( ) ,
675
+ } ;
676
+ let key = format ! ( "target.{}.{}" , target, name) ;
677
+ if let Some ( args) = config. get :: < Option < StringList > > ( & key) ? {
678
+ rustflags. extend ( args. as_slice ( ) . iter ( ) . cloned ( ) ) ;
679
+ }
680
+ // ...including target.'cfg(...)'.rustflags
681
+ if let Some ( target_cfg) = target_cfg {
682
+ config
683
+ . target_cfgs ( ) ?
684
+ . iter ( )
685
+ . filter_map ( |( key, cfg) | {
686
+ cfg. rustflags
687
+ . as_ref ( )
688
+ . map ( |rustflags| ( key, & rustflags. val ) )
689
+ } )
690
+ . filter ( |( key, _rustflags) | CfgExpr :: matches_key ( key, target_cfg) )
691
+ . for_each ( |( _key, cfg_rustflags) | {
692
+ rustflags. extend ( cfg_rustflags. as_slice ( ) . iter ( ) . cloned ( ) ) ;
693
+ } ) ;
694
+ }
654
695
}
655
- // ...including target.'cfg(...)'.rustflags
656
- if let Some ( target_cfg) = target_cfg {
657
- config
658
- . target_cfgs ( ) ?
659
- . iter ( )
660
- . filter_map ( |( key, cfg) | {
661
- cfg. rustflags
662
- . as_ref ( )
663
- . map ( |rustflags| ( key, & rustflags. val ) )
664
- } )
665
- . filter ( |( key, _rustflags) | CfgExpr :: matches_key ( key, target_cfg) )
666
- . for_each ( |( _key, cfg_rustflags) | {
667
- rustflags. extend ( cfg_rustflags. as_slice ( ) . iter ( ) . cloned ( ) ) ;
668
- } ) ;
696
+
697
+ if include_for_host {
698
+ let target_cfg = config. host_cfg_triple ( host_triple) ?;
699
+ if let Some ( rf) = target_cfg. rustflags {
700
+ rustflags. extend ( rf. val . as_slice ( ) . iter ( ) . cloned ( ) ) ;
701
+ }
669
702
}
670
703
671
704
if !rustflags. is_empty ( ) {
672
705
return Ok ( rustflags) ;
673
706
}
674
707
675
- // Then the `build.rustflags` value.
676
- let build = config. build_config ( ) ?;
677
- let list = if name == "rustflags" {
678
- & build. rustflags
679
- } else {
680
- & build. rustdocflags
681
- } ;
682
- if let Some ( list) = list {
683
- return Ok ( list. as_slice ( ) . to_vec ( ) ) ;
708
+ if include_generic {
709
+ // Then the `build.rustflags` value.
710
+ let build = config. build_config ( ) ?;
711
+ let list = if name == "rustflags" {
712
+ & build. rustflags
713
+ } else {
714
+ & build. rustdocflags
715
+ } ;
716
+ if let Some ( list) = list {
717
+ return Ok ( list. as_slice ( ) . to_vec ( ) ) ;
718
+ }
684
719
}
685
720
686
721
Ok ( Vec :: new ( ) )
@@ -718,7 +753,7 @@ impl<'cfg> RustcTargetData<'cfg> {
718
753
let mut target_info = HashMap :: new ( ) ;
719
754
let target_applies_to_host = config. target_applies_to_host ( ) ?;
720
755
let host_info = TargetInfo :: new ( config, requested_kinds, & rustc, CompileKind :: Host ) ?;
721
- let host_config = if target_applies_to_host {
756
+ let host_config = if target_applies_to_host != Some ( false ) {
722
757
config. target_cfg_triple ( & rustc. host ) ?
723
758
} else {
724
759
config. host_cfg_triple ( & rustc. host ) ?
0 commit comments