Example cross-compiled app¶
Projects built using the Autotools plugin can be cross-compiled, allowing software to be developed on one architecture and built for a number of target architectures.
Example project file for example-curl¶
The following code comprises the project file for a project that uses libcurl. The complete code can be found in this repository.
hello-curl project
name: hello-curl
version: "1.0"
summary: cross-compiled app that uses curl
description: |
A cross-compiled snap that uses libcurl. This exercises installing
libcurl-dev as a build package and staging libcurl, both from ubuntu-ports.
grade: devel
base: core24
confinement: strict
platforms:
armhf:
build-on: [amd64]
build-for: [armhf]
arm64:
build-on: [amd64]
build-for: [arm64]
riscv64:
build-on: [amd64]
build-for: [riscv64]
lint:
ignore:
- library
apps:
hello-curl:
command: usr/bin/hello-curl
package-repositories:
- type: apt
architectures: [$CRAFT_ARCH_BUILD_FOR]
formats: [deb, deb-src]
components: [main]
suites: [noble, noble-updates, noble-backports]
key-id: F6ECB3762474EDA9D21B7022871920D1991BC93C
url: http://ports.ubuntu.com/ubuntu-ports
parts:
hello-curl:
plugin: autotools
source: src
build-environment:
- PKG_CONFIG_PATH: "/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/pkgconfig"
build-packages:
- pkg-config
- libcurl4-openssl-dev:$CRAFT_ARCH_BUILD_FOR
- gcc-$CRAFT_ARCH_TRIPLET_BUILD_FOR
- libc6-dev-$CRAFT_ARCH_BUILD_FOR-cross
stage-packages:
- libcurl4t64:$CRAFT_ARCH_BUILD_FOR
autotools-configure-parameters:
- --prefix=/usr
- --host=$CRAFT_ARCH_TRIPLET_BUILD_FOR
Enable cross-compilation¶
The platforms key specifies which architectures should
be used when building a snap. The platforms
key can also be used to specify sets
of architectures with the build-on
and build-for
keys. In the simplest case,
this can be used to cross-compile on one architecture for a single, different
architecture:
platforms:
- build-on: amd64
build-for: armhf
In this example, Snapcraft will only build the project on the AMD64 architecture, and it will only build it for the armhf architecture.
In the hello-curl
project, the platforms
key to lists several cross-compilation
targets:
platforms:
armhf:
build-on: [amd64]
build-for: [armhf]
arm64:
build-on: [amd64]
build-for: [arm64]
riscv64:
build-on: [amd64]
build-for: [riscv64]
Adjust the Autotools configuration¶
When building for a particular architecture, Snapcraft will initialise the
CRAFT_ARCH_TRIPLET_BUILD_FOR
environment variable in the build environment. This
variable describes the platform and architecture that Autotools uses to configure
cross-compilation. For more information on environment variables, see environment
variables.
A project building with the Autotools plugin can adjust the options passed to the
configure
script for a given part with the plugin’s
autotools-configure-parameters
key.
autotools-configure-parameters:
- --prefix=/usr
- --host=$CRAFT_ARCH_TRIPLET_BUILD_FOR
Satisfy the dependencies¶
The build-packages
key specifies which packages will supply the toolchain and
libraries necessary for cross-compilation.
build-packages:
- pkg-config
- libcurl4-openssl-dev:$CRAFT_ARCH_BUILD_FOR
- gcc-$CRAFT_ARCH_TRIPLET_BUILD_FOR
- libc6-dev-$CRAFT_ARCH_BUILD_FOR-cross
Package repositories can also be
specified for the target platform using the package-repositories
key and the
CRAFT_ARCH_BUILD_FOR
environment variable.
package-repositories:
- type: apt
architectures: [$CRAFT_ARCH_BUILD_FOR]
formats: [deb, deb-src]
components: [main]
suites: [noble, noble-updates, noble-backports]
key-id: F6ECB3762474EDA9D21B7022871920D1991BC93C
url: http://ports.ubuntu.com/ubuntu-ports
To select the correct library for the target platform, include these packages in the
stage-packages
key with the package:repo
syntax.
stage-packages:
- libcurl4t64:$CRAFT_ARCH_BUILD_FOR
The build-packages
and stage-packages
keys additionally support the advanced
grammar keys, which allow
further customisation of packages installed per-platform.
Build the snap¶
To build the snap, navigate to the project directory and run:
snapcraft
Because linters are enabled by default for core24
snaps, this will produce warnings
like the following:
user@host:~$
snapcraft
not a dynamic executable
arm-binfmt-P: Could not open '/lib/ld-linux-armhf.so.3': No such file or directory
Unable to determine library dependencies for '/root/prime/usr/bin/autotools-cross-compile-example'
This is because snapcraft is unable to resolve the dependencies for the target architecture using the library linter.
Since the /lib/ld-linux-armhf.so.3
library will be present in the base of the
target system, these warnings can be suppressed for this case by including a lint
section in the project file:
lint:
ignore:
- library
Rebuild the snap, and this time it should finish without warnings. A .snap
file for
each target architecture is deposited at the root of the project directory. Each snap is
distinguished by the architecture name at the end of its name. The
hello-curl project should’ve created three files, ending in _armhf.snap
,
_arm64.snap
, and _riscv.snap
.