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

