bazel-contrib / bazel-contrib/rules_go
Building a multi-package source tree generated by an external tool
- 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
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