Skip to content

Commit f64ed09

Browse files
committed
Auto merge of #60526 - alexcrichton:wasm-main-symbols, r=oli-obk
rustc: Always handle exported symbols on the wasm target Currently when linking an artifact rustc will only conditionally call the `Linker::export_symbols` function, but this causes issues on some targets, like WebAssembly, where it means that executable outputs will not have the same symbols exported that cdylib outputs have. This commit sinks the conditional call to `export_symbols` inside the various implementations of the function that still need it, and otherwise the wasm linker is configured to always pass through symbol visibility lists.
2 parents a19cf18 + 884632c commit f64ed09

File tree

5 files changed

+31
-8
lines changed

5 files changed

+31
-8
lines changed

src/librustc_codegen_ssa/back/link.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1017,12 +1017,10 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
10171017
}
10181018
}
10191019

1020-
// If we're building a dynamic library then some platforms need to make sure
1021-
// that all symbols are exported correctly from the dynamic library.
1022-
if crate_type != config::CrateType::Executable ||
1023-
sess.target.target.options.is_like_emscripten {
1024-
cmd.export_symbols(tmpdir, crate_type);
1025-
}
1020+
// If we're building something like a dynamic library then some platforms
1021+
// need to make sure that all symbols are exported correctly from the
1022+
// dynamic library.
1023+
cmd.export_symbols(tmpdir, crate_type);
10261024

10271025
// When linking a dynamic library, we put the metadata into a section of the
10281026
// executable. This metadata is in a separate object file from the main

src/librustc_codegen_ssa/back/linker.rs

+10
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,11 @@ impl<'a> Linker for GccLinker<'a> {
372372
}
373373

374374
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
375+
// Symbol visibility in object files typically takes care of this.
376+
if crate_type == CrateType::Executable {
377+
return;
378+
}
379+
375380
// If we're compiling a dylib, then we let symbol visibility in object
376381
// files to take care of whether they're exported or not.
377382
//
@@ -645,6 +650,11 @@ impl<'a> Linker for MsvcLinker<'a> {
645650
fn export_symbols(&mut self,
646651
tmpdir: &Path,
647652
crate_type: CrateType) {
653+
// Symbol visibility takes care of this typically
654+
if crate_type == CrateType::Executable {
655+
return;
656+
}
657+
648658
let path = tmpdir.join("lib.def");
649659
let res: io::Result<()> = try {
650660
let mut f = BufWriter::new(File::create(&path)?);

src/test/run-make/wasm-export-all-symbols/Makefile

+6
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ all:
66
$(RUSTC) bar.rs --target wasm32-unknown-unknown
77
$(RUSTC) foo.rs --target wasm32-unknown-unknown
88
$(NODE) verify.js $(TMPDIR)/foo.wasm
9+
$(RUSTC) main.rs --target wasm32-unknown-unknown
10+
$(NODE) verify.js $(TMPDIR)/main.wasm
911
$(RUSTC) bar.rs --target wasm32-unknown-unknown -O
1012
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O
1113
$(NODE) verify.js $(TMPDIR)/foo.wasm
14+
$(RUSTC) main.rs --target wasm32-unknown-unknown -O
15+
$(NODE) verify.js $(TMPDIR)/main.wasm
1216
$(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto
1317
$(NODE) verify.js $(TMPDIR)/foo.wasm
18+
$(RUSTC) main.rs --target wasm32-unknown-unknown -C lto
19+
$(NODE) verify.js $(TMPDIR)/main.wasm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extern crate bar;
2+
3+
fn main() {}

src/test/run-make/wasm-export-all-symbols/verify.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ for (const entry of list) {
1616
nexports += 1;
1717
}
1818

19-
if (nexports != 1)
20-
throw new Error("should only have one function export");
2119
if (my_exports.foo === undefined)
2220
throw new Error("`foo` wasn't defined");
21+
22+
if (my_exports.main === undefined) {
23+
if (nexports != 1)
24+
throw new Error("should only have one function export");
25+
} else {
26+
if (nexports != 2)
27+
throw new Error("should only have two function exports");
28+
}

0 commit comments

Comments
 (0)