53
53
//! is a platform-defined dynamic library. Each library has a metadata somewhere
54
54
//! inside of it.
55
55
//!
56
+ //! A third kind of dependency is an rmeta file. These are rlibs, which contain
57
+ //! metadata, but no code. To a first approximation, these are treated in the
58
+ //! same way as rlibs. Where there is both an rlib and an rmeta file, the rlib
59
+ //! gets priority (even if the rmeta file is newer). An rmeta file is only
60
+ //! useful for checking a downstream crate, attempting to link one will cause an
61
+ //! error.
62
+ //!
56
63
//! When translating a crate name to a crate on the filesystem, we all of a
57
64
//! sudden need to take into account both rlibs and dylibs! Linkage later on may
58
65
//! use either one of these files, as each has their pros/cons. The job of crate
@@ -275,33 +282,31 @@ pub struct CratePaths {
275
282
pub ident : String ,
276
283
pub dylib : Option < PathBuf > ,
277
284
pub rlib : Option < PathBuf > ,
285
+ pub rmeta : Option < PathBuf > ,
278
286
}
279
287
280
288
pub const METADATA_FILENAME : & ' static str = "rust.metadata.bin" ;
281
289
282
290
#[ derive( Copy , Clone , PartialEq ) ]
283
291
enum CrateFlavor {
284
292
Rlib ,
293
+ Rmeta ,
285
294
Dylib ,
286
295
}
287
296
288
297
impl fmt:: Display for CrateFlavor {
289
298
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
290
299
f. write_str ( match * self {
291
300
CrateFlavor :: Rlib => "rlib" ,
301
+ CrateFlavor :: Rmeta => "rmeta" ,
292
302
CrateFlavor :: Dylib => "dylib" ,
293
303
} )
294
304
}
295
305
}
296
306
297
307
impl CratePaths {
298
308
fn paths ( & self ) -> Vec < PathBuf > {
299
- match ( & self . dylib , & self . rlib ) {
300
- ( & None , & None ) => vec ! [ ] ,
301
- ( & Some ( ref p) , & None ) |
302
- ( & None , & Some ( ref p) ) => vec ! [ p. clone( ) ] ,
303
- ( & Some ( ref p1) , & Some ( ref p2) ) => vec ! [ p1. clone( ) , p2. clone( ) ] ,
304
- }
309
+ self . dylib . iter ( ) . chain ( self . rlib . iter ( ) ) . chain ( self . rmeta . iter ( ) ) . cloned ( ) . collect ( )
305
310
}
306
311
}
307
312
@@ -457,11 +462,13 @@ impl<'a> Context<'a> {
457
462
None => return FileDoesntMatch ,
458
463
Some ( file) => file,
459
464
} ;
460
- let ( hash, rlib) = if file. starts_with ( & rlib_prefix[ ..] ) && file. ends_with ( ".rlib" ) {
461
- ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( ) - ".rlib" . len ( ) ) ] , true )
465
+ let ( hash, found_kind) = if file. starts_with ( & rlib_prefix[ ..] ) && file. ends_with ( ".rlib" ) {
466
+ ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( ) - ".rlib" . len ( ) ) ] , CrateFlavor :: Rlib )
467
+ } else if file. starts_with ( & rlib_prefix[ ..] ) && file. ends_with ( ".rmeta" ) {
468
+ ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( ) - ".rmeta" . len ( ) ) ] , CrateFlavor :: Rmeta )
462
469
} else if file. starts_with ( & dylib_prefix) &&
463
470
file. ends_with ( & dypair. 1 ) {
464
- ( & file[ ( dylib_prefix. len ( ) ) ..( file. len ( ) - dypair. 1 . len ( ) ) ] , false )
471
+ ( & file[ ( dylib_prefix. len ( ) ) ..( file. len ( ) - dypair. 1 . len ( ) ) ] , CrateFlavor :: Dylib )
465
472
} else {
466
473
if file. starts_with ( & staticlib_prefix[ ..] ) && file. ends_with ( & staticpair. 1 ) {
467
474
staticlibs. push ( CrateMismatch {
@@ -475,14 +482,14 @@ impl<'a> Context<'a> {
475
482
476
483
let hash_str = hash. to_string ( ) ;
477
484
let slot = candidates. entry ( hash_str)
478
- . or_insert_with ( || ( FxHashMap ( ) , FxHashMap ( ) ) ) ;
479
- let ( ref mut rlibs, ref mut dylibs) = * slot;
485
+ . or_insert_with ( || ( FxHashMap ( ) , FxHashMap ( ) , FxHashMap ( ) ) ) ;
486
+ let ( ref mut rlibs, ref mut rmetas , ref mut dylibs) = * slot;
480
487
fs:: canonicalize ( path)
481
488
. map ( |p| {
482
- if rlib {
483
- rlibs. insert ( p, kind) ;
484
- } else {
485
- dylibs. insert ( p, kind) ;
489
+ match found_kind {
490
+ CrateFlavor :: Rlib => { rlibs. insert ( p, kind) ; }
491
+ CrateFlavor :: Rmeta => { rmetas . insert ( p , kind ) ; }
492
+ CrateFlavor :: Dylib => { dylibs. insert ( p, kind) ; }
486
493
}
487
494
FileMatches
488
495
} )
@@ -499,15 +506,17 @@ impl<'a> Context<'a> {
499
506
// libraries corresponds to the crate id and hash criteria that this
500
507
// search is being performed for.
501
508
let mut libraries = FxHashMap ( ) ;
502
- for ( _hash, ( rlibs, dylibs) ) in candidates {
509
+ for ( _hash, ( rlibs, rmetas , dylibs) ) in candidates {
503
510
let mut slot = None ;
504
511
let rlib = self . extract_one ( rlibs, CrateFlavor :: Rlib , & mut slot) ;
512
+ let rmeta = self . extract_one ( rmetas, CrateFlavor :: Rmeta , & mut slot) ;
505
513
let dylib = self . extract_one ( dylibs, CrateFlavor :: Dylib , & mut slot) ;
506
514
if let Some ( ( h, m) ) = slot {
507
515
libraries. insert ( h,
508
516
Library {
509
517
dylib : dylib,
510
518
rlib : rlib,
519
+ rmeta : rmeta,
511
520
metadata : m,
512
521
} ) ;
513
522
}
@@ -703,6 +712,7 @@ impl<'a> Context<'a> {
703
712
let sess = self . sess ;
704
713
let dylibname = self . dylibname ( ) ;
705
714
let mut rlibs = FxHashMap ( ) ;
715
+ let mut rmetas = FxHashMap ( ) ;
706
716
let mut dylibs = FxHashMap ( ) ;
707
717
{
708
718
let locs = locs. map ( |l| PathBuf :: from ( l) ) . filter ( |loc| {
@@ -744,6 +754,8 @@ impl<'a> Context<'a> {
744
754
for loc in locs {
745
755
if loc. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . ends_with ( ".rlib" ) {
746
756
rlibs. insert ( fs:: canonicalize ( & loc) . unwrap ( ) , PathKind :: ExternFlag ) ;
757
+ } else if loc. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . ends_with ( ".rmeta" ) {
758
+ rmetas. insert ( fs:: canonicalize ( & loc) . unwrap ( ) , PathKind :: ExternFlag ) ;
747
759
} else {
748
760
dylibs. insert ( fs:: canonicalize ( & loc) . unwrap ( ) , PathKind :: ExternFlag ) ;
749
761
}
@@ -753,16 +765,18 @@ impl<'a> Context<'a> {
753
765
// Extract the rlib/dylib pair.
754
766
let mut slot = None ;
755
767
let rlib = self . extract_one ( rlibs, CrateFlavor :: Rlib , & mut slot) ;
768
+ let rmeta = self . extract_one ( rmetas, CrateFlavor :: Rmeta , & mut slot) ;
756
769
let dylib = self . extract_one ( dylibs, CrateFlavor :: Dylib , & mut slot) ;
757
770
758
- if rlib. is_none ( ) && dylib. is_none ( ) {
771
+ if rlib. is_none ( ) && rmeta . is_none ( ) && dylib. is_none ( ) {
759
772
return None ;
760
773
}
761
774
match slot {
762
775
Some ( ( _, metadata) ) => {
763
776
Some ( Library {
764
777
dylib : dylib,
765
778
rlib : rlib,
779
+ rmeta : rmeta,
766
780
metadata : metadata,
767
781
} )
768
782
}
@@ -832,7 +846,7 @@ fn get_metadata_section_imp(target: &Target,
832
846
if !filename. exists ( ) {
833
847
return Err ( format ! ( "no such file: '{}'" , filename. display( ) ) ) ;
834
848
}
835
- if flavor == CrateFlavor :: Rlib {
849
+ if flavor == CrateFlavor :: Rlib || flavor == CrateFlavor :: Rmeta {
836
850
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
837
851
// internally to read the file. We also avoid even using a memcpy by
838
852
// just keeping the archive along while the metadata is in use.
@@ -933,6 +947,8 @@ pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) ->
933
947
let filename = path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
934
948
let flavor = if filename. ends_with ( ".rlib" ) {
935
949
CrateFlavor :: Rlib
950
+ } else if filename. ends_with ( ".rmeta" ) {
951
+ CrateFlavor :: Rmeta
936
952
} else {
937
953
CrateFlavor :: Dylib
938
954
} ;
0 commit comments