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

How solnix is built

solnix reuses NixOS’s evaluator and module system verbatim, then retargets everything below it to illumos. This is nixbsd’s playbook applied to a different kernel and userland: keep the Nix language, the store, and the module system; replace the OS the packages target. This page describes the layers — the illumos gate, kernel versus userland, how Nix sits on top, and the two toolchains — for a reader who knows Nix/NixOS but is new to illumos.

The illumos gate

illumos is distributed as illumos-gate: a single source repository holding the kernel, the core libraries, the link-editor and runtime linker, and the base userland (libc, the C runtime, the ELF/CTF tools, svc.startd, and so on) — all built together as one coherent tree. Downstream distributions (OmniOS, OpenIndiana, SmartOS) take the gate and add packaging, installers, and extra software on top.

solnix is one such downstream, but instead of a traditional package manager it uses Nix. The gate provides the kernel and the load-bearing userland pieces that must match the kernel’s ABI; Nix provides everything above that and the mechanism for building, distributing, and activating it.

Bootstrap constraint (stated honestly): illumos-gate does not cross-build from Linux. The bootstrap must start on an illumos host — a stage0 seed toolchain, extracted from a gate build, has to run natively on illumos before Nix can take over. See “Seed toolchain” below.

Kernel versus userland

Two boundaries matter on illumos and they shape how Nix layers on:

  • The kernel (unix, genunix, and modules) is inherited from the gate. It provides the system-call interface, ZFS, DTrace, zones, and the fault management architecture. solnix does not rebuild the kernel with Nix in the general case; it is part of the platform the seed and the boot environment carry.
  • The userland splits into a load-bearing base — libc.so.1, the runtime linker ld.so.1, the C runtime objects, the link-editor ld, and the SMF machinery — which must be ABI-compatible with the kernel, and everything else, which is ordinary software Nix can build and place in /nix/store.

solnix packages the load-bearing base as a fine-grained world so that even the lowest layers are Nix-managed store paths, then builds the rest the normal Nix way.

How Nix layers on illumos

Platform tuple

Add x86_64-solaris (GNU triple x86_64-unknown-solaris2.11) to a nixpkgs fork. nixpkgs already carries partial Solaris support — kernels.solaris, isSunOS, and an ld-solaris-wrapper — which is load-bearing for the bootstrap. The other targets follow the same pattern; see CPU architecture support.

pkgs.solnix.* — the fine-grained world

A dedicated package world holds the base illumos pieces as individual Nix derivations:

  • pkgs.solnix.libc — the Solaris libc.so.1 (not glibc).
  • pkgs.solnix.rtld — the runtime linker ld.so.1.
  • pkgs.solnix.ld — the Solaris link-editor.
  • pkgs.solnix.sys — the base tools and headers needed to reach multi-user.

These are the “world slices”: libc, rtld, ld, sys. Everything else in the solnix package set builds against them. (Use pkgs.solnix.*, not pkgs.illumos.*.)

Seed toolchain (stage0)

Because the gate cannot cross-build from Linux, the bootstrap begins with a relocatable seed tarball extracted from an illumos-gate build: a compiler, a linker, libc, the C runtime objects (crt), headers, the runtime linker, and the ELF/CTF tools. It is unpacked into /nix/store and used to build a native Nix stdenv on the illumos host. Once that native stdenv exists, the seed is never referenced again — every later package is built by the Nix-native toolchain, and its outputs land in the binary cache so no one rebuilds them.

Nix’s whole model depends on baking absolute /nix/store paths into binaries so they find their exact dependencies. On solnix this is done with the Solaris link-editor writing ELF RUNPATH, and inspected with elfdumpno GNU tooling. This is a real divergence from Linux nixpkgs, which leans on GNU ld and patchelf; on solnix the native ld and elfdump do the equivalent work.

Init and generations

  • Init is SMF, not systemd. solnix renders SMF manifests and drives svc.startd on activation. See SMF services.
  • Generations map onto ZFS boot environments — each Nix generation is a bootable BE, giving atomic upgrade and instant rollback. See ZFS boot environments.

The two toolchains

illumos-gate historically builds with a specific compiler, and modern illumos work supports both GCC and Clang. solnix carries two toolchains:

  • GCC 14 (current pin) — the primary toolchain, matching the direction illumos-gate has moved for its main build.
  • Clang 21 (current pin) — the alternate toolchain, useful for code that expects Clang and for cross-checking correctness/diagnostics.

Carrying both is deliberate: it keeps solnix honest about portability and gives package authors a fallback when one compiler chokes on illumos-specific code. The seed toolchain provides whichever compiler the stage0 gate build shipped; the Nix-native stdenv then rebuilds GCC 14 and Clang 21 (current pins) as ordinary packages.

Why this order matters

illumos-gate does not cross-build from Linux, so the bootstrap must start on an illumos host. Once a native Nix stdenv exists on illumos, the rest of the package set builds the usual Nix way — and those artifacts land in the binary cache so the community never rebuilds them. The architecture is, in one line: inherit the kernel and load-bearing userland from the gate, Nix-manage everything from libc up, activate through SMF and boot environments.

Further reading