What is the proper way to build and support multi-architecture snap in store (year 2018)?

Hello!

How do we package architecture specific software it in snapcraft? Our build CI is able to cross-compile and line the binaries up as the following:

bin/hello-i386
bin/hello-amd64
bin/hello-arm
bin/hello-arm64
bin/hello-armhf

For simplicity sake, let’s leave the source-codes (as in, the way Launchpad did with the .deb packages) asides.


#1 Multiple arch specific snaps?
Each snaps is specific to one architecture and I’ll have to run a build script looping all the snapcraft.yaml and upstream them accordingly. This is similar to building deb packages for Launchpad.

NOTE: following Multiple architectures in store


#2 Build a bash script and wrap around each command in the snap?
This is to make use of $SNAP_ARCH environment variables, mentioned in https://askubuntu.com/questions/757668/how-to-build-multi-arch-snaps.

Quote from David Planella: https://askubuntu.com/users/9781/david-planella

#!/bin/sh

case "$SNAP_ARCH" in
    "amd64") ARCH='x86_64-linux-gnu'
    ;;
    "i386") ARCH='i386-linux-gnu'
    ;;
    *)
        echo "Unsupported architecture for this clock app build"
        exit 1
    ;;
esac

NOTE: If possible, I want to avoid this step. It’s ridiculous for snap with a lot of commands.


Our snapcraft.yaml are mostly using prepare, build, install keywords for our dump plugin. We use the shell script commands to pack the binaries accordingly.

We do have a packaging script that help us automate .deb + .snap packaging for our current not architecture specific projects. We don’t mind upgrade it as long as the direction is right.

see the architectures documentation, build-on and run-on were recently added (this does not yet fully work with build.snapcraft.io though, you will have to build locally):

there is also $SNAP_ARCH_TRIPLET:

and $SNAPCRAFT_ARCH_TRIPLET:

1 Like

Thanks for the sharing @ogra.

Based on the documentations, we’ll upgrade our packaging script towards the multiple arch-specific snaps.
That’s is the convincing way to do it while maintaining single snapcraft.yaml script.


To build arch-specific snaps, we issue the snapcraft command with the --target-arch flag and loop across each architectures. E.g.

$ snapcraft --target-arch=i386 ...
$ snapcraft --target-arch=arm64 ...

Inside the scriplets, we chop the $SNAP_ARCH_TRIPLET to get identify the target architecture. From there, we can move the correct arch-specific binary accordingly to match the app commands. Something, like this:

    override-build: |
            case ${SNAPCRAFT_ARCH_TRIPLET%%-*} in
            x86_64)
                echo "x86_64"
                ;;
            i386)
                echo "i386"
                ;;
            *)
                echo "ailen"
            esac

Side-note: the $SNAP_TARGET_ARCH idea is really helpful. +1 instead of doing manual chopping.


When up-streaming all the snaps, the store is able to identify and sort the architectures out under 1 snap name. This applies to user downloads the snap as well.

Yikes! i just updated my snapcraft and now my snaps are all broken - I posted the original question here in 2017 and I was told to use

architectures: [armhf, arm64]

Am I to assume this is no longer supported?

[Update] - after reading over doc’s it looks like this should be supported so maybe I found a bug and I’ll start a new topic: Multi arch snapcraft.yaml broken after snapcraft upgade

1 Like

Did you read the Architectures doc above ? It changed to be more fine grained telling snapcraft with architectures you can build on and on which architectures a binary produced in such a build can run … (build-on and run-on).

There might be backwards compatibility issues though, i’ll leave answering that to the snapcraft team…

yes, i re-read it (and then opened a second topic) note the example is [amd64, i386] which is similar to what I am doing with armhf and arm64

architectures
The architectures on which this snap runs. This defaults to the host architecture unless --target-arch is specified, in which case it defaults to the target architecture. One may specify multiple architectures if that’s supported (for example, a 32-bit snap might run on both i386 and amd64 using [amd64, i386], or a snap that is shell-only might run on all architectures, using all).

Type: list of strings

No I take that back - I thought I read the manual on architectures here:
https://docs.snapcraft.io/build-snaps/syntax#architectures

Uhm… you mean the manual is not correct? some random forum post is the ‘manual’ ? <- please update the official docs or link to the forum post.

based on the forum post - I think what I am supposed to do is change

architectures: [armhf, arm64]

to

architectures:
  - build-on: amd64
    run-on: [armhf, arm64]

(FYI - build machine is amd64)

I suspect you’re reading the docs for snap.yaml and snapcraft.yaml and getting them mixed up: they both have architectures, but they’re different.

No

The link I read and provided (https://docs.snapcraft.io/build-snaps/syntax#architectures) clearly says:

The snapcraft.yaml file is the main entry point to create a snap through Snapcraft.

This has been my ‘goto’ for all snapcraft related RTM issues.

The confusion is that there is a forum post with the tag doc here:

This seems to be more up to date than the manual?

that does seem to be out of date, yes.

Thought so - Well the newer syntax seems to be working …

and this is yet another reason why I think using the forum for documentation is a bad idea™ but I’ve complained about it enough…

9 Likes