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

Re: cross building go packages?

On Fri, May 15, 2020 at 08:34:48AM +1200, Michael Hudson-Doyle wrote:
> On Fri, 15 May 2020 at 06:18, Helmut Grohne <helmut@subdivi.de> wrote:
> > I did not propose "golang-any".
> golang-any is a package that already exists. It exists to allow packages to
> build with "Google Go" (i.e. golang-go) on architectures where it is
> available and gccgo where it is not.

The confusion was on my side. Thank you for the explanation.

> The suggestion was to change golang-any to depend on golang-go:native
> rather than just golang-go.

Unfortunately, that will not work. ":native" is not allowed in binary
package dependencies. It can only be used in Build-Depends.

> (The gccgo-go / golang-go split is another dimension to this, I guess to
> cross build with gccgo you need something like option 5)

That's an interesting wrinkle that I completely overlooked. Thank you!

Looking down that rabbit hole one can see that gcc effectively
implements parts of option 5 already. On amd64, there already is
x86_64-linux-gnu-go-9. I fear that I agree with your conclusion here.
Let me get into more detail of how that would look like.

So gccgo-9 already contains the relevant triplet-prefixed tools. Beyond
that the gcc-9-cross source package builds gccgo cross compilers. What
is missing thus far is the split into gccgo-9-<triplet> vs gccgo-9 for
native compilers. I've sent a patch for doing that in #666743. Then,
we'd add gccgo-9-for-build and gccgo-9-for-host packages. Doing so is
relatively simple after the previous step and analogous to what happened
to binutils. The same dance is necessary for gcc-defaults such that we
end up with gccgo-<triplet>, gccgo-for-build and gccgo-for-host.

What are these ${TOOL}-for-build and ${TOOL}-for-host packages about
precisely? A dependency (or build-dependency) on ${TOOL}-for-host asks
for an instance of the tool that targets the architecture of the
dependency. Since Build-Depends are interpreted as host architecture
dependencies, the primary motive here is using it in Build-Depends. The
${TOOL}-for-host interface does not provide a ${TOOL} executable on
$PATH. Instead, it requires the caller to run the tool as
${DEB_HOST_GNU_TYPE}-${TOOL}. On the other hand, the ${TOOL}-for-build
variant selects the tool for the build architecture. It provides a
${TOOL} executable that targets the build (or native) architecture. In
the vast majority of uses in Build-Depends, one needs ${TOOL}-for-host.

The golang side is less clear to me. We'd also need golang-go-for-build
and golang-go-for-host. golang-go-for-host would be a Multi-Arch: same
package containing ${DEB_HOST_GNU_TYPE}-go wrapper scripts that
effectively set up the environment we added the dh golang buildsystem in
#930176 and then execs the real go. It would need a dependency on the
native architecture go executable package. Since it is a binary package,
we cannot use :native annotations here. So golang-go would have to
become either Multi-Arch: foreign or Multi-Arch: allowed. We're using a
combination of option 2 or 4 and 5 here. golang-go-for-host would depend
on golang-go (without or with :any). Then golang-go-for-build isn't
strictly needed as it doesn't provide anything different from golang-go
(without or with :any).  In option 2, it could be provided as a virtual
package and in option 4 it could be an empty binary package depending on
golang-go:any if deemed worthwhile for consistency.

The golang-defaults package would gain two new, empty packages
golang-any-for-build and golang-any-for-host with dependencies on
"golang-go-for-build | gccgo-go-for-build" and "golang-go-for-host |
gccgo-go-for-host" respectively.

To make a go package cross buildable, a golang-go dependency would
either become golang-go:any and something would set up the cross
environment (e.g. the golang debhelper buildsystem) or one would use
golang-go-for-host and replace every invocation of plain "go" with
"<triplet>-go". A golang-any dependency would become golang-any-for-host
and invocations of plain "go" would have to be replaced likewise.

This sounds like a lot of quite disruptive changes.

Still it seems to me that we can tackle these layers somewhat
independently. Even if we do the option 5 dance for the golang-any
layer, we can still do another option for the golang-go layer and have
it provide the *-for-build and *-for-host variants.

I don't have a good intuition of whether it is "safe" to mark golang-go
Multi-Arch: foreign. Are there situations where you would load
architecture-dependent plugins into the golang go compiler?

We could also start with Multi-Arch: foreign and see whether it breaks.
Switching from Multi-Arch: foreign to Multi-Arch: allowed is a lot less
painful than the other way round.

The other part of this is that using "golang-any:native" in
Build-Depends is wrong. That's a non-option since you'd get the wrong
compiler when the gcc alternative is selected. We can practically rule
out that option.

I think a relatively safe conclusion at this point is that we want to
mark golang-go with Multi-Arch something regardless of how the rest
plays out. Just what that something is isn't entirely clear to me.


Reply to: