@@ -10,6 +10,7 @@ use crate::core::{Dependency, PackageId, PackageSet, Resolve, SourceId, Workspac
10
10
use crate :: ops:: { self , Packages } ;
11
11
use crate :: util:: errors:: CargoResult ;
12
12
use crate :: Config ;
13
+ use std:: collections:: hash_map:: Entry ;
13
14
use std:: collections:: { HashMap , HashSet } ;
14
15
use std:: path:: PathBuf ;
15
16
@@ -168,7 +169,8 @@ pub fn generate_std_roots(
168
169
crates : & [ String ] ,
169
170
std_resolve : & Resolve ,
170
171
std_features : & ResolvedFeatures ,
171
- kinds : & [ CompileKind ] ,
172
+ requested_kinds : & [ CompileKind ] ,
173
+ explicit_host_kind : CompileKind ,
172
174
package_set : & PackageSet < ' _ > ,
173
175
interner : & UnitInterner ,
174
176
profiles : & Profiles ,
@@ -182,41 +184,62 @@ pub fn generate_std_roots(
182
184
let std_pkgs = package_set. get_many ( std_ids) ?;
183
185
// Generate a map of Units for each kind requested.
184
186
let mut ret = HashMap :: new ( ) ;
185
- for pkg in std_pkgs {
186
- let lib = pkg
187
- . targets ( )
188
- . iter ( )
189
- . find ( |t| t. is_lib ( ) )
190
- . expect ( "std has a lib" ) ;
191
- // I don't think we need to bother with Check here, the difference
192
- // in time is minimal, and the difference in caching is
193
- // significant.
194
- let mode = CompileMode :: Build ;
195
- let features = std_features. activated_features ( pkg. package_id ( ) , FeaturesFor :: NormalOrDev ) ;
196
- for kind in kinds {
197
- let list = ret. entry ( * kind) . or_insert_with ( Vec :: new) ;
198
- let unit_for = UnitFor :: new_normal ( * kind) ;
187
+
188
+ // Get information for the list of packages for standard library
189
+ let std_pkg_infos: Vec < _ > = std_pkgs
190
+ . iter ( )
191
+ . map ( |pkg| {
192
+ let lib = pkg
193
+ . targets ( )
194
+ . iter ( )
195
+ . find ( |t| t. is_lib ( ) )
196
+ . expect ( "std has a lib" ) ;
197
+ let features =
198
+ std_features. activated_features ( pkg. package_id ( ) , FeaturesFor :: NormalOrDev ) ;
199
+ let unit_for = UnitFor :: new_normal ( explicit_host_kind) ;
200
+ ( pkg, lib, unit_for, features)
201
+ } )
202
+ . collect ( ) ;
203
+
204
+ // Iterate over all packages over the package set to find all targets requested.
205
+ for kind in package_set
206
+ . packages ( )
207
+ . flat_map ( |pkg| pkg. explicit_kinds ( requested_kinds, explicit_host_kind) )
208
+ {
209
+ let e = match ret. entry ( kind) {
210
+ Entry :: Vacant ( e) => e,
211
+ Entry :: Occupied ( _) => continue ,
212
+ } ;
213
+
214
+ let units = std_pkg_infos. iter ( ) . map ( |( pkg, lib, unit_for, features) | {
215
+ // I don't think we need to bother with Check here, the difference
216
+ // in time is minimal, and the difference in caching is
217
+ // significant.
218
+ let mode = CompileMode :: Build ;
199
219
let profile = profiles. get_profile (
200
220
pkg. package_id ( ) ,
201
221
/*is_member*/ false ,
202
222
/*is_local*/ false ,
203
- unit_for,
204
- * kind,
223
+ * unit_for,
224
+ kind,
205
225
) ;
206
- list . push ( interner. intern (
226
+ interner. intern (
207
227
pkg,
208
228
lib,
209
229
profile,
210
- * kind,
230
+ kind,
211
231
mode,
212
232
features. clone ( ) ,
213
233
/*is_std*/ true ,
214
234
/*dep_hash*/ 0 ,
215
235
IsArtifact :: No ,
216
236
None ,
217
- ) ) ;
218
- }
237
+ )
238
+ } ) ;
239
+
240
+ e. insert ( units. collect ( ) ) ;
219
241
}
242
+
220
243
Ok ( ret)
221
244
}
222
245
0 commit comments