Moving forward with go cross compilation
Hello,
I've been sitting down with Mathias Gibbens and we talked about Go and
cross compilation. This mail summarizes the conversation and conclusions
reached.
He indicated that the state of the gcc implementation is not good at the
moment as much Go code has started to use generics which are still
unsupported by the gcc implementation. As a result, we cannot presently
compile many packaged tools writting in Go using gccg. Therefore, we
concluded to focus cross building effort on the golang imlementation,
not doing the work for gccgo while still sketching a path of what would
be needed there.
Fundamentally, Go upstream treats the Go compiler executable name as a
toolchain selector. Other paths tend to be derived by querying it and
often times knowing just the Go compiler path is enough to use a
toolchain. This bears challenges with the traditional cross building
view that tends to use the compiler name to indicate the host
architecture. The Go view here is that the architecture can be selected
after having fixed a toolchain by exporting environment variables such
as GOARCH, GOOS and optionally GOARM.
In supporting both gcc Go and golang Go, we have a choice of either
using gcc's view or Go's view. Given the state of the gcc
implementation, the two of us consider adopting the golang view the
better option long term. That would mean that gcc's implementation
should eventually provide a compatible entry point. This can be
Debian-specific. For instance, /usr/bin/go as installed by gccgo-go
could be changed from being a symbolic link to be a wrapper script that
evaluates GOARCH, GOOS and GOARM to select a suitable TRIPLET-gccgo. In
the absence of those variables, it could forward to /usr/bin/gccgo as
before retaining backwards compatibility.
On the dependency side, a Build-Depends: golang-any needs to transfer
the architecture constraint down for the gcc implementation and
therefore cannot be M-A:foreign. It presently is M-A:same. gccgo-go
would likely have its gccgo-VER dependency become gccgo-VER-for-host and
then things may work.
We note the aspects on gcc to demonstrate a path forward there without
having an intention to perform the required work there. Still that path
enables us to move forward with improving cross compilation for golang
Go. If anyone sees a fundamental problem with the approach sketched,
please tell.
Practically speaking, cross compiling Go things most frequently fails
for running the host architecture Go executable. At one link of the
dependency chain from Build-Depends to golang-VER-go we'll have to
insert a M-A:foreign or :any. We're not sure whether there are practical
use cases for requireing golang-VER-go for a particular architecture,
but since /usr/bin/go compiles for the package's architecture by
default, marking it M-A:foreign is a stretch at least. Marking it
M-A:allowed is an option and then golang-go may have its dependency
annotated :any. This bears a prospect of getting basic Go cross building
to work practically.
In a similar way to Rust, Go is and will be affected by the Multi-Arch
interpreter problem. Arch:all packages are implicitly treated as native
architecture and thereby cannot satisfy cross Build-Depends by default.
If a Go library depends on a C library, the architecture constraint must
be transferred and such libraries presently require using the "multiarch
interpreter workaround", i.e. turning them A:any and optionally
M-A:same. A big chunk of Go modules does not transitively use C
libraries and therefore can be marked M-A:foreign instead. This work has
been carried out to some extent already.
I would like to thank Mathias for having taken the time and it would be
great if this could also be discussed at the Go or cross BoFs to capture
more feedback and arrive at something we may call consensus.
Helmut
Reply to: