How to build a golang multi-arch snap

So, I am a bit confused here. I’ve seen that there’s support for cross-compiling go applications with snap and that there’s support for multi-arch snap.

I have the following snap file:

name: cordless
version: git
summary: Third party discord client
description: |
  A third party discord client for your terminal.

confinement: strict
grade: stable
architectures:
  - amd64
  - arm64
  - armhf
base: core20

parts:
  cordless:
    plugin: go
    go-channel: 1.14/stable
    source: .
    source-type: git
    stage-packages:
      - xclip
      - libnotify-bin
    build-packages:
      - gcc
      - libc6-dev

apps:
  cordless:
    command: bin/cordless
    plugs: [x11, network-bind, desktop]
    environment:
      XDG_CONFIG_DIR: $SNAP_USER_DATA/

However, it only builds one go-binary instead of 3? How could this possibly be cross-compatible. I assuming I am approaching this the wrong way? Do I instead have to build 3 separate snaps? If so, how do i do that? The target-arch parameter seems to have been disabled and I can’t define multiple snapcraft.yml’s since the build command doesn’t appear to allow me choosing one per parameter. I hope someone can help me on this.

Hello :wave:

When doing local builds, the architectures flag doesn’t get processed of a list of snaps to build, but rather a list of supported architectures the snap could be built on. It also allows you to override which host architecture can be used to build snaps for target architectures - see here for some more detail on this behaviour.

target-arch is still usable but only in specific use cases as it is designed for specific part types and is not universally applicable to your situation (cross compilation of an application). It is mostly useful in my experience when building kernels or bootloaders which are natively compiled on the host machine, or with plugins that support cross compilation.

You may want to try using remote-build to have your snap built on the correct architectures automatically using native runners provided by launchpad - this seems to be the direction the tooling is proceeding in to make this easier for folks. If you can’t build on launchpad, you could try your luck with --target-arch for each machine you’d like to build a snap for, but it relies heavily on the plugin in use. In your case, the go plugin, does seem to support cross compilation, so adding architectures and using target-arch or using remote-build are things you could try.

1 Like

If it’s open source you can snapcraft remote-build and it will send the source over to launchpad where it can build all or some of the architectures you specify. I use this all the time to build for aches other than the one my laptop is running. Works very nicely, and means I get to keep my laptop battery for other uses than compiling software :smiley:

Once the remote-build is complete - and if successful, you’ll end up with three snap files in your directory, one for each supported architecture. You also get the build log pulled down. If any of them fail, you can debug that from the individual build logs.

1 Like

Thanks, both of you. Guess i’ll try the remote build over next days :slight_smile:

I just tried remote build via the webinterface. I already specified multiple architechtures, but remote build seems to only queue a build for amd64. Is there anything specific I need to add to my snapcraft.yml? Afaik architechture was supposed to replace build-on and run-on? Oh, and on cli there’s no remote-build subcommand available, that’s correct, right?

Either:

  1. Put architectures with multiple build-on sections (as you did) and use snapcraft.io/build to do build automation
    or/and
  2. Run snapcraft remote-build (optionally with --build-on=amd64,armhf,arm64) to send the build to launchpad

If you have no remote-build option you may be running an outdated snapcraft.

What’s the output of snapcraft version?

Mb, i only checked snapcraft help, it’s not listed there.

Anyway, no luck:

If interrupted, resume with: 'snapcraft remote-build --recover'
Building snap package for amd64, arm64, and armhf. This may take some time to finish.
Build status as of 2020-08-21 20:36:33.375974:
	arch=amd64	state=Needs building
Build status as of 2020-08-21 20:37:03.553452:
	arch=amd64	state=Currently building
Build status as of 2020-08-21 20:37:33.732996:
	arch=amd64	state=Currently building
Build status as of 2020-08-21 20:38:04.069697:
	arch=amd64	state=Currently building
Build status as of 2020-08-21 20:38:34.510911:
	arch=amd64	state=Currently building
Build status as of 2020-08-21 20:39:04.768939:
	arch=amd64	state=Currently building
Build status as of 2020-08-21 20:39:35.205146:
	arch=amd64	state=Currently building
Build status as of 2020-08-21 20:40:05.447673:
	arch=amd64	state=Currently building
Build status as of 2020-08-21 20:40:35.885697:
	arch=amd64	state=Failed to build
Snap file not available for arch 'amd64'.
Build log available at 'cordless_amd64.txt'
Build failed for arch 'amd64'.
Build complete.

In the log it says:

+ go mod download
go mod download: no modules specified (see 'go help mod download')
Failed to build 'cordless'.

Which doesn’t make sense to me, as the project builds locally.