Home / Alt manpages / dpkg-architecture(1)

  • dpkg-architecture(1)
  • User command
  • linux

Get Cross-Build Architectures Right with dpkg-architecture

Cross-building a Debian package goes wrong the moment you mix up build, host and target, and dpkg-architecture is how you stop guessing. You will inspect the three roles, pick a host architecture, and pass the values to a command or a Make-based package build.

The examples use dpkg-architecture from dpkg-dev version 1.22.6ubuntu6.6 on this machine. Allow about fifteen minutes. You need a shell and the dpkg-dev package. Every check is an ordinary, unprivileged command, and nothing here changes installed packages or system architecture settings.

1. Keep the three architecture roles separate

Start with the distinction that prevents most mistakes:

  • Build is the machine running the package build.
  • Host is the machine the package is built for. This is usually what you mean when selecting a Debian package architecture.
  • Target is the machine a compiler or emulator produces code for. It matters when building a cross-toolchain or emulator.

On a native build, these values commonly match. In a cross-build, build and host differ. Do not use the host value as a synonym for the machine currently running the command.

Confirm the installed version and the default build and host values:

$ dpkg-architecture --version
Debian dpkg-architecture version 1.22.6.
$ dpkg-architecture -qDEB_BUILD_ARCH
amd64
$ dpkg-architecture -qDEB_HOST_ARCH
amd64

Checkpoint

The exact architecture names depend on the machine. The -q option prints one variable, which is less distracting than the full default list.

2. Inspect the values a build system needs

Ask for the Debian architecture when comparing package metadata. Ask for the GNU type or multiarch value when configuring compiler and library paths:

$ dpkg-architecture -qDEB_HOST_ARCH
amd64
$ dpkg-architecture -qDEB_HOST_GNU_TYPE
x86_64-linux-gnu
$ dpkg-architecture -qDEB_HOST_MULTIARCH
x86_64-linux-gnu

DEB_HOST_GNU_TYPE describes the host as a GNU system type. DEB_HOST_MULTIARCH is the clarified form used for stable multiarch filesystem paths. They are often equal on a current amd64 system, but they mean different things, so use the one your consumer expects.

If you need machine properties rather than a complete name, query DEB_HOST_ARCH_CPU, DEB_HOST_ARCH_OS, DEB_HOST_ARCH_BITS or DEB_HOST_ARCH_ENDIAN. For a Makefile, the installed /usr/share/dpkg/architecture.mk snippet can initialise and export the full set of variables.

3. Select a host architecture for a cross-build

Pass the Debian host architecture with -a. This computes the related GNU values for you:

$ dpkg-architecture -a arm64 -qDEB_HOST_ARCH
arm64
$ dpkg-architecture -a arm64 -qDEB_HOST_GNU_TYPE
aarch64-linux-gnu

The installed command may warn that the selected GNU type does not match the native compiler in CC. That warning earns its keep: selecting an architecture describes the intended build, but it does not install a cross-compiler or make an amd64 compiler produce arm64 binaries.

Use -t when you have a GNU system type rather than a Debian architecture name:

$ dpkg-architecture -t aarch64-linux-gnu -qDEB_HOST_ARCH
arm64

Usually choose one of -a or -t, not both. If both are supplied and disagree, stop and fix the selection rather than relying on whichever value happens to appear last.

Tip

These options affect this invocation only. They do not persist in your shell, change dpkg or reconfigure the compiler, and they need no elevated privileges.

4. Export the computed environment for one command

Use -c to run a command with the calculated variables set. This keeps the environment scoped to the child process:

$ dpkg-architecture -a arm64 -c 'printf "%s %s\n" "$DEB_HOST_ARCH" "$DEB_HOST_MULTIARCH"'
arm64 aarch64-linux-gnu

The command string is passed through the Bourne shell when it contains shell metacharacters. Quote values carefully, especially if any part comes from outside your own script. The exit status is the child command's status, so check the command itself when this is a build gate.

For a persistent shell change, print assignments and evaluate them deliberately:

$ eval "$(dpkg-architecture -a arm64 -s)"
$ printf '%s\n' "$DEB_HOST_ARCH"
arm64

Warning

eval executes text produced by a command. Here the producer is the local utility with a fixed architecture argument, which is fine. Do not substitute untrusted text into this pattern.

To remove the variables from the current shell, use eval "$(dpkg-architecture -u)", or open a new shell. The command does not alter files.

5. Make architecture checks explicit

Use -e for an exact Debian architecture comparison. It returns status 0 for a match and 1 for a mismatch:

$ dpkg-architecture -a arm64 -e arm64
$ printf 'status: %s\n' "$?"
status: 0
$ dpkg-architecture -a arm64 -e amd64
$ printf 'status: %s\n' "$?"
status: 1

Use -i when a wildcard is what you mean. This expands the architecture wildcard before comparing it:

$ dpkg-architecture -a arm64 -i linux-any
$ printf 'status: %s\n' "$?"
status: 0

The two checks are not interchangeable. -e linux-any asks whether the literal Debian architecture is named linux-any. -i linux-any asks whether the host matches a Linux architecture wildcard. In a script, branch on the status immediately and keep status 1 distinct from a command failure.

6. Take the values from Make, not from guesswork

Do not parse dpkg --print-architecture during a package build. The manpage specifically directs build scripts to dpkg-architecture. A small Makefile can query exactly what it needs:

DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)

ifeq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE))
configure_args += --build=$(DEB_HOST_GNU_TYPE)
else
configure_args += --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
endif

show-architecture:
\t@printf 'build=%s host=%s arch=%s\n' \
\t  "$(DEB_BUILD_GNU_TYPE)" "$(DEB_HOST_GNU_TYPE)" "$(DEB_HOST_ARCH)"

The ?= assignments leave a command-line or environment override available, while still providing a value for a manual invocation. Run the checkpoint target before a real build:

$ make show-architecture
build=x86_64-linux-gnu host=x86_64-linux-gnu arch=amd64

For a Debian packaging workflow, include /usr/share/dpkg/architecture.mk is the supported shortcut when that file is available.

Tip

For a cross-compile, verify the compiler, sysroot and dependency packages separately. Architecture variables alone cannot supply those pieces.

7. Find valid architectures without changing anything

-L lists known architecture names. Narrow the list when checking a policy or picking a test value:

$ dpkg-architecture -B 64 -E little -L | head -n 5
uclibc-linux-armel
uclibc-linux-alpha
uclibc-linux-amd64
uclibc-linux-arc
uclibc-linux-armeb

The output lists names known to this installation, not a promise that a compiler, runtime or package repository for every name is installed. The filters:

  • -B accepts 32 or 64.
  • -E accepts little or big.
  • -W filters by an architecture wildcard.

These filters apply to -L, not to an ordinary architecture query.

Done means

  • Roles clear. You can say which machine is build, host and target for the job.
  • Right variable. You queried the one that matches the consumer: Debian architecture, GNU type or multiarch path.
  • Cross-build checked. Your selection uses -a or -t and has been compared with the available compiler.
  • Scoped environment. One-command overrides use -c, and any eval is limited to trusted local output.
  • Tests are exact. Your architecture checks distinguish exact equality from wildcard identity and read the exit status immediately.
  • Make does it properly. Your workflow takes values from dpkg-architecture instead of calling dpkg --print-architecture.