@@ -16,7 +16,7 @@ use proc_macro_api::ProcMacroClient;
16
16
use rustc_hash:: { FxHashMap , FxHashSet } ;
17
17
18
18
use crate :: {
19
- cargo_workspace, cfg_flag:: CfgFlag , sysroot:: SysrootCrate , utf8_stdout, CargoConfig ,
19
+ cargo_workspace, cfg_flag:: CfgFlag , rustc_cfg , sysroot:: SysrootCrate , utf8_stdout, CargoConfig ,
20
20
CargoWorkspace , ProjectJson , ProjectManifest , Sysroot , TargetKind ,
21
21
} ;
22
22
@@ -34,29 +34,41 @@ pub struct PackageRoot {
34
34
#[ derive( Clone , Eq , PartialEq ) ]
35
35
pub enum ProjectWorkspace {
36
36
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
37
- Cargo { cargo : CargoWorkspace , sysroot : Sysroot , rustc : Option < CargoWorkspace > } ,
37
+ Cargo {
38
+ cargo : CargoWorkspace ,
39
+ sysroot : Sysroot ,
40
+ rustc : Option < CargoWorkspace > ,
41
+ /// Holds cfg flags for the current target. We get those by running
42
+ /// `rustc --print cfg`.
43
+ ///
44
+ /// FIXME: make this a per-crate map, as, eg, build.rs might have a
45
+ /// different target.
46
+ rustc_cfg : Vec < CfgFlag > ,
47
+ } ,
38
48
/// Project workspace was manually specified using a `rust-project.json` file.
39
- Json { project : ProjectJson , sysroot : Option < Sysroot > } ,
49
+ Json { project : ProjectJson , sysroot : Option < Sysroot > , rustc_cfg : Vec < CfgFlag > } ,
40
50
}
41
51
42
52
impl fmt:: Debug for ProjectWorkspace {
43
53
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
44
54
match self {
45
- ProjectWorkspace :: Cargo { cargo, sysroot, rustc } => f
55
+ ProjectWorkspace :: Cargo { cargo, sysroot, rustc, rustc_cfg } => f
46
56
. debug_struct ( "Cargo" )
47
57
. field ( "n_packages" , & cargo. packages ( ) . len ( ) )
48
58
. field ( "n_sysroot_crates" , & sysroot. crates ( ) . len ( ) )
49
59
. field (
50
60
"n_rustc_compiler_crates" ,
51
61
& rustc. as_ref ( ) . map_or ( 0 , |rc| rc. packages ( ) . len ( ) ) ,
52
62
)
63
+ . field ( "rustc_cfg" , rustc_cfg)
53
64
. finish ( ) ,
54
- ProjectWorkspace :: Json { project, sysroot } => {
65
+ ProjectWorkspace :: Json { project, sysroot, rustc_cfg } => {
55
66
let mut debug_struct = f. debug_struct ( "Json" ) ;
56
67
debug_struct. field ( "n_crates" , & project. n_crates ( ) ) ;
57
68
if let Some ( sysroot) = sysroot {
58
69
debug_struct. field ( "n_sysroot_crates" , & sysroot. crates ( ) . len ( ) ) ;
59
70
}
71
+ debug_struct. field ( "rustc_cfg" , rustc_cfg) ;
60
72
debug_struct. finish ( )
61
73
}
62
74
}
@@ -79,7 +91,7 @@ impl ProjectWorkspace {
79
91
} ) ?;
80
92
let project_location = project_json. parent ( ) . unwrap ( ) . to_path_buf ( ) ;
81
93
let project_json = ProjectJson :: new ( & project_location, data) ;
82
- ProjectWorkspace :: load_inline ( project_json) ?
94
+ ProjectWorkspace :: load_inline ( project_json, config . target . as_deref ( ) ) ?
83
95
}
84
96
ProjectManifest :: CargoToml ( cargo_toml) => {
85
97
let cargo_version = utf8_stdout ( {
@@ -117,29 +129,32 @@ impl ProjectWorkspace {
117
129
} else {
118
130
None
119
131
} ;
120
-
121
- ProjectWorkspace :: Cargo { cargo, sysroot, rustc }
132
+ let rustc_cfg = rustc_cfg :: get ( config . target . as_deref ( ) ) ;
133
+ ProjectWorkspace :: Cargo { cargo, sysroot, rustc, rustc_cfg }
122
134
}
123
135
} ;
124
136
125
137
Ok ( res)
126
138
}
127
139
128
- pub fn load_inline ( project_json : ProjectJson ) -> Result < ProjectWorkspace > {
140
+ pub fn load_inline (
141
+ project_json : ProjectJson ,
142
+ target : Option < & str > ,
143
+ ) -> Result < ProjectWorkspace > {
129
144
let sysroot = match & project_json. sysroot_src {
130
145
Some ( path) => Some ( Sysroot :: load ( path) ?) ,
131
146
None => None ,
132
147
} ;
133
-
134
- Ok ( ProjectWorkspace :: Json { project : project_json, sysroot } )
148
+ let rustc_cfg = rustc_cfg :: get ( target ) ;
149
+ Ok ( ProjectWorkspace :: Json { project : project_json, sysroot, rustc_cfg } )
135
150
}
136
151
137
152
/// Returns the roots for the current `ProjectWorkspace`
138
153
/// The return type contains the path and whether or not
139
154
/// the root is a member of the current workspace
140
155
pub fn to_roots ( & self ) -> Vec < PackageRoot > {
141
156
match self {
142
- ProjectWorkspace :: Json { project, sysroot } => project
157
+ ProjectWorkspace :: Json { project, sysroot, rustc_cfg : _ } => project
143
158
. crates ( )
144
159
. map ( |( _, krate) | PackageRoot {
145
160
is_member : krate. is_workspace_member ,
@@ -156,7 +171,7 @@ impl ProjectWorkspace {
156
171
} )
157
172
} ) )
158
173
. collect :: < Vec < _ > > ( ) ,
159
- ProjectWorkspace :: Cargo { cargo, sysroot, rustc } => cargo
174
+ ProjectWorkspace :: Cargo { cargo, sysroot, rustc, rustc_cfg : _ } => cargo
160
175
. packages ( )
161
176
. map ( |pkg| {
162
177
let is_member = cargo[ pkg] . is_member ;
@@ -194,7 +209,7 @@ impl ProjectWorkspace {
194
209
pub fn n_packages ( & self ) -> usize {
195
210
match self {
196
211
ProjectWorkspace :: Json { project, .. } => project. n_crates ( ) ,
197
- ProjectWorkspace :: Cargo { cargo, sysroot, rustc } => {
212
+ ProjectWorkspace :: Cargo { cargo, sysroot, rustc, .. } => {
198
213
let rustc_package_len = rustc. as_ref ( ) . map_or ( 0 , |rc| rc. packages ( ) . len ( ) ) ;
199
214
cargo. packages ( ) . len ( ) + sysroot. crates ( ) . len ( ) + rustc_package_len
200
215
}
@@ -203,7 +218,6 @@ impl ProjectWorkspace {
203
218
204
219
pub fn to_crate_graph (
205
220
& self ,
206
- target : Option < & str > ,
207
221
proc_macro_client : Option < & ProcMacroClient > ,
208
222
load : & mut dyn FnMut ( & AbsPath ) -> Option < FileId > ,
209
223
) -> CrateGraph {
@@ -214,12 +228,21 @@ impl ProjectWorkspace {
214
228
} ;
215
229
216
230
let mut crate_graph = match self {
217
- ProjectWorkspace :: Json { project, sysroot } => {
218
- project_json_to_crate_graph ( target, & proc_macro_loader, load, project, sysroot)
219
- }
220
- ProjectWorkspace :: Cargo { cargo, sysroot, rustc } => {
221
- cargo_to_crate_graph ( target, & proc_macro_loader, load, cargo, sysroot, rustc)
222
- }
231
+ ProjectWorkspace :: Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph (
232
+ rustc_cfg. clone ( ) ,
233
+ & proc_macro_loader,
234
+ load,
235
+ project,
236
+ sysroot,
237
+ ) ,
238
+ ProjectWorkspace :: Cargo { cargo, sysroot, rustc, rustc_cfg } => cargo_to_crate_graph (
239
+ rustc_cfg. clone ( ) ,
240
+ & proc_macro_loader,
241
+ load,
242
+ cargo,
243
+ sysroot,
244
+ rustc,
245
+ ) ,
223
246
} ;
224
247
if crate_graph. patch_cfg_if ( ) {
225
248
log:: debug!( "Patched std to depend on cfg-if" )
@@ -231,7 +254,7 @@ impl ProjectWorkspace {
231
254
}
232
255
233
256
fn project_json_to_crate_graph (
234
- target : Option < & str > ,
257
+ rustc_cfg : Vec < CfgFlag > ,
235
258
proc_macro_loader : & dyn Fn ( & Path ) -> Vec < ProcMacro > ,
236
259
load : & mut dyn FnMut ( & AbsPath ) -> Option < FileId > ,
237
260
project : & ProjectJson ,
@@ -240,9 +263,9 @@ fn project_json_to_crate_graph(
240
263
let mut crate_graph = CrateGraph :: default ( ) ;
241
264
let sysroot_deps = sysroot
242
265
. as_ref ( )
243
- . map ( |sysroot| sysroot_to_crate_graph ( & mut crate_graph, sysroot, target , load) ) ;
266
+ . map ( |sysroot| sysroot_to_crate_graph ( & mut crate_graph, sysroot, rustc_cfg . clone ( ) , load) ) ;
244
267
245
- let mut cfg_cache: FxHashMap < Option < & str > , Vec < CfgFlag > > = FxHashMap :: default ( ) ;
268
+ let mut cfg_cache: FxHashMap < & str , Vec < CfgFlag > > = FxHashMap :: default ( ) ;
246
269
let crates: FxHashMap < CrateId , CrateId > = project
247
270
. crates ( )
248
271
. filter_map ( |( crate_id, krate) | {
@@ -254,9 +277,12 @@ fn project_json_to_crate_graph(
254
277
let env = krate. env . clone ( ) . into_iter ( ) . collect ( ) ;
255
278
let proc_macro = krate. proc_macro_dylib_path . clone ( ) . map ( |it| proc_macro_loader ( & it) ) ;
256
279
257
- let target = krate. target . as_deref ( ) . or ( target) ;
258
- let target_cfgs =
259
- cfg_cache. entry ( target) . or_insert_with ( || get_rustc_cfg_options ( target) ) ;
280
+ let target_cfgs = match krate. target . as_deref ( ) {
281
+ Some ( target) => {
282
+ cfg_cache. entry ( target) . or_insert_with ( || rustc_cfg:: get ( Some ( target) ) )
283
+ }
284
+ None => & rustc_cfg,
285
+ } ;
260
286
261
287
let mut cfg_options = CfgOptions :: default ( ) ;
262
288
cfg_options. extend ( target_cfgs. iter ( ) . chain ( krate. cfg . iter ( ) ) . cloned ( ) ) ;
@@ -293,7 +319,7 @@ fn project_json_to_crate_graph(
293
319
}
294
320
295
321
fn cargo_to_crate_graph (
296
- target : Option < & str > ,
322
+ rustc_cfg : Vec < CfgFlag > ,
297
323
proc_macro_loader : & dyn Fn ( & Path ) -> Vec < ProcMacro > ,
298
324
load : & mut dyn FnMut ( & AbsPath ) -> Option < FileId > ,
299
325
cargo : & CargoWorkspace ,
@@ -303,10 +329,10 @@ fn cargo_to_crate_graph(
303
329
let _p = profile:: span ( "cargo_to_crate_graph" ) ;
304
330
let mut crate_graph = CrateGraph :: default ( ) ;
305
331
let ( public_deps, libproc_macro) =
306
- sysroot_to_crate_graph ( & mut crate_graph, sysroot, target , load) ;
332
+ sysroot_to_crate_graph ( & mut crate_graph, sysroot, rustc_cfg . clone ( ) , load) ;
307
333
308
334
let mut cfg_options = CfgOptions :: default ( ) ;
309
- cfg_options. extend ( get_rustc_cfg_options ( target ) ) ;
335
+ cfg_options. extend ( rustc_cfg ) ;
310
336
311
337
let mut pkg_to_lib_crate = FxHashMap :: default ( ) ;
312
338
@@ -492,12 +518,12 @@ fn add_target_crate_root(
492
518
fn sysroot_to_crate_graph (
493
519
crate_graph : & mut CrateGraph ,
494
520
sysroot : & Sysroot ,
495
- target : Option < & str > ,
521
+ rustc_cfg : Vec < CfgFlag > ,
496
522
load : & mut dyn FnMut ( & AbsPath ) -> Option < FileId > ,
497
523
) -> ( Vec < ( CrateName , CrateId ) > , Option < CrateId > ) {
498
524
let _p = profile:: span ( "sysroot_to_crate_graph" ) ;
499
525
let mut cfg_options = CfgOptions :: default ( ) ;
500
- cfg_options. extend ( get_rustc_cfg_options ( target ) ) ;
526
+ cfg_options. extend ( rustc_cfg ) ;
501
527
let sysroot_crates: FxHashMap < SysrootCrate , CrateId > = sysroot
502
528
. crates ( )
503
529
. filter_map ( |krate| {
@@ -536,35 +562,6 @@ fn sysroot_to_crate_graph(
536
562
( public_deps, libproc_macro)
537
563
}
538
564
539
- fn get_rustc_cfg_options ( target : Option < & str > ) -> Vec < CfgFlag > {
540
- let _p = profile:: span ( "get_rustc_cfg_options" ) ;
541
- let mut res = Vec :: new ( ) ;
542
-
543
- // Some nightly-only cfgs, which are required for stdlib
544
- res. push ( CfgFlag :: Atom ( "target_thread_local" . into ( ) ) ) ;
545
- for & ty in [ "8" , "16" , "32" , "64" , "cas" , "ptr" ] . iter ( ) {
546
- for & key in [ "target_has_atomic" , "target_has_atomic_load_store" ] . iter ( ) {
547
- res. push ( CfgFlag :: KeyValue { key : key. to_string ( ) , value : ty. into ( ) } ) ;
548
- }
549
- }
550
-
551
- let rustc_cfgs = {
552
- let mut cmd = Command :: new ( toolchain:: rustc ( ) ) ;
553
- cmd. args ( & [ "--print" , "cfg" , "-O" ] ) ;
554
- if let Some ( target) = target {
555
- cmd. args ( & [ "--target" , target] ) ;
556
- }
557
- utf8_stdout ( cmd)
558
- } ;
559
-
560
- match rustc_cfgs {
561
- Ok ( rustc_cfgs) => res. extend ( rustc_cfgs. lines ( ) . map ( |it| it. parse ( ) . unwrap ( ) ) ) ,
562
- Err ( e) => log:: error!( "failed to get rustc cfgs: {:#}" , e) ,
563
- }
564
-
565
- res
566
- }
567
-
568
565
fn add_dep ( graph : & mut CrateGraph , from : CrateId , name : CrateName , to : CrateId ) {
569
566
if let Err ( err) = graph. add_dep ( from, name, to) {
570
567
log:: error!( "{}" , err)
0 commit comments