|
9 | 9 | "fmt"
|
10 | 10 | "go/token"
|
11 | 11 | "io"
|
| 12 | + "os/exec" |
12 | 13 | "path"
|
13 | 14 | "path/filepath"
|
14 | 15 | "runtime"
|
@@ -248,8 +249,8 @@ func (g *generator) defineWorld(w *wit.World) error {
|
248 | 249 | }
|
249 | 250 |
|
250 | 251 | // Write WIT file for this world
|
251 |
| - witFile := g.witFileFor(w) |
252 |
| - witFile.WriteString(g.res.WIT(wit.Filter(w, nil), "")) |
| 252 | + // witFile := g.witFileFor(w) |
| 253 | + // witFile.WriteString(g.res.WIT(wit.Filter(w, nil), "")) |
253 | 254 |
|
254 | 255 | // Write Go package docs
|
255 | 256 | file := g.fileFor(w)
|
@@ -2319,23 +2320,53 @@ func (g *generator) newPackage(w *wit.World, i *wit.Interface, name string) (*ge
|
2319 | 2320 | g.exportScopes[owner] = gen.NewScope(nil)
|
2320 | 2321 | pkg.DeclareName("Exports")
|
2321 | 2322 |
|
2322 |
| - // Write a Cgo file that adds a library to the linker arguments. |
| 2323 | + // Write a Cgo file and a .wasm library to the linker arguments. |
2323 | 2324 | // The library is a WebAssembly file that includes a custom section
|
2324 | 2325 | // with a name prefixed with "component-type:". The contents are the
|
2325 | 2326 | // Component Model definition for a world that encapsulates the
|
2326 | 2327 | // Component Model types and functions imported into and/or exported
|
2327 | 2328 | // from this Go package.
|
2328 | 2329 | if false {
|
2329 |
| - cgoFile := g.cgoFileFor(owner) |
| 2330 | + // Synthesize a unique-ish library name |
2330 | 2331 | lib := id.String()
|
2331 | 2332 | if name != id.Extension {
|
2332 | 2333 | lib += "-" + name
|
2333 | 2334 | }
|
2334 | 2335 | lib = strings.ReplaceAll(lib, "/", "-")
|
2335 | 2336 | lib = strings.ReplaceAll(lib, ":", "-")
|
| 2337 | + libFile := pkg.File("lib" + lib + ".a") |
| 2338 | + |
| 2339 | + // Generate |
| 2340 | + witText := g.res.WIT(wit.FilterFor(w, i), "") |
| 2341 | + witFile := g.witFileFor(owner) |
| 2342 | + witFile.WriteString(witText) |
| 2343 | + content, err := g.componentEmbed(witText) |
| 2344 | + if err != nil { |
| 2345 | + // return nil, err |
| 2346 | + } |
| 2347 | + libFile.Write(content) |
| 2348 | + |
| 2349 | + // Write Cgo file |
| 2350 | + cgoFile := g.cgoFileFor(owner) |
2336 | 2351 | stringio.Write(cgoFile, "// #cgo LDFLAGS: -L. -l", lib, "\n")
|
2337 | 2352 | stringio.Write(cgoFile, "import \"C\"\n")
|
2338 | 2353 | }
|
2339 | 2354 |
|
2340 | 2355 | return pkg, nil
|
2341 | 2356 | }
|
| 2357 | + |
| 2358 | +// componentEmbed runs generated WIT through wasm-tools to generate a wasm file with a component-type custom section. |
| 2359 | +func (g *generator) componentEmbed(witData string) ([]byte, error) { |
| 2360 | + // TODO: --all-features? |
| 2361 | + cmd := exec.Command("wasm-tools", "component", "embed", "--only-custom", "/dev/stdin") |
| 2362 | + cmd.Stdin = strings.NewReader(witData) |
| 2363 | + stdout := &bytes.Buffer{} |
| 2364 | + stderr := &bytes.Buffer{} |
| 2365 | + cmd.Stdout = stdout |
| 2366 | + cmd.Stderr = stderr |
| 2367 | + err := cmd.Run() |
| 2368 | + if err != nil { |
| 2369 | + g.opts.logger.Errorf("wasm-tools: %s", stderr.String()) |
| 2370 | + } |
| 2371 | + return stdout.Bytes(), err |
| 2372 | +} |
0 commit comments