@@ -14,7 +14,7 @@ use crate::util::context::{GlobalContext, StringList, TargetConfig};
14
14
use crate :: util:: interning:: InternedString ;
15
15
use crate :: util:: { CargoResult , Rustc } ;
16
16
use anyhow:: Context as _;
17
- use cargo_platform:: { Cfg , CfgExpr } ;
17
+ use cargo_platform:: { Cfg , CfgExpr , CheckCfg } ;
18
18
use cargo_util:: { paths, ProcessBuilder } ;
19
19
use serde:: { Deserialize , Serialize } ;
20
20
use std:: cell:: RefCell ;
@@ -43,6 +43,8 @@ pub struct TargetInfo {
43
43
crate_types : RefCell < HashMap < CrateType , Option < ( String , String ) > > > ,
44
44
/// `cfg` information extracted from `rustc --print=cfg`.
45
45
cfg : Vec < Cfg > ,
46
+ /// `check-cfg` informations extracted from `rustc --print=check-cfg`.
47
+ check_cfg : Option < CheckCfg > ,
46
48
/// `supports_std` information extracted from `rustc --print=target-spec-json`
47
49
pub supports_std : Option < bool > ,
48
50
/// Supported values for `-Csplit-debuginfo=` flag, queried from rustc
@@ -206,6 +208,14 @@ impl TargetInfo {
206
208
process. arg ( "--print=crate-name" ) ; // `___` as a delimiter.
207
209
process. arg ( "--print=cfg" ) ;
208
210
211
+ if gctx. cli_unstable ( ) . check_target_cfgs {
212
+ process. arg ( "--print=crate-name" ) ; // `___` as a delimiter.
213
+ process. arg ( "--print=check-cfg" ) ;
214
+
215
+ process. arg ( "--check-cfg=cfg()" ) ; // otherwise `--print=check-cfg` won't output
216
+ process. arg ( "-Zunstable-options" ) ; // required by `--print=check-cfg`
217
+ }
218
+
209
219
let ( output, error) = rustc
210
220
. cached_output ( & process, extra_fingerprint)
211
221
. with_context ( || {
@@ -258,6 +268,11 @@ impl TargetInfo {
258
268
let cfg = {
259
269
let mut res = Vec :: new ( ) ;
260
270
for line in & mut lines {
271
+ // HACK: abuse `--print=crate-name` to use `___` as a delimiter.
272
+ if line == "___" {
273
+ break ;
274
+ }
275
+
261
276
let cfg = Cfg :: from_str ( line) . with_context ( || {
262
277
format ! (
263
278
"failed to parse the cfg from `rustc --print=cfg`, got:\n {}" ,
@@ -271,6 +286,22 @@ impl TargetInfo {
271
286
res
272
287
} ;
273
288
289
+ let check_cfg = if gctx. cli_unstable ( ) . check_target_cfgs {
290
+ let mut check_cfg = CheckCfg :: default ( ) ;
291
+ check_cfg. exhaustive = true ;
292
+
293
+ for line in lines {
294
+ check_cfg
295
+ . parse_print_check_cfg_line ( line)
296
+ . with_context ( || {
297
+ format ! ( "unable to parse a line from `--print=check-cfg`" )
298
+ } ) ?;
299
+ }
300
+ Some ( check_cfg)
301
+ } else {
302
+ None
303
+ } ;
304
+
274
305
// recalculate `rustflags` from above now that we have `cfg`
275
306
// information
276
307
let new_flags = extra_args (
@@ -355,6 +386,7 @@ impl TargetInfo {
355
386
) ?
356
387
. into ( ) ,
357
388
cfg,
389
+ check_cfg,
358
390
supports_std,
359
391
support_split_debuginfo,
360
392
} ) ;
@@ -378,6 +410,11 @@ impl TargetInfo {
378
410
& self . cfg
379
411
}
380
412
413
+ /// The [`CheckCfg`] settings.
414
+ pub fn check_cfg ( & self ) -> & Option < CheckCfg > {
415
+ & self . check_cfg
416
+ }
417
+
381
418
/// Returns the list of file types generated by the given crate type.
382
419
///
383
420
/// Returns `None` if the target does not support the given crate type.
0 commit comments