1
+ //! This modules contains types storing information of target platfroms.
2
+ //!
3
+ //! Normally, call [`RustcTargetData::new`] to construct all the target
4
+ //! platform once, and then query info on your demand. For example,
5
+ //!
6
+ //! * [`RustcTargetData::dep_platform_activated`] to check if platform is activated.
7
+ //! * [`RustcTargetData::info`] to get a [`TargetInfo`] for an in-depth query.
8
+ //! * [`TargetInfo::rustc_outputs`] to get a list of supported file types.
9
+
1
10
use crate :: core:: compiler:: {
2
11
BuildOutput , CompileKind , CompileMode , CompileTarget , Context , CrateType ,
3
12
} ;
@@ -16,8 +25,9 @@ use std::str::{self, FromStr};
16
25
17
26
/// Information about the platform target gleaned from querying rustc.
18
27
///
19
- /// `RustcTargetData` keeps two of these, one for the host and one for the
20
- /// target. If no target is specified, it uses a clone from the host.
28
+ /// [`RustcTargetData`] keeps several of these, one for the host and the others
29
+ /// for other specified targets. If no target is specified, it uses a clone from
30
+ /// the host.
21
31
#[ derive( Clone ) ]
22
32
pub struct TargetInfo {
23
33
/// A base process builder for discovering crate type information. In
@@ -41,9 +51,9 @@ pub struct TargetInfo {
41
51
/// Path to the "lib" directory in the sysroot which rustc uses for linking
42
52
/// target libraries.
43
53
pub sysroot_target_libdir : PathBuf ,
44
- /// Extra flags to pass to `rustc`, see `env_args` .
54
+ /// Extra flags to pass to `rustc`, see [`extra_args`] .
45
55
pub rustflags : Vec < String > ,
46
- /// Extra flags to pass to `rustdoc`, see `env_args` .
56
+ /// Extra flags to pass to `rustdoc`, see [`extra_args`] .
47
57
pub rustdocflags : Vec < String > ,
48
58
/// Whether or not rustc supports the `-Csplit-debuginfo` flag.
49
59
pub supports_split_debuginfo : bool ,
@@ -132,13 +142,20 @@ impl FileType {
132
142
}
133
143
134
144
impl TargetInfo {
145
+ /// Learns the information of target platform from `rustc` invocation(s).
146
+ ///
147
+ /// Generally, the first time calling this function is expensive, as it may
148
+ /// query `rustc` several times. To reduce the cost, output of each `rustc`
149
+ /// invocation is cached by [`Rustc::cached_output`].
150
+ ///
151
+ /// Search `Tricky` to learn why querying `rustc` several times is needed.
135
152
pub fn new (
136
153
config : & Config ,
137
154
requested_kinds : & [ CompileKind ] ,
138
155
rustc : & Rustc ,
139
156
kind : CompileKind ,
140
157
) -> CargoResult < TargetInfo > {
141
- let mut rustflags = env_args (
158
+ let mut rustflags = extra_args (
142
159
config,
143
160
requested_kinds,
144
161
& rustc. host ,
@@ -149,6 +166,13 @@ impl TargetInfo {
149
166
let mut turn = 0 ;
150
167
loop {
151
168
let extra_fingerprint = kind. fingerprint_hash ( ) ;
169
+
170
+ // Query rustc for several kinds of info from each line of output:
171
+ // 0) file-names (to determine output file prefix/suffix for given crate type)
172
+ // 1) sysroot
173
+ // 2) cfg
174
+ //
175
+ // Search `--print` to see what we query so far.
152
176
let mut process = rustc. workspace_process ( ) ;
153
177
process
154
178
. arg ( "-" )
@@ -174,6 +198,8 @@ impl TargetInfo {
174
198
for crate_type in KNOWN_CRATE_TYPES . iter ( ) {
175
199
process. arg ( "--crate-type" ) . arg ( crate_type. as_str ( ) ) ;
176
200
}
201
+
202
+ // An extra `rustc` call to determine `-Csplit-debuginfo=packed` support.
177
203
let supports_split_debuginfo = rustc
178
204
. cached_output (
179
205
process. clone ( ) . arg ( "-Csplit-debuginfo=packed" ) ,
@@ -233,7 +259,7 @@ impl TargetInfo {
233
259
234
260
// recalculate `rustflags` from above now that we have `cfg`
235
261
// information
236
- let new_flags = env_args (
262
+ let new_flags = extra_args (
237
263
config,
238
264
requested_kinds,
239
265
& rustc. host ,
@@ -268,7 +294,7 @@ impl TargetInfo {
268
294
sysroot_host_libdir,
269
295
sysroot_target_libdir,
270
296
rustflags,
271
- rustdocflags : env_args (
297
+ rustdocflags : extra_args (
272
298
config,
273
299
requested_kinds,
274
300
& rustc. host ,
@@ -294,7 +320,7 @@ impl TargetInfo {
294
320
true
295
321
}
296
322
297
- /// All the target `cfg` settings.
323
+ /// All the target [`Cfg`] settings.
298
324
pub fn cfg ( & self ) -> & [ Cfg ] {
299
325
& self . cfg
300
326
}
@@ -580,6 +606,7 @@ fn output_err_info(cmd: &ProcessBuilder, stdout: &str, stderr: &str) -> String {
580
606
result
581
607
}
582
608
609
+ /// Compiler flags for either rustc or rustdoc.
583
610
#[ derive( Debug , Copy , Clone ) ]
584
611
enum Flags {
585
612
Rust ,
@@ -614,6 +641,7 @@ impl Flags {
614
641
/// - `target.*.rustflags` from the config (.cargo/config)
615
642
/// - `target.cfg(..).rustflags` from the config
616
643
/// - `host.*.rustflags` from the config if compiling a host artifact or without `--target`
644
+ /// (requires `-Zhost-config`)
617
645
///
618
646
/// then if none of those were found
619
647
///
@@ -624,7 +652,7 @@ impl Flags {
624
652
/// For those artifacts, _only_ `host.*.rustflags` is respected, and no other configuration
625
653
/// sources, _regardless of the value of `target-applies-to-host`_. This is counterintuitive, but
626
654
/// necessary to retain backwards compatibility with older versions of Cargo.
627
- fn env_args (
655
+ fn extra_args (
628
656
config : & Config ,
629
657
requested_kinds : & [ CompileKind ] ,
630
658
host_triple : & str ,
@@ -669,6 +697,8 @@ fn env_args(
669
697
}
670
698
}
671
699
700
+ /// Gets compiler flags from environment variables.
701
+ /// See [`extra_args`] for more.
672
702
fn rustflags_from_env ( flags : Flags ) -> Option < Vec < String > > {
673
703
// First try CARGO_ENCODED_RUSTFLAGS from the environment.
674
704
// Prefer this over RUSTFLAGS since it's less prone to encoding errors.
@@ -693,6 +723,8 @@ fn rustflags_from_env(flags: Flags) -> Option<Vec<String>> {
693
723
None
694
724
}
695
725
726
+ /// Gets compiler flags from `[target]` section in the config.
727
+ /// See [`extra_args`] for more.
696
728
fn rustflags_from_target (
697
729
config : & Config ,
698
730
host_triple : & str ,
@@ -734,6 +766,8 @@ fn rustflags_from_target(
734
766
}
735
767
}
736
768
769
+ /// Gets compiler flags from `[host]` section in the config.
770
+ /// See [`extra_args`] for more.
737
771
fn rustflags_from_host (
738
772
config : & Config ,
739
773
flag : Flags ,
@@ -750,6 +784,8 @@ fn rustflags_from_host(
750
784
Ok ( list. as_ref ( ) . map ( |l| l. val . as_slice ( ) . to_vec ( ) ) )
751
785
}
752
786
787
+ /// Gets compiler flags from `[build]` section in the config.
788
+ /// See [`extra_args`] for more.
753
789
fn rustflags_from_build ( config : & Config , flag : Flags ) -> CargoResult < Option < Vec < String > > > {
754
790
// Then the `build.rustflags` value.
755
791
let build = config. build_config ( ) ?;
@@ -773,11 +809,12 @@ pub struct RustcTargetData<'cfg> {
773
809
/// `rustc` is invoked without a `--target` flag. This is used for
774
810
/// procedural macros, build scripts, etc.
775
811
host_config : TargetConfig ,
812
+ /// Information about the host platform.
776
813
host_info : TargetInfo ,
777
814
778
- /// Build information for targets that we're building for. This will be
779
- /// empty if the `--target` flag is not passed.
815
+ /// Build information for targets that we're building for.
780
816
target_config : HashMap < CompileTarget , TargetConfig > ,
817
+ /// Information about the target platform that we're building for.
781
818
target_info : HashMap < CompileTarget , TargetInfo > ,
782
819
}
783
820
0 commit comments