tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.23k stars 898 forks source link

Building WASM artifacts with a tinygo library? #2016

Open simar7 opened 3 years ago

simar7 commented 3 years ago

Is it possible to build a wasm module through a library method? In other words:

Current scenario:

tinygo build -o wasm/sum.wasm -target wasm wasm/sum.go

Ideal Scenario:

mod, _ := tinygo.BuildWasm("wasm/sum.go")

Where mod is a []bytes that can be used.

codefromthecrypt commented 2 years ago

I suspect that running tinygo as a library would be a bridge too far (too much work) due to the dependency on LLVM.

aykevl commented 2 years ago

This is certainly possible, but would mean some amount of refactoring. @simar7 can you explain why you want to do this?

simar7 commented 2 years ago

Sorry it's been a while, but my original motivation was to programmatically build stuff rather than exec a tinygo process.

Let me know if there's any interest in pursuing this. If so, happy to contribute if shown the ropes on how to do so.

james-lawrence commented 2 years ago

FWIW its worth I'm also interested in a go -> wasi embeddable compiler that can be used within an application. LLVM wasn't a huge concern.

I have a few projects where I want a plugin system that can be language agnostic (yay wasi) but need a way to compile source to wasm; ideally without external dependencies.

codefromthecrypt commented 2 years ago

"ideally without external dependencies." I guess that means post any artifacts/shared libs implied by LLVM, wasi-libc, etc as attachments to a release tag (*arch/os) like how wasmtime includes their 45-70MB shared libs, right? https://github.com/bytecodealliance/wasmtime-go/commit/be70ab331d28cb63d2118c80d5293157e01534c0

james-lawrence commented 2 years ago

@codefromthecrypt sorry that was a confusing comment. I didn't mean in my application I mean for the code running in the wasi environment provided by my application.

codefromthecrypt commented 2 years ago

Gotcha, but let me make sure.

You have a wasm+wasi runner defined in Go. Right now, it depends on offline compilation of wasm (or forking a tinygo process). You'd prefer to use tinygo as a library in the runner, so it can compile source to wasm on-demand.

Is that right?

james-lawrence commented 2 years ago

precisely.

codefromthecrypt commented 2 years ago

cool, so I think unless my technical assessment is off (often is) the runner (wasm host) would import a tinygo library, but in doing so need to somehow get access to some non-go artifacts to work, and one way is to attach them to a release. That said, if a feature like this is developed, those developing it can defer details like this until the idea works in general.

aykevl commented 2 years ago

@simar7 can you explain why you need it to be a library rather than an external command?

simar7 commented 2 years ago

@simar7 can you explain why you need it to be a library rather than an external command?

There's nothing wrong with running an external command. In fact that's what I ended up doing for the time being to get traction.

From a security POV, I just find a little less appealing to shell out an external process. If ran through a library call at least I can be somewhat sure that someone will not swap the code that actually gets run under the rug, such as with an exec.

Of course nothing is perfectly safe, library dependencies can be hijacked too.

The other aspect would be testability of code. Injecting test doubles for a library based code base is subjectively easier than one that touches the system with external calls.

Just my 2¥

aykevl commented 2 years ago

Right, I see. Thank you for the clarification.

From a security POV, I just find a little less appealing to shell out an external process. If ran through a library call at least I can be somewhat sure that someone will not swap the code that actually gets run under the rug, such as with an exec.

Unfortunately, that wouldn't help you here. TinyGo itself also runs external commands, for various reasons: