@@ -1976,10 +1976,11 @@ fn add_linked_symbol_object(
1976
1976
cmd : & mut dyn Linker ,
1977
1977
sess : & Session ,
1978
1978
tmpdir : & Path ,
1979
+ crate_type : CrateType ,
1979
1980
linked_symbols : & [ ( String , SymbolExportKind ) ] ,
1980
1981
exported_symbols : & [ ( String , SymbolExportKind ) ] ,
1981
1982
) {
1982
- if linked_symbols. is_empty ( ) {
1983
+ if linked_symbols. is_empty ( ) && exported_symbols . is_empty ( ) {
1983
1984
return ;
1984
1985
}
1985
1986
@@ -2075,26 +2076,35 @@ fn add_linked_symbol_object(
2075
2076
}
2076
2077
2077
2078
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 ( "" ) ;
2095
2103
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
+ }
2098
2108
}
2099
2109
2100
2110
let path = tmpdir. join ( "symbols.o" ) ;
@@ -2271,6 +2281,7 @@ fn linker_with_args(
2271
2281
cmd,
2272
2282
sess,
2273
2283
tmpdir,
2284
+ crate_type,
2274
2285
& codegen_results. crate_info . linked_symbols [ & crate_type] ,
2275
2286
& codegen_results. crate_info . exported_symbols [ & crate_type] ,
2276
2287
) ;
0 commit comments