gobusybox
gobusybox copied to clipboard
Go 1.18 support
We should start testing gobusybox with Go 1.18, which is being readied for release some time this month.
New features we have to pay attention to:
- Generics,
- Go workspaces,
- debug/buildinfo
Generics
One of the features of gobusybox is that global variables must be rewritten if they implicitly are initialization statements. For example,
var foo = flag.Uint64("something", 100, "haha")
must be rewritten to
var foo *string
// Some function that can be called if this command is selected by argv[0]
func Init() {
foo = flag.Uint64(...)
}
One of the things that we must do here is derive the return type of flag.String
, which is where paying attention to generics comes in. I don't know Go's generics syntax well yet, but I assume that one can do something like
func NumberFlag[T int64 | int32 | int16 | int8](name string, value T, usage string) *T {
..
}
var foo = NumberFlag[int64]("something", -100, "blabla")
and it has to be rewritten to
// This will always be a concrete type, and never contain type parameters.
var foo *int64
func Init() {
foo = NumberFlag[int64]("something", -100, "blabla")
}
All this happens here in the gobusybox codebase: https://github.com/u-root/gobusybox/blob/fcf634c39c0ed91bde24d69134b7828582d5c030/src/pkg/bb/bbinternal/bb.go#L333-L373
But specifically, the type declaration of the global variable is here: https://github.com/u-root/gobusybox/blob/fcf634c39c0ed91bde24d69134b7828582d5c030/src/pkg/bb/bbinternal/bb.go#L370
We need to verify that all this still works as expected with generics, or find out what needs to be modified. The go/types
did gain support for generics in Go 1.18. See proposal. But hopefully it just works.
Workspaces
Workspaces may mess with how we figure out the main module go.mod and how we synthesize the new directory structure. To be honest, I won't know what's wrong until I try it out, so that's what I suggest: learn about go workspaces and try them out, see how they work, then put a few different modules in a workspace together and see if you can compile them using gobusybox (but I'd avoid u-root at first)
debug/buildinfo
Go binaries will as of Go 1.18 contain a bunch of info about how they were built. If you read the draft release notes and search for "buildinfo" you'll find
Additionally, the go command embeds information about the build including build and tool tags (set with -tags), compiler, assembler, and linker flags (like -gcflags), whether cgo was enabled, and if it was, the values of the cgo environment variables (like CGO_CFLAGS). Both VCS and build information may be read together with module information using go version -m file or runtime/debug.ReadBuildInfo (for the currently running binary) or the new debug/buildinfo package.
This sounds kind of awesome, but it will make binaries produced by gobusybox not reproducible. We should add a bool (or a couple, I don't know what knobs the Go compiler has) to golang.BuildOpts for users to be able to enable/disable this feature and add corresponding flags that can be used in makebb
and u-root
commands.
cc @rminnich @rjoleary @10000TB
If I understand workspaces correctly then it's just a way to separate replace
stanzas from the go.mod file into a go.work file which is usually intended to be marked in the .gitignore as something that should not go into the repo but rather aid local development as one would not need to worry about replace
lines being commited into the repository by accident. So I'd say contents of go.work should be treated exactly like replace
lines in a go.mod file.