1
1
#![ allow( deprecated) ]
2
2
use std:: collections:: { BTreeSet , HashMap , HashSet } ;
3
3
use std:: ffi:: OsStr ;
4
- use std:: fmt:: Write ;
5
4
use std:: path:: PathBuf ;
6
5
use std:: sync:: { Arc , Mutex } ;
7
6
@@ -10,7 +9,7 @@ use jobserver::Client;
10
9
11
10
use crate :: core:: compiler:: compilation;
12
11
use crate :: core:: compiler:: Unit ;
13
- use crate :: core:: { PackageId , Resolve } ;
12
+ use crate :: core:: PackageId ;
14
13
use crate :: util:: errors:: { CargoResult , CargoResultExt } ;
15
14
use crate :: util:: { internal, profile, Config } ;
16
15
@@ -19,6 +18,7 @@ use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts};
19
18
use super :: fingerprint:: Fingerprint ;
20
19
use super :: job_queue:: JobQueue ;
21
20
use super :: layout:: Layout ;
21
+ use super :: unit_dependencies:: { UnitDep , UnitGraph } ;
22
22
use super :: { BuildContext , Compilation , CompileMode , Executor , FileFlavor , Kind } ;
23
23
24
24
mod compilation_files;
@@ -48,17 +48,14 @@ pub struct Context<'a, 'cfg> {
48
48
/// Linking information for each `Unit`.
49
49
/// See `build_map` for details.
50
50
pub build_scripts : HashMap < Unit < ' a > , Arc < BuildScripts > > ,
51
- /// Used to check the `links` field in the manifest is not duplicated and
52
- /// is used correctly.
53
- pub links : Links ,
54
51
/// Job server client to manage concurrency with other processes.
55
52
pub jobserver : Client ,
56
53
/// "Primary" packages are the ones the user selected on the command-line
57
54
/// with `-p` flags. If no flags are specified, then it is the defaults
58
55
/// based on the current directory and the default workspace members.
59
56
primary_packages : HashSet < PackageId > ,
60
57
/// The dependency graph of units to compile.
61
- unit_dependencies : HashMap < Unit < ' a > , Vec < Unit < ' a > > > ,
58
+ unit_dependencies : UnitGraph < ' a > ,
62
59
/// An abstraction of the files and directories that will be generated by
63
60
/// the compilation. This is `None` until after `unit_dependencies` has
64
61
/// been computed.
@@ -80,7 +77,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
80
77
pub fn new (
81
78
config : & ' cfg Config ,
82
79
bcx : & ' a BuildContext < ' a , ' cfg > ,
83
- unit_dependencies : HashMap < Unit < ' a > , Vec < Unit < ' a > > > ,
80
+ unit_dependencies : UnitGraph < ' a > ,
84
81
) -> CargoResult < Self > {
85
82
// Load up the jobserver that we'll use to manage our parallelism. This
86
83
// is the same as the GNU make implementation of a jobserver, and
@@ -111,7 +108,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
111
108
compiled : HashSet :: new ( ) ,
112
109
build_scripts : HashMap :: new ( ) ,
113
110
build_explicit_deps : HashMap :: new ( ) ,
114
- links : Links :: new ( ) ,
115
111
jobserver,
116
112
primary_packages : HashSet :: new ( ) ,
117
113
unit_dependencies,
@@ -201,18 +197,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
201
197
// pass `--extern` for rlib deps and skip out on all other
202
198
// artifacts.
203
199
let mut doctest_deps = Vec :: new ( ) ;
204
- for dep in self . dep_targets ( unit) {
205
- if dep. target . is_lib ( ) && dep. mode == CompileMode :: Build {
206
- let outputs = self . outputs ( & dep) ?;
200
+ for dep in self . unit_deps ( unit) {
201
+ if dep. unit . target . is_lib ( ) && dep. unit . mode == CompileMode :: Build {
202
+ let outputs = self . outputs ( & dep. unit ) ?;
207
203
let outputs = outputs. iter ( ) . filter ( |output| {
208
204
output. path . extension ( ) == Some ( OsStr :: new ( "rlib" ) )
209
- || dep. target . for_host ( )
205
+ || dep. unit . target . for_host ( )
210
206
} ) ;
211
207
for output in outputs {
212
- doctest_deps. push ( (
213
- self . bcx . extern_crate_name ( unit, & dep) ?,
214
- output. path . clone ( ) ,
215
- ) ) ;
208
+ doctest_deps. push ( ( dep. extern_crate_name , output. path . clone ( ) ) ) ;
216
209
}
217
210
}
218
211
}
@@ -356,10 +349,19 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
356
349
357
350
/// For a package, return all targets which are registered as dependencies
358
351
/// for that package.
352
+ /// NOTE: This is deprecated, use `unit_deps` instead.
359
353
//
360
354
// TODO: this ideally should be `-> &[Unit<'a>]`.
361
355
pub fn dep_targets ( & self , unit : & Unit < ' a > ) -> Vec < Unit < ' a > > {
362
- self . unit_dependencies [ unit] . clone ( )
356
+ self . unit_dependencies [ unit]
357
+ . iter ( )
358
+ . map ( |dep| dep. unit )
359
+ . collect ( )
360
+ }
361
+
362
+ /// Direct dependencies for the given unit.
363
+ pub fn unit_deps ( & self , unit : & Unit < ' a > ) -> & [ UnitDep < ' a > ] {
364
+ & self . unit_dependencies [ unit]
363
365
}
364
366
365
367
pub fn is_primary_package ( & self , unit : & Unit < ' a > ) -> bool {
@@ -369,12 +371,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
369
371
/// Returns the list of filenames read by cargo to generate the `BuildContext`
370
372
/// (all `Cargo.toml`, etc.).
371
373
pub fn build_plan_inputs ( & self ) -> CargoResult < Vec < PathBuf > > {
374
+ // Keep sorted for consistency.
372
375
let mut inputs = BTreeSet :: new ( ) ;
373
- // Note that we're using the `package_cache`, which should have been
374
- // populated by `build_unit_dependencies`, and only those packages are
375
- // considered as all the inputs.
376
- //
377
- // (Notably, we skip dev-deps here if they aren't present.)
376
+ // Note: dev-deps are skipped if they are not present in the unit graph.
378
377
for unit in self . unit_dependencies . keys ( ) {
379
378
inputs. insert ( unit. pkg . manifest_path ( ) . to_path_buf ( ) ) ;
380
379
}
@@ -485,8 +484,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
485
484
fn record_units_requiring_metadata ( & mut self ) {
486
485
for ( key, deps) in self . unit_dependencies . iter ( ) {
487
486
for dep in deps {
488
- if self . only_requires_rmeta ( key, dep) {
489
- self . rmeta_required . insert ( * dep) ;
487
+ if self . only_requires_rmeta ( key, & dep. unit ) {
488
+ self . rmeta_required . insert ( dep. unit ) ;
490
489
}
491
490
}
492
491
}
@@ -513,70 +512,3 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
513
512
self . rmeta_required . contains ( unit)
514
513
}
515
514
}
516
-
517
- #[ derive( Default ) ]
518
- pub struct Links {
519
- validated : HashSet < PackageId > ,
520
- links : HashMap < String , PackageId > ,
521
- }
522
-
523
- impl Links {
524
- pub fn new ( ) -> Links {
525
- Links {
526
- validated : HashSet :: new ( ) ,
527
- links : HashMap :: new ( ) ,
528
- }
529
- }
530
-
531
- pub fn validate ( & mut self , resolve : & Resolve , unit : & Unit < ' _ > ) -> CargoResult < ( ) > {
532
- if !self . validated . insert ( unit. pkg . package_id ( ) ) {
533
- return Ok ( ( ) ) ;
534
- }
535
- let lib = match unit. pkg . manifest ( ) . links ( ) {
536
- Some ( lib) => lib,
537
- None => return Ok ( ( ) ) ,
538
- } ;
539
- if let Some ( & prev) = self . links . get ( lib) {
540
- let pkg = unit. pkg . package_id ( ) ;
541
-
542
- let describe_path = |pkgid : PackageId | -> String {
543
- let dep_path = resolve. path_to_top ( & pkgid) ;
544
- let mut dep_path_desc = format ! ( "package `{}`" , dep_path[ 0 ] ) ;
545
- for dep in dep_path. iter ( ) . skip ( 1 ) {
546
- write ! ( dep_path_desc, "\n ... which is depended on by `{}`" , dep) . unwrap ( ) ;
547
- }
548
- dep_path_desc
549
- } ;
550
-
551
- failure:: bail!(
552
- "multiple packages link to native library `{}`, \
553
- but a native library can be linked only once\n \
554
- \n \
555
- {}\n links to native library `{}`\n \
556
- \n \
557
- {}\n also links to native library `{}`",
558
- lib,
559
- describe_path( prev) ,
560
- lib,
561
- describe_path( pkg) ,
562
- lib
563
- )
564
- }
565
- if !unit
566
- . pkg
567
- . manifest ( )
568
- . targets ( )
569
- . iter ( )
570
- . any ( |t| t. is_custom_build ( ) )
571
- {
572
- failure:: bail!(
573
- "package `{}` specifies that it links to `{}` but does not \
574
- have a custom build script",
575
- unit. pkg. package_id( ) ,
576
- lib
577
- )
578
- }
579
- self . links . insert ( lib. to_string ( ) , unit. pkg . package_id ( ) ) ;
580
- Ok ( ( ) )
581
- }
582
- }
0 commit comments