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.
This commit is contained in:
parent
3af1bdc4bc
commit
884632cc79
@ -1017,12 +1017,10 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
|
||||
}
|
||||
}
|
||||
|
||||
// If we're building a dynamic library then some platforms need to make sure
|
||||
// that all symbols are exported correctly from the dynamic library.
|
||||
if crate_type != config::CrateType::Executable ||
|
||||
sess.target.target.options.is_like_emscripten {
|
||||
cmd.export_symbols(tmpdir, crate_type);
|
||||
}
|
||||
// If we're building something like a dynamic library then some platforms
|
||||
// need to make sure that all symbols are exported correctly from the
|
||||
// dynamic library.
|
||||
cmd.export_symbols(tmpdir, crate_type);
|
||||
|
||||
// When linking a dynamic library, we put the metadata into a section of the
|
||||
// executable. This metadata is in a separate object file from the main
|
||||
|
@ -372,6 +372,11 @@ impl<'a> Linker for GccLinker<'a> {
|
||||
}
|
||||
|
||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
|
||||
// Symbol visibility in object files typically takes care of this.
|
||||
if crate_type == CrateType::Executable {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're compiling a dylib, then we let symbol visibility in object
|
||||
// files to take care of whether they're exported or not.
|
||||
//
|
||||
@ -645,6 +650,11 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||
fn export_symbols(&mut self,
|
||||
tmpdir: &Path,
|
||||
crate_type: CrateType) {
|
||||
// Symbol visibility takes care of this typically
|
||||
if crate_type == CrateType::Executable {
|
||||
return;
|
||||
}
|
||||
|
||||
let path = tmpdir.join("lib.def");
|
||||
let res: io::Result<()> = try {
|
||||
let mut f = BufWriter::new(File::create(&path)?);
|
||||
|
@ -6,8 +6,14 @@ all:
|
||||
$(RUSTC) bar.rs --target wasm32-unknown-unknown
|
||||
$(RUSTC) foo.rs --target wasm32-unknown-unknown
|
||||
$(NODE) verify.js $(TMPDIR)/foo.wasm
|
||||
$(RUSTC) main.rs --target wasm32-unknown-unknown
|
||||
$(NODE) verify.js $(TMPDIR)/main.wasm
|
||||
$(RUSTC) bar.rs --target wasm32-unknown-unknown -O
|
||||
$(RUSTC) foo.rs --target wasm32-unknown-unknown -O
|
||||
$(NODE) verify.js $(TMPDIR)/foo.wasm
|
||||
$(RUSTC) main.rs --target wasm32-unknown-unknown -O
|
||||
$(NODE) verify.js $(TMPDIR)/main.wasm
|
||||
$(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto
|
||||
$(NODE) verify.js $(TMPDIR)/foo.wasm
|
||||
$(RUSTC) main.rs --target wasm32-unknown-unknown -C lto
|
||||
$(NODE) verify.js $(TMPDIR)/main.wasm
|
||||
|
3
src/test/run-make/wasm-export-all-symbols/main.rs
Normal file
3
src/test/run-make/wasm-export-all-symbols/main.rs
Normal file
@ -0,0 +1,3 @@
|
||||
extern crate bar;
|
||||
|
||||
fn main() {}
|
@ -16,7 +16,13 @@ for (const entry of list) {
|
||||
nexports += 1;
|
||||
}
|
||||
|
||||
if (nexports != 1)
|
||||
throw new Error("should only have one function export");
|
||||
if (my_exports.foo === undefined)
|
||||
throw new Error("`foo` wasn't defined");
|
||||
|
||||
if (my_exports.main === undefined) {
|
||||
if (nexports != 1)
|
||||
throw new Error("should only have one function export");
|
||||
} else {
|
||||
if (nexports != 2)
|
||||
throw new Error("should only have two function exports");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user