gobusybox icon indicating copy to clipboard operation
gobusybox copied to clipboard

Go 1.18 support

Open hugelgupf opened this issue 3 years ago • 2 comments

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.

hugelgupf avatar Feb 12 '22 07:02 hugelgupf

cc @rminnich @rjoleary @10000TB

hugelgupf avatar Feb 12 '22 07:02 hugelgupf

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.

MDr164 avatar Feb 12 '22 14:02 MDr164