Skip to content

Commit 64a1e54

Browse files
committed
Allow implementing different WIT worlds in wasip2 target
As mentioned in [this comment](#4843 (comment)), we are also interested in Wasm components with custom worlds (for [Grafbase extensions](https://grafbase.com/docs/gateway/extensions)). I have succesfully compiled and used examples based on the changes in this branch. They are mostly from @daedric's patch in the issue. So this PR is meant as a starting point for discussions, a working branch for anyone else looking at trying this, and to discuss how best to test it (I've made attempts, but they added up to a lot of code, and I wasn't too happy with them). I understand it's work to review and merge something like this, and even more to provide guidance on a proper test setup, so while feedback would be much appreciated, I understand if it's not a priority. fixes #4843
1 parent 733a17d commit 64a1e54

File tree

5 files changed

+45
-5
lines changed

5 files changed

+45
-5
lines changed

builder/build.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,11 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
914914
}
915915

916916
// Run wasm-tools for component-model binaries
917+
wasiPackage := strings.ReplaceAll(config.Target.WASIPackage, "{root}", goenv.Get("TINYGOROOT"))
918+
if config.Options.WASIPackage != "" {
919+
wasiPackage = config.Options.WASIPackage
920+
}
921+
917922
witPackage := strings.ReplaceAll(config.Target.WITPackage, "{root}", goenv.Get("TINYGOROOT"))
918923
if config.Options.WITPackage != "" {
919924
witPackage = config.Options.WITPackage
@@ -922,7 +927,37 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
922927
if config.Options.WITWorld != "" {
923928
witWorld = config.Options.WITWorld
924929
}
930+
925931
if witPackage != "" && witWorld != "" {
932+
if wasiPackage != "" {
933+
934+
fmt.Println("Embedding WASI component. Wasi package: ", wasiPackage)
935+
936+
// wasm-tools component embed -w wasi:cli/command
937+
// $$(tinygo env TINYGOROOT)/lib/wasi-cli/wit/ main.wasm -o embedded.wasm
938+
componentEmbedInputFile := result.Binary
939+
result.Binary = result.Executable + ".wasm-component-embed-1"
940+
args := []string{
941+
"component",
942+
"embed",
943+
wasiPackage,
944+
componentEmbedInputFile,
945+
"-o", result.Binary,
946+
}
947+
948+
wasmtools := goenv.Get("WASMTOOLS")
949+
if config.Options.PrintCommands != nil {
950+
config.Options.PrintCommands(wasmtools, args...)
951+
}
952+
cmd := exec.Command(wasmtools, args...)
953+
cmd.Stdout = os.Stdout
954+
cmd.Stderr = os.Stderr
955+
956+
err := cmd.Run()
957+
if err != nil {
958+
return fmt.Errorf("`wasm-tools component embed` failed: %w", err)
959+
}
960+
}
926961

927962
// wasm-tools component embed -w wasi:cli/command
928963
// $$(tinygo env TINYGOROOT)/lib/wasi-cli/wit/ main.wasm -o embedded.wasm

compileopts/options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type Options struct {
5656
Monitor bool
5757
BaudRate int
5858
Timeout time.Duration
59+
WASIPackage string // pass trough to wasm-tools component first embed invocation
5960
WITPackage string // pass through to wasm-tools component embed invocation
6061
WITWorld string // pass through to wasm-tools component embed -w option
6162
ExtLDFlags []string

compileopts/target.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ type TargetSpec struct {
6565
JLinkDevice string `json:"jlink-device,omitempty"`
6666
CodeModel string `json:"code-model,omitempty"`
6767
RelocationModel string `json:"relocation-model,omitempty"`
68+
WASIPackage string `json:"wasi-package,omitempty"`
6869
WITPackage string `json:"wit-package,omitempty"`
6970
WITWorld string `json:"wit-world,omitempty"`
7071
}

main.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,19 +1285,19 @@ microcontrollers, it is common to use the .elf file extension to indicate a
12851285
linked ELF file is generated. For Linux, it is common to build binaries with no
12861286
extension at all.`
12871287

1288-
usageRun = `Run the program, either directly on the host or in an emulated environment
1288+
usageRun = `Run the program, either directly on the host or in an emulated environment
12891289
(depending on -target).`
12901290

12911291
usageFlash = `Flash the program to a microcontroller. Some common flags are described below.
12921292
1293-
-target={name}:
1293+
-target={name}:
12941294
Specifies the type of microcontroller that is used. The name of the
12951295
microcontroller is given on the individual pages for each board type
12961296
listed under Microcontrollers
12971297
(https://tinygo.org/docs/reference/microcontrollers/).
12981298
Examples: "arduino-nano", "d1mini", "xiao".
12991299
1300-
-monitor:
1300+
-monitor:
13011301
Start the serial monitor (see below) immediately after
13021302
flashing. However, some microcontrollers need a split second
13031303
or two to configure the serial port after flashing, and
@@ -1347,7 +1347,7 @@ instead of the expected \n (also known as ^J, NL, or LF) to indicate
13471347
end-of-line. You may be able to get around this problem by hitting Control-J in
13481348
tinygo monitor to transmit the \n end-of-line character.`
13491349

1350-
usageGdb = `Build the program, optionally flash it to a microcontroller if it is a remote
1350+
usageGdb = `Build the program, optionally flash it to a microcontroller if it is a remote
13511351
target, and drop into a GDB shell. From there you can set breakpoints, start the
13521352
program with "run" or "continue" ("run" for a local program, continue for
13531353
on-chip debugging), single-step, show a backtrace, break and resume the program
@@ -1631,8 +1631,9 @@ func main() {
16311631
flag.StringVar(&outpath, "o", "", "output filename")
16321632
}
16331633

1634-
var witPackage, witWorld string
1634+
var witPackage, witWorld, wasiPackage string
16351635
if command == "help" || command == "build" || command == "test" || command == "run" {
1636+
flag.StringVar(&wasiPackage, "wasi-package", "", "wasi package for wasm component embedding")
16361637
flag.StringVar(&witPackage, "wit-package", "", "wit package for wasm component embedding")
16371638
flag.StringVar(&witWorld, "wit-world", "", "wit world for wasm component embedding")
16381639
}
@@ -1720,6 +1721,7 @@ func main() {
17201721
Monitor: *monitor,
17211722
BaudRate: *baudrate,
17221723
Timeout: *timeout,
1724+
WASIPackage: wasiPackage,
17231725
WITPackage: witPackage,
17241726
WITWorld: witWorld,
17251727
}

targets/wasip2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"src/runtime/asm_tinygowasm.S"
2929
],
3030
"emulator": "wasmtime run --wasm component-model -Sinherit-network -Sallow-ip-name-lookup --dir={tmpDir}::/tmp {}",
31+
"wasi-package": "{root}/lib/wasi-cli/wit/",
3132
"wit-package": "{root}/lib/wasi-cli/wit/",
3233
"wit-world": "wasi:cli/command"
3334
}

0 commit comments

Comments
 (0)