i386

  • Partial-port

    i386 is a partial-port of Ubuntu, which is supported as a multi-arch supplementary architecture.

  • No boot support

    There is no kernel, no installers, and no bootloaders for i386, thus it cannot be booted as pure i386.

  • Self-hosted, natively built

    All package building is self-hosting, and is built in an i386 chroot on an amd64 host.

Allowlist

Launchpad has an allowlist of packages that build for i386, which are based on a seed. This was scoped through the community process. The full set of built i386 packages also consists of their build and runtime dependencies.

If in doubt, it is helpful to inspect the Germinate output for i386 on Plucky or Jammy.

The “why” column there explains if it comes directly from the i386 allowlist I386.$series i386 seed or indirectly due to a dependency from another package.

Modifying Dependencies

The allowlist won’t be auto-updated, so if (for example) you worked on dropping a dependency and is confirmed by germinate output for i386 you will then need to contact the Archive Admins to update the allowlist.

This update of the allowlist needs to be done before the sync/rebuild of the package that was formerly depended on. If this was missed, then after updating the allowlist the i386 build record can be created using the following command:

copy-package -b --force-same-destination -e $version $pkg

In rare cases, this command will fail if this exact package version was previously built on powerpc; in that case, a no-change rebuild will achieve the same.

In addition, after that the old binaries need to be removed. Otherwise e.g. proposed migration will block the new package on “missing build on i386”. The Archive Admins usually do this as part of the regular cleanup, but if nothing happens or you want to push on the case one can call to remove it via a removal bug.

How to transition src:foo1 to src:foo2

Sometimes, as part of an ABI transition src:foo(N+1) needs to be built on i386 to eventually replace src:foo(N), for example: boost1.74 -> boost1.83, or gcc-11 -> gcc-12.

When such a need arises, one should:

  1. Ask an Archive Admin to add a new versioned abi-source package to newSet in update-i386-allowlist script in ubuntu-archive-tools

  2. Ask an Archive Admin to run it to update Launchpad’s allowlist

  3. Then one can upload/sync/no-change rebuild src:foo(N+1) and it will be built for i386.

Proposed migration requested i386 test result, which does not exist

Sometimes, Britney requests test results for i386, despite a source package not building for i386 at all.

In such a case please contact the Ubuntu Release Team to update the Britney hint to badtest the i386 result. These usually clear on subsequent uploads, and thus only happen once per source package.

How to expand i386 port scope

If you genuinely need to increase the scope of the i386 port (i.e. 3rd party app now needs a specific i386 library that isn’t yet present), then the community process must be used to nominate and get a library added to the i386 seed as the supported target package.

Alternatively, open bug reports in ubuntu-meta asking for i386: seed inclusion.

Test for i386 dependency issues

A common case to need this is e.g. if you have an autopkgtest with an error like:

php7.4-common:i386 : Depends: php-common:i386 (>= 1:73) but it is not installable
php7.4-json:i386 : Depends: php-common:i386 (>= 1:73) but it is not installable
php7.4-opcache:i386 : Depends: php-common:i386 (>= 1:73) but it is not installable
php7.4-readline:i386 : Depends: php-common:i386 (>= 1:73) but it is not installable

Then, quite often it is secondary or even deeper dependencies that (now on i386) fail. The tests are in x86_64 environments with i386 as arch added, you can easily get that with lxd and dpkg.

$ lxc launch ubuntu-daily:h h-i386
$ lxc exec h-i386 bash
root@h-i386:~# dpkg --add-architecture i386; apt-get update
# There you can re-create the error of the test by installing its dependencies:
root@h-i386:~# apt install php7.4-common:i386 php7.4-json:i386 php7.4-opcache:i386 php7.4-readline:i386

From there feel free to debug as needed.

P.S. quite often this debugging leads into the Multi-Arch definitions of the involved packages.

Cross test for i386

Autopkgtests for i386 on Ubuntu run in an amd64 environment with i386 added via dpkg --add-architecture i386. While that gives working environments sometimes the defaults do not work as expected by test scripts. That provides a common error-pattern which gladly also has a common pattern for a fix.

pkg-config

If run just as pkg-config it will return the data for amd64 which either isn’t installed (the test installed i386 dependencies) or amd64 data for pkg-config is installed does not work for i386. We need to ensure pkg-config is called with the right prefix.

+if [ -n "${DEB_HOST_GNU_TYPE:-}" ]; then
+    CROSS_COMPILE_PREFIX="$DEB_HOST_GNU_TYPE-"
+else
+    CROSS_COMPILE_PREFIX=
+fi
-LDFLAGS="$(pkg-config --libs libftdi1) -lboost_unit_test_framework"
+LDFLAGS="$(${CROSS_COMPILE_PREFIX}pkg-config --libs libftdi1) -lboost_unit_test_framework"

Example bug #974171 submitting this to Debian.

Calling the compiler

Similarly to pkg-config you’ll want the i386 compiler in those cases. Note that the same would equally apply for e.g. armhf on arm64.

+if [ -n "${DEB_HOST_GNU_TYPE:-}" ]; then
+    CROSS_COMPILE_CPP="${CROSS_COMPILE_PREFIX}g++"
+else
+    CROSS_COMPILE_CPP="c++"
+fi
-c++ $CFLAGS -o $WORKDIR/basic.o -c test/basic.cpp
+${CROSS_COMPILE_CPP} $CFLAGS -o $WORKDIR/basic.o -c test/basic.cpp

Example bug #946577 submitting this to Debian.

CMake

CMake projects (as alternative to pkg-config) need the same prefix treatment, but in CMake syntax.

The following example prepends things in a CMakeList file that is later processed. Other cases created a CMake Toolchain file to then be included.

+if [ -n "${DEB_HOST_GNU_TYPE:-}" ]; then
+    cat <<EOF > "$WORKDIR/toolchain.cmake"
+set(CMAKE_C_COMPILER $DEB_HOST_GNU_TYPE-gcc)
+set(CMAKE_CXX_COMPILER $DEB_HOST_GNU_TYPE-g++)
+set(CMAKE_PREFIX_PATH "/usr/lib/${DEB_HOST_MULTIARCH}/cmake/libftdi1")
+set(PKG_CONFIG_EXECUTABLE $DEB_HOST_GNU_TYPE-pkg-config)
+EOF
+    CCFILE=-DCMAKE_TOOLCHAIN_FILE="$WORKDIR/toolchain.cmake"
+else
+    CCFILE=
+fi

Note

Not all cases need all the statements added in the example above, please test and only add the minimum amount of changes.

Warning

This section is a work in progress as e.g. in some cases find_package seems to need further tweaks to work.

Example bug #946496 submitting this to Debian.

Run local VM based autopkgtest for i386

While the following was fine in the past, with Focal that won’t work:

$ sudo autopkgtest-buildvm-ubuntu-cloud -a i386 -r focal -s 15G
Downloading https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-i386.img...
No image exists for this release/architecture

First of all, you need a autopkgtest capable of cross arch testing. To generally get the latest with all the fixes, clone git and run it from there.

$ git clone git+ssh://git.launchpad.net/~ubuntu-release/autopkgtest/+git/development

Since with Focal you only have amd64 images - to run it you have to add the architecture:

--architecture i386

And setup the environment before the testing starts:

--setup-commands="dpkg --add-architecture i386; apt-get update"

Overall that will look like:

$ sudo autopkgtest-buildvm-ubuntu-cloud -a amd64 -r focal -s 15G
$ sudo ~/work/autopkgtest/autopkgtest/runner/autopkgtest \
  --setup-commands="dpkg --add-architecture i386; apt-get update" --architecture i386 <YOUR.dsc>\
  -- qemu --ram-size=1536 --cpus 2 ~/work/autopkgtest-focal-amd64.img

In this example, do NOT run it from a location installed by “make install”, just run it from the checkout location.

i386 allowlist updates

The i386 is a partial archive now.

Add packages to the allowlist

Adding packages to the allowlist is one of the responsibilities of the Archive Admins.

To do so, update the update-i386-allowlist script from ubuntu-archive-tools (typically adding a newSet.update(['$package']) entry.

Run the update-i386-allowlist script:

$ update-i386-allowlist -s $series

Trigger the i386 build either by:

  • Doing an upload

  • Copying the package over itself:

    $ copy-package -b --force-same-destination -e $version $pkg`
    

    Note that if the binary package was built for an earlier release, e.g. Oracular for the current Plucky, you’ll need to adjust the copy-package invocation to:

    $ copy-package -b --from-suite=oracular --to-suite=plucky -e $version $pkg
    

The copy should trigger a build on i386.

After it’s published

Remove the entry from the update-i386-allowlist script.

If the new item isn’t pulled in as a build-/dependencies, manually add it to the ubuntu-seeds repository following the usual semantics of Seed management.