Cross compile snap on amd64 to arm

I think there’s 2 compounding issues here you’re running into.

  1. the new snapcraft 3.X doesn’t support cross-compiling the way that the old snapcraft 2.X did.
  2. the new architectures spec doesn’t support both a cross-compiling specification for armhf and a native compiling specification for armhf

for 1, the issue is that even when you specify snapcraft --target-arch=armhf the env var SNAPCRAFT_ARCH_TRIPLET when snapcraft actually runs the build is still the host var. This is a bug with snapcraft and if there’s not already a LP bug I will file one

For 2, the issue is with the design of the architectures key in that there’s no way to specify that a given snapcraft.yaml when run on a particular host architecture could produce either a armhf architecture snap or an amd64 architecture snap. It only allows specifying that a given snapcraft.yaml when built on a particular host architecture results in a specific single architecture (i.e. run-on: armhf) or a single snap which can run on multiple architectures (i.e. architecture generic code like a shell script or python script) which is known as a multiarch snap and specified with run-on: [armhf, amd64].

For now you have two options:

  1. Don’t use base: core18 and don’t use architectures -> then you can cross-compile a go part with snapcraft cleanbuild --target-arch=armhf successfully, this will require you to install lxd on your build machine
  2. Use base: core18 and specify a single architectures stanza for cross-compiling (note that this is mutually exclusive with specifying a native compiling snapcraft.yaml architectures stanza) and hard-code the architecture you want to cross-compile to inside the part’s override-build step, i.e. do something like:
architectures:
  - build-on: amd64
    run-on: armhf

parts:
  my-part:
    source: .
    plugin: go
    override-build:
      mkdir -p $SNAPCRAFT_PART_INSTALL/bin
      GOOS=linux GOARCH=armhf go build -o $SNAPCRAFT_PART_INSTALL/bin/my-app ./cmd/my-app

Then if you wanted to build your app natively for amd64, you would need to change the architectures to be:

architectures:
  - build-on: amd64
    run-on: amd64