1
1
#![ allow( deprecated) ]
2
2
use std:: collections:: { HashMap , HashSet } ;
3
+ use std:: fmt:: Write ;
3
4
use std:: path:: PathBuf ;
4
5
use std:: sync:: Arc ;
5
6
6
7
use jobserver:: Client ;
7
8
8
- use core:: { Package , PackageId , Target } ;
9
+ use core:: { Package , PackageId , Resolve , Target } ;
9
10
use core:: profiles:: Profile ;
10
11
use ops:: CompileMode ;
11
12
use util:: errors:: { CargoResult , CargoResultExt } ;
@@ -15,7 +16,6 @@ use super::custom_build::{self, BuildDeps, BuildScripts, BuildState};
15
16
use super :: fingerprint:: Fingerprint ;
16
17
use super :: job_queue:: JobQueue ;
17
18
use super :: layout:: Layout ;
18
- use super :: links:: Links ;
19
19
use super :: { BuildContext , Compilation , Executor , FileFlavor , Kind } ;
20
20
21
21
mod unit_dependencies;
@@ -430,3 +430,69 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
430
430
Ok ( vec ! [ "-C" . to_string( ) , format!( "incremental={}" , dir) ] )
431
431
}
432
432
}
433
+
434
+ #[ derive( Default ) ]
435
+ pub struct Links < ' a > {
436
+ validated : HashSet < & ' a PackageId > ,
437
+ links : HashMap < String , & ' a PackageId > ,
438
+ }
439
+
440
+ impl < ' a > Links < ' a > {
441
+ pub fn new ( ) -> Links < ' a > {
442
+ Links {
443
+ validated : HashSet :: new ( ) ,
444
+ links : HashMap :: new ( ) ,
445
+ }
446
+ }
447
+
448
+ pub fn validate ( & mut self , resolve : & Resolve , unit : & Unit < ' a > ) -> CargoResult < ( ) > {
449
+ if !self . validated . insert ( unit. pkg . package_id ( ) ) {
450
+ return Ok ( ( ) ) ;
451
+ }
452
+ let lib = match unit. pkg . manifest ( ) . links ( ) {
453
+ Some ( lib) => lib,
454
+ None => return Ok ( ( ) ) ,
455
+ } ;
456
+ if let Some ( prev) = self . links . get ( lib) {
457
+ let pkg = unit. pkg . package_id ( ) ;
458
+
459
+ let describe_path = |pkgid : & PackageId | -> String {
460
+ let dep_path = resolve. path_to_top ( pkgid) ;
461
+ let mut dep_path_desc = format ! ( "package `{}`" , dep_path[ 0 ] ) ;
462
+ for dep in dep_path. iter ( ) . skip ( 1 ) {
463
+ write ! ( dep_path_desc, "\n ... which is depended on by `{}`" , dep) . unwrap ( ) ;
464
+ }
465
+ dep_path_desc
466
+ } ;
467
+
468
+ bail ! (
469
+ "multiple packages link to native library `{}`, \
470
+ but a native library can be linked only once\n \
471
+ \n \
472
+ {}\n links to native library `{}`\n \
473
+ \n \
474
+ {}\n also links to native library `{}`",
475
+ lib,
476
+ describe_path( prev) ,
477
+ lib,
478
+ describe_path( pkg) ,
479
+ lib
480
+ )
481
+ }
482
+ if !unit. pkg
483
+ . manifest ( )
484
+ . targets ( )
485
+ . iter ( )
486
+ . any ( |t| t. is_custom_build ( ) )
487
+ {
488
+ bail ! (
489
+ "package `{}` specifies that it links to `{}` but does not \
490
+ have a custom build script",
491
+ unit. pkg. package_id( ) ,
492
+ lib
493
+ )
494
+ }
495
+ self . links . insert ( lib. to_string ( ) , unit. pkg . package_id ( ) ) ;
496
+ Ok ( ( ) )
497
+ }
498
+ }
0 commit comments