ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.

Home Page:https://ziglang.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

antocuni opened this issue · comments

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)))

I believe the correct arg is -Wl,--import-symbols see

zig/src/link/Wasm.zig

Lines 3547 to 3549 in e5c974f

if (wasm.import_symbols) {
try argv.append("--allow-undefined");
}

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

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?