bazel-contrib / bazel-contrib/rules_go

Building a multi-package source tree generated by an external tool

Open
#4,333 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
1.5k
Forks
762
Avg merge
1d 11h
Merged PRs (30d)
12

Description

I'm trying to build a Bazel rule to run [`wit-bindgen-go`](https://github.com/bytecodealliance/go-modules/tree/main/cmd/wit-bindgen-go). This is a Go tool that generates a single directory tree of source files containing multiple packages (more docs [here](https://component-model.bytecodealliance.org/language-support/go.html)). I'm struggling to understand if it's possible to somehow use the output of this tool as a dependency to a `go_binary` or `go_library`.

Here's an example of a directory structure that the tool might produce as output, annotated with the package declaration in each Go source file, in case the visual helps:

```
bazel-bin/go/wit-bindgen-output
├── test
│   ├── foo
│   │   └── custom
│   │   ├── custom.wasm.go # package custom
│   │   ├── custom.wit.go # package custom
│   │   └── empty.s
│   └── foo-wrapper
│   └── foo-command
│   └── foo-command.wit.go # package foocommand
└── wasi
└── cli
└── run
├── empty.s
├── run.exports.go # package run
├── run.wasm.go # package run
└── run.wit.go # package run
```

Normally, this is generated into the source tree somewhere, and a normal `go build` command can infer all the import paths from the directory structure, which is obviously not how Bazel rolls.

I thought maybe I could achieve my goal by returning a `GoPath` provider from my build rule, since the output directory looks a lot like a `GOPATH` source tree. I could easily root the generated folders in a parent directory called `src/` . But, AFAICT, you can't use a `go_path` as a "dependency" for a `go_binary`. Am I wrong about that? Whenever I build a `go_binary` with `--sandbox_debug`, I notice it sets `GOPATH=''`. Is that something I could override, in practice or in theory?

Seems like my other option is to generate a complex `GoInfo` and/or `GoArchive` provider with a bunch of dependencies. This (and possibly the `GoPath` option as well) would be complicated by the fact that the set of generated packages depends on the contents of the original WIT files, which is information that could only be available during the execution phase. For instance — in my provided example — `wit-bindgen-go` realized that the only package I needed from `wasi/cli` was the `run` package. There are other packages in that namespace that it neglected to generate Go bindings for because they are not referenced by the main package. I could build a superset of all potentially-generated packages during the analysis phase, but it would be impossible to narrow it down to the exact set of generated packages outside of the execution phase.

Contributor guide

Open the contributing guide

Research direction

Start by reading the rules_go interfaces and rules named in the issue: go_binary, go_library, GoPath, GoInfo, and GoArchive, then compare them with wit-bindgen-go's generated multi-package output. Done means determining whether that output can be represented as a supported dependency or documenting the limitation; the payload names no repository files or tests to run.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
build-system
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.