[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: