@@ -9,80 +9,52 @@ use crate::core::resolver::HasDevUnits;
9
9
use crate :: core:: { PackageId , PackageSet , Resolve , Workspace } ;
10
10
use crate :: ops:: { self , Packages } ;
11
11
use crate :: util:: errors:: CargoResult ;
12
- use crate :: GlobalContext ;
12
+
13
13
use std:: collections:: { HashMap , HashSet } ;
14
14
use std:: path:: PathBuf ;
15
15
16
16
use super :: BuildConfig ;
17
17
18
- /// Parse the `-Zbuild-std` flag.
19
- pub fn parse_unstable_flag ( value : Option < & str > ) -> Vec < String > {
18
+ fn std_crates < ' a > ( crates : & ' a [ String ] , default : & ' static str , units : & [ Unit ] ) -> HashSet < & ' a str > {
19
+ let mut crates = HashSet :: from_iter ( crates . iter ( ) . map ( |s| s . as_str ( ) ) ) ;
20
20
// This is a temporary hack until there is a more principled way to
21
21
// declare dependencies in Cargo.toml.
22
- let value = value. unwrap_or ( "std" ) ;
23
- let mut crates: HashSet < & str > = value. split ( ',' ) . collect ( ) ;
22
+ if crates. is_empty ( ) {
23
+ crates. insert ( default) ;
24
+ }
24
25
if crates. contains ( "std" ) {
25
26
crates. insert ( "core" ) ;
26
27
crates. insert ( "alloc" ) ;
27
28
crates. insert ( "proc_macro" ) ;
28
29
crates. insert ( "panic_unwind" ) ;
29
30
crates. insert ( "compiler_builtins" ) ;
30
- } else if crates. contains ( "core" ) {
31
- crates. insert ( "compiler_builtins" ) ;
32
- }
33
- crates. into_iter ( ) . map ( |s| s. to_string ( ) ) . collect ( )
34
- }
35
-
36
- pub ( crate ) fn std_crates ( gctx : & GlobalContext , units : Option < & [ Unit ] > ) -> Option < Vec < String > > {
37
- let crates = gctx. cli_unstable ( ) . build_std . as_ref ( ) ?. clone ( ) ;
38
-
39
- // Only build libtest if it looks like it is needed.
40
- let mut crates = crates. clone ( ) ;
41
- // If we know what units we're building, we can filter for libtest depending on the jobs.
42
- if let Some ( units) = units {
31
+ // Only build libtest if it looks like it is needed (libtest depends on libstd)
32
+ // If we know what units we're building, we can filter for libtest depending on the jobs.
43
33
if units
44
34
. iter ( )
45
35
. any ( |unit| unit. mode . is_rustc_test ( ) && unit. target . harness ( ) )
46
36
{
47
- // Only build libtest when libstd is built (libtest depends on libstd)
48
- if crates. iter ( ) . any ( |c| c == "std" ) && !crates. iter ( ) . any ( |c| c == "test" ) {
49
- crates. push ( "test" . to_string ( ) ) ;
50
- }
51
- }
52
- } else {
53
- // We don't know what jobs are going to be run, so download libtest just in case.
54
- if !crates. iter ( ) . any ( |c| c == "test" ) {
55
- crates. push ( "test" . to_string ( ) )
37
+ crates. insert ( "test" ) ;
56
38
}
39
+ } else if crates. contains ( "core" ) {
40
+ crates. insert ( "compiler_builtins" ) ;
57
41
}
58
42
59
- Some ( crates)
43
+ crates
60
44
}
61
45
62
46
/// Resolve the standard library dependencies.
63
47
pub fn resolve_std < ' gctx > (
64
48
ws : & Workspace < ' gctx > ,
65
49
target_data : & mut RustcTargetData < ' gctx > ,
66
50
build_config : & BuildConfig ,
67
- crates : & [ String ] ,
68
51
) -> CargoResult < ( PackageSet < ' gctx > , Resolve , ResolvedFeatures ) > {
69
52
if build_config. build_plan {
70
53
ws. gctx ( )
71
54
. shell ( )
72
55
. warn ( "-Zbuild-std does not currently fully support --build-plan" ) ?;
73
56
}
74
57
75
- // check that targets support building std
76
- if crates. contains ( & "std" . to_string ( ) ) {
77
- let unsupported_targets = target_data. get_unsupported_std_targets ( ) ;
78
- if !unsupported_targets. is_empty ( ) {
79
- anyhow:: bail!(
80
- "building std is not supported on the following targets: {}" ,
81
- unsupported_targets. join( ", " )
82
- )
83
- }
84
- }
85
-
86
58
let src_path = detect_sysroot_src_path ( target_data) ?;
87
59
let std_ws_manifest_path = src_path. join ( "Cargo.toml" ) ;
88
60
let gctx = ws. gctx ( ) ;
@@ -93,12 +65,10 @@ pub fn resolve_std<'gctx>(
93
65
// `[dev-dependencies]`. No need for us to generate a `Resolve` which has
94
66
// those included because we'll never use them anyway.
95
67
std_ws. set_require_optional_deps ( false ) ;
96
- // `sysroot` is not in the default set because it is optional, but it needs
97
- // to be part of the resolve in case we do need it or `libtest`.
98
- let mut spec_pkgs = Vec :: from ( crates) ;
99
- spec_pkgs. push ( "sysroot" . to_string ( ) ) ;
100
- let spec = Packages :: Packages ( spec_pkgs) ;
101
- let specs = spec. to_package_id_specs ( & std_ws) ?;
68
+ // `sysroot` + the default feature set below should give us a good default
69
+ // Resolve, which includes `libtest` as well.
70
+ let specs = Packages :: Packages ( vec ! [ "sysroot" . into( ) ] ) ;
71
+ let specs = specs. to_package_id_specs ( & std_ws) ?;
102
72
let features = match & gctx. cli_unstable ( ) . build_std_features {
103
73
Some ( list) => list. clone ( ) ,
104
74
None => vec ! [
@@ -128,11 +98,13 @@ pub fn resolve_std<'gctx>(
128
98
) )
129
99
}
130
100
131
- /// Generate a list of root `Unit`s for the standard library.
101
+ /// Generates a map of root units for the standard library for each kind requested .
132
102
///
133
- /// The given slice of crate names is the root set.
103
+ /// * `crates` is the arg value from `-Zbuild-std`.
104
+ /// * `units` is the root units of the build.
134
105
pub fn generate_std_roots (
135
106
crates : & [ String ] ,
107
+ units : & [ Unit ] ,
136
108
std_resolve : & Resolve ,
137
109
std_features : & ResolvedFeatures ,
138
110
kinds : & [ CompileKind ] ,
@@ -141,15 +113,52 @@ pub fn generate_std_roots(
141
113
profiles : & Profiles ,
142
114
target_data : & RustcTargetData < ' _ > ,
143
115
) -> CargoResult < HashMap < CompileKind , Vec < Unit > > > {
144
- // Generate the root Units for the standard library.
145
- let std_ids = crates
116
+ // Generate a map of Units for each kind requested.
117
+ let mut ret = HashMap :: new ( ) ;
118
+ let ( core_only, maybe_std) : ( Vec < & CompileKind > , Vec < _ > ) = kinds. iter ( ) . partition ( |kind|
119
+ // Only include targets that explicitly don't support std
120
+ target_data. info ( * * kind) . supports_std == Some ( false ) ) ;
121
+ for ( default_crate, kinds) in [ ( "core" , core_only) , ( "std" , maybe_std) ] {
122
+ if kinds. is_empty ( ) {
123
+ continue ;
124
+ }
125
+ generate_roots (
126
+ & mut ret,
127
+ default_crate,
128
+ crates,
129
+ units,
130
+ std_resolve,
131
+ std_features,
132
+ & kinds,
133
+ package_set,
134
+ interner,
135
+ profiles,
136
+ target_data,
137
+ ) ?;
138
+ }
139
+
140
+ Ok ( ret)
141
+ }
142
+
143
+ fn generate_roots (
144
+ ret : & mut HashMap < CompileKind , Vec < Unit > > ,
145
+ default : & ' static str ,
146
+ crates : & [ String ] ,
147
+ units : & [ Unit ] ,
148
+ std_resolve : & Resolve ,
149
+ std_features : & ResolvedFeatures ,
150
+ kinds : & [ & CompileKind ] ,
151
+ package_set : & PackageSet < ' _ > ,
152
+ interner : & UnitInterner ,
153
+ profiles : & Profiles ,
154
+ target_data : & RustcTargetData < ' _ > ,
155
+ ) -> CargoResult < ( ) > {
156
+ let std_ids = std_crates ( crates, default, units)
146
157
. iter ( )
147
158
. map ( |crate_name| std_resolve. query ( crate_name) )
148
159
. collect :: < CargoResult < Vec < PackageId > > > ( ) ?;
149
- // Convert PackageId to Package.
150
160
let std_pkgs = package_set. get_many ( std_ids) ?;
151
- // Generate a map of Units for each kind requested.
152
- let mut ret = HashMap :: new ( ) ;
161
+
153
162
for pkg in std_pkgs {
154
163
let lib = pkg
155
164
. targets ( )
@@ -162,33 +171,34 @@ pub fn generate_std_roots(
162
171
let mode = CompileMode :: Build ;
163
172
let features = std_features. activated_features ( pkg. package_id ( ) , FeaturesFor :: NormalOrDev ) ;
164
173
for kind in kinds {
165
- let list = ret. entry ( * kind) . or_insert_with ( Vec :: new) ;
166
- let unit_for = UnitFor :: new_normal ( * kind) ;
174
+ let kind = * * kind;
175
+ let list = ret. entry ( kind) . or_insert_with ( Vec :: new) ;
176
+ let unit_for = UnitFor :: new_normal ( kind) ;
167
177
let profile = profiles. get_profile (
168
178
pkg. package_id ( ) ,
169
179
/*is_member*/ false ,
170
180
/*is_local*/ false ,
171
181
unit_for,
172
- * kind,
182
+ kind,
173
183
) ;
174
184
list. push ( interner. intern (
175
185
pkg,
176
186
lib,
177
187
profile,
178
- * kind,
188
+ kind,
179
189
mode,
180
190
features. clone ( ) ,
181
- target_data. info ( * kind) . rustflags . clone ( ) ,
182
- target_data. info ( * kind) . rustdocflags . clone ( ) ,
183
- target_data. target_config ( * kind) . links_overrides . clone ( ) ,
191
+ target_data. info ( kind) . rustflags . clone ( ) ,
192
+ target_data. info ( kind) . rustdocflags . clone ( ) ,
193
+ target_data. target_config ( kind) . links_overrides . clone ( ) ,
184
194
/*is_std*/ true ,
185
195
/*dep_hash*/ 0 ,
186
196
IsArtifact :: No ,
187
197
None ,
188
198
) ) ;
189
199
}
190
200
}
191
- Ok ( ret )
201
+ Ok ( ( ) )
192
202
}
193
203
194
204
fn detect_sysroot_src_path ( target_data : & RustcTargetData < ' _ > ) -> CargoResult < PathBuf > {
0 commit comments