Skip to content

Webassembly linker does not import symbols #1622

@josephg

Description

@josephg

Related to #1570...

Consider this zig code:

extern fn inc(a: i32) i32;

export fn add(a: i32, b: i32) i32 {
    return inc(a) + b;
}

... Which expects the symbol inc to be imported from javascript (or whatever environment is embedding the wasm build).

It won't compile, because the linker is (correctly) identifying that it has no idea where inc will come from in the built artifact:

sephsmac:zig josephg$ zig build-lib --release-small --target-arch wasm32 wasm.zig 
lld: error: zig-cache/wasm.o: undefined symbol: inc

sephsmac:zig josephg$ zig build-exe --release-small --target-arch wasm32 wasm.zig 
lld: error: zig-cache/wasm.o: undefined symbol: inc

The wasm linker supports 2 option arguments for dealing with this:

sephsmac:zig josephg$ wasm-ld --help
OVERVIEW: LLVM Linker

USAGE: wasm-ld [options] <inputs>

OPTIONS:
  --allow-undefined-file=<value>
                         Allow symbols listed in <file> to be undefined in linked binary
  --allow-undefined      Allow undefined symbols in linked binary
...

So either this:

$ zig build-obj --release-small --target-arch wasm32 wasm.zig 
$ wasm-ld wasm.o -o xyz.wasm -O2 --no-entry --allow-undefined

or this:

$ zig build-obj --release-small --target-arch wasm32 wasm.zig 
$ echo 'inc' > symbols.txt 
$ wasm-ld wasm.o -o xyz -O2 --no-entry --allow-undefined-file=symbols.txt 
(module
...
  (import "env" "inc" (func $inc (type 0)))
  (func $add (type 2) (param i32 i32) (result i32)
    get_local 0
    call $inc
    get_local 1
    i32.add)
  (export "add" (func $add)))

How should zig import functions from JS? For now maybe just pass --allow-undefined to wasm-ld?

But that said, larger projects we want that link error if you forget to add a function. We could have extern "wasm" fn blah() void;, or something like that. Then compilation could drop all those function names into a text file and pass them via --allow-undefined-file= to the linker.

?? Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions