5353//! is a platform-defined dynamic library. Each library has a metadata somewhere
5454//! inside of it.
5555//!
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
56+ //! A third kind of dependency is an rmeta file. These are metadata files and do
57+ //! not contain any code, etc . To a first approximation, these are treated in the
5858//! same way as rlibs. Where there is both an rlib and an rmeta file, the rlib
5959//! gets priority (even if the rmeta file is newer). An rmeta file is only
6060//! useful for checking a downstream crate, attempting to link one will cause an
@@ -239,8 +239,8 @@ use rustc_back::target::Target;
239239
240240use std:: cmp;
241241use std:: fmt;
242- use std:: fs;
243- use std:: io;
242+ use std:: fs:: { self , File } ;
243+ use std:: io:: { self , Read } ;
244244use std:: path:: { Path , PathBuf } ;
245245use std:: ptr;
246246use std:: slice;
@@ -462,22 +462,23 @@ impl<'a> Context<'a> {
462462 None => return FileDoesntMatch ,
463463 Some ( file) => file,
464464 } ;
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 )
469- } else if file. starts_with ( & dylib_prefix) &&
470- file. ends_with ( & dypair. 1 ) {
471- ( & file[ ( dylib_prefix. len ( ) ) ..( file. len ( ) - dypair. 1 . len ( ) ) ] , CrateFlavor :: Dylib )
472- } else {
473- if file. starts_with ( & staticlib_prefix[ ..] ) && file. ends_with ( & staticpair. 1 ) {
474- staticlibs. push ( CrateMismatch {
475- path : path. to_path_buf ( ) ,
476- got : "static" . to_string ( ) ,
477- } ) ;
478- }
479- return FileDoesntMatch ;
480- } ;
465+ let ( hash, found_kind) =
466+ if file. starts_with ( & rlib_prefix[ ..] ) && file. ends_with ( ".rlib" ) {
467+ ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( ) - ".rlib" . len ( ) ) ] , CrateFlavor :: Rlib )
468+ } else if file. starts_with ( & rlib_prefix[ ..] ) && file. ends_with ( ".rmeta" ) {
469+ ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( ) - ".rmeta" . len ( ) ) ] , CrateFlavor :: Rmeta )
470+ } else if file. starts_with ( & dylib_prefix) &&
471+ file. ends_with ( & dypair. 1 ) {
472+ ( & file[ ( dylib_prefix. len ( ) ) ..( file. len ( ) - dypair. 1 . len ( ) ) ] , CrateFlavor :: Dylib )
473+ } else {
474+ if file. starts_with ( & staticlib_prefix[ ..] ) && file. ends_with ( & staticpair. 1 ) {
475+ staticlibs. push ( CrateMismatch {
476+ path : path. to_path_buf ( ) ,
477+ got : "static" . to_string ( ) ,
478+ } ) ;
479+ }
480+ return FileDoesntMatch ;
481+ } ;
481482 info ! ( "lib candidate: {}" , path. display( ) ) ;
482483
483484 let hash_str = hash. to_string ( ) ;
@@ -731,7 +732,8 @@ impl<'a> Context<'a> {
731732 return false ;
732733 }
733734 } ;
734- if file. starts_with ( "lib" ) && file. ends_with ( ".rlib" ) {
735+ if file. starts_with ( "lib" ) &&
736+ ( file. ends_with ( ".rlib" ) || file. ends_with ( ".rmeta" ) ) {
735737 return true ;
736738 } else {
737739 let ( ref prefix, ref suffix) = dylibname;
@@ -846,7 +848,7 @@ fn get_metadata_section_imp(target: &Target,
846848 if !filename. exists ( ) {
847849 return Err ( format ! ( "no such file: '{}'" , filename. display( ) ) ) ;
848850 }
849- if flavor == CrateFlavor :: Rlib || flavor == CrateFlavor :: Rmeta {
851+ if flavor == CrateFlavor :: Rlib {
850852 // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
851853 // internally to read the file. We also avoid even using a memcpy by
852854 // just keeping the archive along while the metadata is in use.
@@ -864,6 +866,15 @@ fn get_metadata_section_imp(target: &Target,
864866 Ok ( blob)
865867 }
866868 } ;
869+ } else if flavor == CrateFlavor :: Rmeta {
870+ let mut file = File :: open ( filename) . map_err ( |_|
871+ format ! ( "could not open file: '{}'" , filename. display( ) ) ) ?;
872+ let mut buf = vec ! [ ] ;
873+ file. read_to_end ( & mut buf) . map_err ( |_|
874+ format ! ( "failed to read rlib metadata: '{}'" , filename. display( ) ) ) ?;
875+ let blob = MetadataBlob :: Raw ( buf) ;
876+ verify_decompressed_encoding_version ( & blob, filename) ?;
877+ return Ok ( blob) ;
867878 }
868879 unsafe {
869880 let buf = common:: path2cstr ( filename) ;
0 commit comments