@@ -800,12 +800,8 @@ impl<'a> Linker for GccLinker<'a> {
800800 return ;
801801 }
802802
803- if self . sess . target . is_like_windows {
804- // We already add -export arguments to the .drectve section of symbols.o
805- return ;
806- }
807-
808- let path = tmpdir. join ( "list" ) ;
803+ let is_windows = self . sess . target . is_like_windows ;
804+ let path = tmpdir. join ( if is_windows { "list.def" } else { "list" } ) ;
809805
810806 debug ! ( "EXPORTED SYMBOLS:" ) ;
811807
@@ -821,6 +817,23 @@ impl<'a> Linker for GccLinker<'a> {
821817 if let Err ( error) = res {
822818 self . sess . dcx ( ) . emit_fatal ( errors:: LibDefWriteFailure { error } ) ;
823819 }
820+ } else if is_windows {
821+ let res: io:: Result < ( ) > = try {
822+ let mut f = File :: create_buffered ( & path) ?;
823+
824+ // .def file similar to MSVC one but without LIBRARY section
825+ // because LD doesn't like when it's empty
826+ writeln ! ( f, "EXPORTS" ) ?;
827+ for ( symbol, _) in symbols {
828+ debug ! ( " _{symbol}" ) ;
829+ // Quote the name in case it's reserved by linker in some way
830+ // (this accounts for names with dots in particular).
831+ writeln ! ( f, " \" {symbol}\" " ) ?;
832+ }
833+ } ;
834+ if let Err ( error) = res {
835+ self . sess . dcx ( ) . emit_fatal ( errors:: LibDefWriteFailure { error } ) ;
836+ }
824837 } else {
825838 // Write an LD version script
826839 let res: io:: Result < ( ) > = try {
@@ -844,6 +857,8 @@ impl<'a> Linker for GccLinker<'a> {
844857 self . link_arg ( "-exported_symbols_list" ) . link_arg ( path) ;
845858 } else if self . sess . target . is_like_solaris {
846859 self . link_arg ( "-M" ) . link_arg ( path) ;
860+ } else if is_windows {
861+ self . link_arg ( path) ;
847862 } else {
848863 let mut arg = OsString :: from ( "--version-script=" ) ;
849864 arg. push ( path) ;
@@ -1083,11 +1098,37 @@ impl<'a> Linker for MsvcLinker<'a> {
10831098
10841099 fn export_symbols (
10851100 & mut self ,
1086- _tmpdir : & Path ,
1087- _crate_type : CrateType ,
1101+ tmpdir : & Path ,
1102+ crate_type : CrateType ,
10881103 _symbols : & [ ( String , SymbolExportKind ) ] ,
10891104 ) {
1090- // We already add /EXPORT arguments to the .drectve section of symbols.o
1105+ // We already add /EXPORT arguments to the .drectve section of symbols.o. We generate
1106+ // a .DEF file here anyway as it might prevent auto-export of some symbols.
1107+
1108+ // Symbol visibility takes care of this typically
1109+ if crate_type == CrateType :: Executable {
1110+ let should_export_executable_symbols =
1111+ self . sess . opts . unstable_opts . export_executable_symbols ;
1112+ if !should_export_executable_symbols {
1113+ return ;
1114+ }
1115+ }
1116+
1117+ let path = tmpdir. join ( "lib.def" ) ;
1118+ let res: io:: Result < ( ) > = try {
1119+ let mut f = File :: create_buffered ( & path) ?;
1120+
1121+ // Start off with the standard module name header and then go
1122+ // straight to exports.
1123+ writeln ! ( f, "LIBRARY" ) ?;
1124+ writeln ! ( f, "EXPORTS" ) ?;
1125+ } ;
1126+ if let Err ( error) = res {
1127+ self . sess . dcx ( ) . emit_fatal ( errors:: LibDefWriteFailure { error } ) ;
1128+ }
1129+ let mut arg = OsString :: from ( "/DEF:" ) ;
1130+ arg. push ( path) ;
1131+ self . link_arg ( & arg) ;
10911132 }
10921133
10931134 fn subsystem ( & mut self , subsystem : & str ) {
0 commit comments