Search code examples
gowebassembly

Golang to wasm compilation


I compile a Golang code to wasm using

GOOS=js GOARCH=wasm go build -o main.wasm

I get the following error when trying to execute with wasmtime

wasmtime main.wasm 
Error: failed to run main module `main.wasm`

Caused by:
    0: failed to instantiate "main.wasm"
    1: unknown import: `go::debug` has not been defined

When executing with wasm3, I get

wasm3 main.wasm 
Error: function lookup failed ('_start')

What do these errors mean and how to fix them?


Solution

  • There is currently no way to use the go compiler to produce wasm outside the broswer. The main.wasm in your example is meant to be used with the wasm_exec.js shim. There are ways to use it in Node, however. This is a previous answer of mine, on the same subject. So, your options are:

    1. use Node, as in the question linked above
    node wasm_exec.js main.wasm
    
    1. compile with tinygo, with wasi support
    tinygo build -target=wasi -o main.wasm main.go
    

    wasmtime should run this just fine.

    1. Secret option three: Go actually has very, very bleeding edge support for wasm outside the browser. I don't think any release version of the go compiler have that enabled, so that means you will likely have to compile go from sources. After compilation, your command should become:
    GOOS=wasip1 GOARCH=wasm go build -o main.wasm
    

    with no other changes.

    For your problem, I would say go with (1), in order to have at least something working, and (2) if you want to run it standalone with wasmtime. A new go release should also come soon enough, if you want to wait without compiling yourself.

    EDIT:

    I had time to look into it myself. It seems that option 3 is not that hard to do yourself:

    I followed the instructions here to get the latest go built from sources, which are just:

    go install golang.org/dl/gotip@latest
    gotip download
    

    You have to have go already installed, in order to be able to do the bootstrap, but any recent version will do. After those instructions, you can use gotip just like go. So your command becomes:

    GOOS=wasip1 GOARCH=wasm gotip build -o main.wasm
    

    As wasmtime supports wasi, you should be able to run you program without any other modifications to your commands.

    The compilation of gotip should also not take too much, provided you have a powerful enough computer.