Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Alternative Package Sets

Importing nixpkgs with a different configuration produces an entirely different package set. Nixpkgs takes advantage of this to expose several pre-configured package sets as attributes directly on pkgs. These cover the most common reasons you might want a non-default build: static linking, a different libc, or a different target architecture.

Because these sets are just nixpkgs imported with different parameters, they compose naturally with the rest of the package set. You can mix packages from multiple sets in the same derivation, using the alternative set only where it is needed.

pkgsStatic

pkgs.pkgsStatic contains packages built with static linking against musl libc. Statically linked binaries have no runtime dependencies on shared libraries, making them easy to distribute and deploy to systems that may not have the same libraries installed.

# A statically linked hello binary
pkgs.pkgsStatic.hello

# Use it as a build input
stdenv.mkDerivation {
  name = "my-tool";
  buildInputs = [ pkgs.pkgsStatic.zlib ];
}

Static builds work well for self-contained command-line tools but are unsupported or broken for many packages — particularly those with mandatory shared library dependencies, plugins, or C extensions. Expect to encounter build failures and treat them as exceptions to fix rather than the norm.

pkgsMusl

pkgs.pkgsMusl is similar to pkgsStatic but produces dynamically linked binaries against musl libc instead of glibc. This is useful when you want the size and compatibility characteristics of musl without full static linking:

pkgs.pkgsMusl.curl

pkgsCross

pkgs.pkgsCross contains package sets for cross-compilation targets. Each attribute is a full nixpkgs instance configured to produce binaries for that target while running on the host machine.

# Produce an aarch64 binary on an x86_64 machine
pkgs.pkgsCross.aarch64-multiplatform.hello

# Produce a RISC-V binary
pkgs.pkgsCross.riscv64.hello

# Produce a Windows binary (using mingw)
pkgs.pkgsCross.mingwW64.hello

Some commonly used targets:

AttributeTarget
aarch64-multiplatform64-bit ARM Linux
aarch64-multiplatform-musl64-bit ARM Linux with musl
riscv6464-bit RISC-V Linux
mingwW6464-bit Windows (MinGW)
raspberryPiARMv6 Linux (Raspberry Pi)
s390xIBM Z (s390x) Linux

Cross-compilation support varies significantly by package. Well-maintained packages in nixpkgs generally cross-compile cleanly. Packages with complex build systems, bundled dependencies, or build-time execution of compiled code are more likely to fail. As with static builds, treat breakages as fixable exceptions rather than reasons to avoid cross-compilation entirely.

Combining alternative sets

Alternative sets can be used as build inputs in ordinary derivations, which is the most common pattern. You do not need to switch your entire build to a cross or static set — just reach into the alternative set for the specific package you need:

stdenv.mkDerivation {
  name = "firmware-bundle";

  # Compile the firmware for ARM, the rest of the build runs natively
  buildInputs = [
    pkgs.pkgsCross.aarch64-multiplatform.openssl
  ];
}

A note on polish

The native x86_64-linux and aarch64-linux package sets are the most thoroughly tested and receive the most attention from the nixpkgs community. Alternative sets — particularly cross-compilation targets and static builds — are less consistently maintained. Some packages have never been tested in these configurations and will fail. If you hit a build failure in an alternative set, check the nixpkgs issue tracker and, if no fix exists, consider contributing one — these configurations improve primarily through users reporting and fixing breakages.