ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.6k stars 2.46k forks source link

zig cc --target=wasm32-wasi-musl: unsupported linker arg: --import-undefined #20636

Open antocuni opened 1 month ago

antocuni commented 1 month ago

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

I have the following hello.c:

#define WASM_EXPORT(name) __attribute__((export_name(#name))) name

int foo(void);

int WASM_EXPORT(bar)(int x, int y) {
    return x + y + foo();
}

The following command fails

$ zig cc --target=wasm32-wasi-musl -c hello.c
$ zig cc --target=wasm32-wasi-musl -mexec-model=reactor -Wl,--import-undefined hello.o -o hello.wasm
error: unsupported linker arg: --import-undefined

I can make it working by invoking wasml-ld directly. This is that I did:

# 1. use zig cc -v *without --import-undefined* to get the wasm-ld command:
$ zig cc -v --target=wasm32-wasi-musl hello.o -mexec-model=reactor -o hello.wasm
wasm-ld --error-limit=0 --export-memory --stack-first --entry _initialize -z stack-size=16777216 -o hello.wasm /home/antocuni/.cache/zig/o/b0372a2115fd741833d24debea7ec384/crt1-reactor.o /home/antocuni/.cache/zig/o/c2fd863b77969fb6f3ed7963872502ec/libc.a hello.o /home/antocuni/.cache/zig/o/dc5b74de12b3bbfc9ca3c1ee2a0ddca5/libcompiler_rt.a
wasm-ld: error: hello.o: undefined symbol: foo

# 2. modify and manually invoke the above wasm-ld command:
$ wasm-ld --import-undefined --error-limit=0 --export-memory --stack-first --entry _initialize -z stack-size=16777216 -o hello.wasm /home/antocuni/.cache/zig/o/b0372a2115fd741833d24debea7ec384/crt1-reactor.o /home/antocuni/.cache/zig/o/c2fd863b77969fb6f3ed7963872502ec/libc.a hello.o /home/antocuni/.cache/zig/o/dc5b74de12b3bbfc9ca3c1ee2a0ddca5/libcompiler_rt.a

$ wasm2wat hello.wasm | grep import
  (import "env" "foo" (func $foo (type 0)))

Expected Behavior

I expect that --export-undefined is passed to the linker.

Note that with wasi-sdk, it works out of the box:

$ clang -c hello.c
$ clang hello.o -mexec-model=reactor -Wl,--import-undefined -o hello.wasm
$ wasm2wat hello.wasm | grep import
  (import "env" "foo" (func $foo (type 0)))
gabydd commented 1 month ago

I believe the correct arg is -Wl,--import-symbols see https://github.com/ziglang/zig/blob/e5c974fa5cd3f9ed49463b597954a053da91de6d/src/link/Wasm.zig#L3547-L3549

so for you example you could use: zig cc --target=wasm32-wasi-musl -mexec-model=reactor hello.o -o hello.wasm -Wl,--import-symbols

antocuni commented 1 month ago

Thank you, -Wl,--import-symbols works! Would be nice to have full compatibility with clang though, so I guess that my bug report is still valid?