@@ -777,6 +777,29 @@ fn link_natively(sess: &Session,
777
777
}
778
778
info ! ( "linker stderr:\n {}" , escape_string( & prog. stderr[ ..] ) ) ;
779
779
info ! ( "linker stdout:\n {}" , escape_string( & prog. stdout[ ..] ) ) ;
780
+
781
+
782
+ // When linking a dynamic library with MSVC, we put the metadata
783
+ // in the import library, so we add that here.
784
+ if crate_type == config:: CrateTypeDylib ||
785
+ crate_type == config:: CrateTypeProcMacro {
786
+ if sess. target . target . options . is_like_msvc {
787
+ // Find the import library and add the metadata to it
788
+ let ref imp_lib_name = out_filename. with_extension ( "dll.lib" ) ;
789
+ let ref imp_rlib_name = out_filename. with_extension ( "dll.rlib" ) ;
790
+
791
+ // Import library may not exist if there were no exports
792
+ if fs:: metadata ( imp_lib_name) . is_ok ( ) {
793
+ add_metadata_to_existing_lib ( sess, trans, Some ( imp_lib_name) ,
794
+ imp_rlib_name, tmpdir) ;
795
+ // Remove plain lib file
796
+ remove ( sess, imp_lib_name) ;
797
+ } else {
798
+ add_metadata_to_existing_lib ( sess, trans, None , imp_rlib_name, tmpdir) ;
799
+ }
800
+ }
801
+ }
802
+
780
803
} ,
781
804
Err ( e) => {
782
805
sess. struct_err ( & format ! ( "could not exec the linker `{}`: {}" , pname, e) )
@@ -803,6 +826,22 @@ fn link_natively(sess: &Session,
803
826
}
804
827
}
805
828
829
+ fn add_metadata_to_existing_lib ( sess : & Session ,
830
+ trans : & CrateTranslation ,
831
+ input_lib : Option < & Path > ,
832
+ output_rlib : & Path ,
833
+ tmpdir : & Path ) {
834
+
835
+ info ! ( "adding metadata to {:?} to build {:?}" , input_lib, output_rlib) ;
836
+ let mut ab = ArchiveBuilder :: new ( archive_config ( sess, output_rlib, input_lib) ) ;
837
+ ab. update_symbols ( ) ;
838
+
839
+ let metadata = tmpdir. join ( sess. cstore . metadata_filename ( ) ) ;
840
+ emit_metadata ( sess, trans, & metadata) ;
841
+ ab. add_file ( & metadata) ;
842
+ ab. build ( ) ;
843
+ }
844
+
806
845
fn link_args ( cmd : & mut Linker ,
807
846
sess : & Session ,
808
847
crate_type : config:: CrateType ,
@@ -844,7 +883,11 @@ fn link_args(cmd: &mut Linker,
844
883
// object file, so we link that in here.
845
884
if crate_type == config:: CrateTypeDylib ||
846
885
crate_type == config:: CrateTypeProcMacro {
847
- cmd. add_object ( & outputs. with_extension ( METADATA_OBJ_NAME ) ) ;
886
+ // We store the metadata in the import library instead of the DLL
887
+ // when targetting MSVC.
888
+ if !sess. target . target . options . is_like_msvc {
889
+ cmd. add_object ( & outputs. with_extension ( METADATA_OBJ_NAME ) ) ;
890
+ }
848
891
}
849
892
850
893
// Try to strip as much out of the generated object by removing unused
@@ -1157,6 +1200,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
1157
1200
lib. kind == NativeLibraryKind :: NativeStatic && !relevant_lib ( sess, lib)
1158
1201
} ) ;
1159
1202
1203
+ // If we're not doing LTO, don't need to remove metadata, and don't
1204
+ // want to skip specific object files, then we can take the fast path,
1205
+ // and pass the library directly to the linker without modification.
1160
1206
if !sess. lto ( ) && crate_type != config:: CrateTypeDylib && !skip_native {
1161
1207
cmd. link_rlib ( & fix_windows_verbatim_for_gcc ( cratepath) ) ;
1162
1208
return
@@ -1240,6 +1286,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
1240
1286
if let Some ( dir) = parent {
1241
1287
cmd. include_path ( & fix_windows_verbatim_for_gcc ( dir) ) ;
1242
1288
}
1289
+
1243
1290
let filestem = cratepath. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
1244
1291
cmd. link_rust_dylib ( & unlib ( & sess. target , filestem) ,
1245
1292
parent. unwrap_or ( Path :: new ( "" ) ) ) ;
0 commit comments