canonical / craft-archives

A library for handling archives/repositories in Craft applications
https://canonical-craft-archives.readthedocs-hosted.com
GNU Lesser General Public License v3.0
0 stars 7 forks source link

[Investigate] support foreign architectures #104

Open tigarmo opened 5 months ago

tigarmo commented 5 months ago

What needs to get done

PR #96 restricted the calls to dpkg --add-architecture to only "compatible" pairs of architectures. This suits a lot of use cases, particularly those that just need to download (but not install) packages from a non-host arch.

Where this breaks is effective cross-compilation; any non-trivial cross-compilation case will require dependencies in the target architecture (like dev versions of shared libraries), and the common idiom of:

build-packages:
  - libxx-dev:arch
stage-packages:
  - libxx:arch

does not work because the installation of libxx-dev:arch fails, because the target arch there has not been added to the system via dpkg --add-architecture.

As #96 explains, the reason we can't just call dpkg --add-architeture non-host-arch is because the official archives list all archs (even those they don't have packages for) and default Apt installations do not restrict the archs in those archives. See /etc/apt/sources.list on my machine:

...
deb http://archive.ubuntu.com/ubuntu jammy-updates universe
...

... so apt update will try to fetch the packages listing for "non-host-arch" from archive.ubuntu.com and fail.

What we need to investigate/prototype is a different strategy: if a package-repo with a non-host arch is added (e.g. adding an armhf repo in an amd64 host), we must call dpkg --add-architecture armhf (or whatever arch), but we must also fix those sources listings that don't "pin" the arch. In the example above, the new line would read:

...
deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates universe
...

Here's a series of steps that users are currently doing in host installations to support this scenario:

> dpkg --add-architecture ${ARCH}
> sed -ri "s/^deb /deb [arch=amd64] /g" /etc/apt/sources.list
> apt update
> apt --fix-broken install -y
> apt upgrade -y

... of course, that script only fixes a single file and doesn't do any verification of pre-existing architectures, so the actual commands need to be improved, but the general idea is this.

Why it needs to get done

To make the build system more robust and improve support for cross-compilation.

tigarmo commented 5 months ago

Here's the script that Ondrej uses to configure the lxd instance (to then run Snapcraft in destructive mode inside it): https://github.com/kubiko/toolbox/blob/20/glue/bin/snapcraft-lxd-wrapper

tigarmo commented 5 months ago

Looks like ubuntu-daily images for noble changed the default sources: instead of the regular file /etc/apt/sources.list, it's now in /etc/apt/sources.list.d/ubuntu.sources in deb822 format:

> cat /etc/apt/sources.list.d/ubuntu.sources
...
# Types: deb deb-src
Types: deb
URIs: http://archive.ubuntu.com/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

## Ubuntu security updates. Aside from URIs and Suites,
## this should mirror your choices in the previous section.
# Types: deb deb-src
Types: deb
URIs: http://security.ubuntu.com/ubuntu
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg