@@ -1976,10 +1976,11 @@ fn add_linked_symbol_object(
19761976 cmd : & mut dyn Linker ,
19771977 sess : & Session ,
19781978 tmpdir : & Path ,
1979+ crate_type : CrateType ,
19791980 linked_symbols : & [ ( String , SymbolExportKind ) ] ,
19801981 exported_symbols : & [ ( String , SymbolExportKind ) ] ,
19811982) {
1982- if linked_symbols. is_empty ( ) {
1983+ if linked_symbols. is_empty ( ) && exported_symbols . is_empty ( ) {
19831984 return ;
19841985 }
19851986
@@ -2075,26 +2076,35 @@ fn add_linked_symbol_object(
20752076 }
20762077
20772078 if sess. target . is_like_msvc {
2078- // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
2079- // export symbols from a dynamic library. When building a dynamic library,
2080- // however, we're going to want some symbols exported, so this adds a
2081- // `.drectve` section which lists all the symbols using /EXPORT arguments.
2082- //
2083- // The linker will read these arguments from the `.drectve` section and
2084- // export all the symbols from the dynamic library. Note that this is not
2085- // as simple as just exporting all the symbols in the current crate (as
2086- // specified by `codegen.reachable`) but rather we also need to possibly
2087- // export the symbols of upstream crates. Upstream rlibs may be linked
2088- // statically to this dynamic library, in which case they may continue to
2089- // transitively be used and hence need their symbols exported.
2090- let drectve = exported_symbols
2091- . into_iter ( )
2092- . map ( |( sym, _kind) | format ! ( " /EXPORT:\" {sym}\" " ) )
2093- . collect :: < Vec < _ > > ( )
2094- . join ( "" ) ;
2079+ // Symbol visibility takes care of this for executables typically
2080+ let should_filter_symbols = if crate_type == CrateType :: Executable {
2081+ sess. opts . unstable_opts . export_executable_symbols
2082+ } else {
2083+ true
2084+ } ;
2085+ if should_filter_symbols {
2086+ // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
2087+ // export symbols from a dynamic library. When building a dynamic library,
2088+ // however, we're going to want some symbols exported, so this adds a
2089+ // `.drectve` section which lists all the symbols using /EXPORT arguments.
2090+ //
2091+ // The linker will read these arguments from the `.drectve` section and
2092+ // export all the symbols from the dynamic library. Note that this is not
2093+ // as simple as just exporting all the symbols in the current crate (as
2094+ // specified by `codegen.reachable`) but rather we also need to possibly
2095+ // export the symbols of upstream crates. Upstream rlibs may be linked
2096+ // statically to this dynamic library, in which case they may continue to
2097+ // transitively be used and hence need their symbols exported.
2098+ let drectve = exported_symbols
2099+ . into_iter ( )
2100+ . map ( |( sym, _kind) | format ! ( " /EXPORT:\" {sym}\" " ) )
2101+ . collect :: < Vec < _ > > ( )
2102+ . join ( "" ) ;
20952103
2096- let section = file. add_section ( vec ! [ ] , b".drectve" . to_vec ( ) , object:: SectionKind :: Linker ) ;
2097- file. append_section_data ( section, drectve. as_bytes ( ) , 1 ) ;
2104+ let section =
2105+ file. add_section ( vec ! [ ] , b".drectve" . to_vec ( ) , object:: SectionKind :: Linker ) ;
2106+ file. append_section_data ( section, drectve. as_bytes ( ) , 1 ) ;
2107+ }
20982108 }
20992109
21002110 let path = tmpdir. join ( "symbols.o" ) ;
@@ -2271,6 +2281,7 @@ fn linker_with_args(
22712281 cmd,
22722282 sess,
22732283 tmpdir,
2284+ crate_type,
22742285 & codegen_results. crate_info . linked_symbols [ & crate_type] ,
22752286 & codegen_results. crate_info . exported_symbols [ & crate_type] ,
22762287 ) ;
0 commit comments