Build scripts structure
Zirconium’s build process is organized into modular shell scripts in thebuild_files/ directory. Each script follows a naming convention that indicates its phase and purpose:
- NN: Numeric prefix (00, 01, 02, 99) determines execution order
- name: Descriptive component name (base, theme, nvidia, misc)
- phase: Execution phase (pre, fetch, post)
Build phases
Scripts are organized into three distinct phases, each with specific purposes and constraints:Pre phase
Executes before any package installation. Characteristics:- No network access (
--network=none) - Temporary filesystems for
/var,/tmp,/run,/boot - Used for system preparation and cleanup
- Removing unwanted packages
- Initial filesystem setup
- Preparing for package installation
Fetch phase
Handles package installation and external resource retrieval. Characteristics:- Network access enabled
- Package manager cache persisted (
--mount=type=cache,dst=/var/cache/libdnf5) - Optimized for DNF operations
- Installing packages via DNF
- Enabling COPR repositories
- Downloading external resources
- Cloning git repositories
Post phase
Performs configuration after packages are installed. Characteristics:- No network access (
--network=none) - Files are immutable at this point
- Final configuration and validation
- Copying configuration files
- Enabling systemd services
- Running post-install setup tasks
- Validating installation
Script reference
00-base-pre.sh
Phase: PrePurpose: Remove unnecessary base packages Removes packages that conflict with or are unnecessary for Zirconium:
- console-login-helper-messages: Login message system (replaced by custom solution)
- chrony: NTP daemon (systemd-timesyncd is used instead)
- sssd: System Security Services Daemon (not needed)
- qemu-user-static: QEMU user emulation (build-time only dependency)
- toolbox: Fedora’s container tool (conflicts with Zirconium’s approach)
00-base-fetch.sh
Phase: FetchPurpose: Install core system packages and hardware support Installs essential system components:
Install system packages
Adds NetworkManager, firmware, and utilities:
- Network management (NetworkManager + plugins)
- Firmware packages (alsa, wifi, bluetooth)
- Hardware support (CUPS, fwupd, fprintd)
- System tools (rsync, unzip, wireguard-tools)
The script uses
-x PackageKit* to exclude PackageKit, which conflicts with Zirconium’s update mechanism.00-base-post.sh
Phase: PostPurpose: Configure base system services and settings Key operations:
auditd.service: System auditingbootc-fetch-apply-updates.service: Automatic OS updatesbrew-setup.service: Homebrew initializationfirewalld.service: Firewall managementsystemd-timesyncd.service: Time synchronizationuupd.timer: Universal update checks
01-theme-fetch.sh
Phase: FetchPurpose: Install Niri window manager, DMS, and desktop applications This is the largest build script, installing all desktop components:
Niri window manager
From The version check ensures the git version is installed.
yalter/niri-git COPR:Desktop applications
Core desktop utilities:
- Terminal:
foot - File manager:
nautilus - Display:
brightnessctl,ddcutil - Input:
fcitx5-mozc,input-remapper - Audio:
pipewire,wireplumber,playerctl - Tools:
chezmoi,fastfetch,git-core,just
01-theme-post.sh
Phase: PostPurpose: Configure desktop services and install assets Key configurations:
greetd.service: Login managerdms.service: DankMaterialShell (user)fcitx5.service: Input method (user)foot-server.socket: Terminal server (user)gnome-keyring-daemon.socket: Keyring (user)iio-niri.service: Screen rotation (user)
02-nvidia-fetch.sh
Phase: FetchPurpose: Install NVIDIA drivers (conditional) Installation process:
02-nvidia-post.sh
Phase: PostPurpose: Build NVIDIA kernel modules and configure driver loading Key operations:
99-misc-fetch.sh
Phase: FetchPurpose: Add Flathub repository configuration Simple script that downloads the Flathub repo configuration:
99-misc-post.sh
Phase: PostPurpose: Final system configuration and branding Operations:
99-dracut.sh
Phase: Special (final)Purpose: Generate the initramfs Creates a reproducible initramfs with ostree support:
--no-hostonly: Create generic initramfs (not hardware-specific)--reproducible: Ensure deterministic output--zstd: Use Zstandard compression--add ostree: Include ostree support for bootc-f: Force overwrite existing initramfs
Adding custom build steps
To add your own build phase:Best practices
- Minimize layers: Combine related operations in a single script
- Use cache mounts: Leverage
/var/cache/libdnf5cache for faster rebuilds - Fail fast: Use
set -euo pipefailto catch errors immediately - Validate installations: Check critical files exist before proceeding
- Document changes: Add comments explaining non-obvious operations
- Test incrementally: Build after each new script to catch issues early
- Respect phases: Keep package installation in fetch, configuration in post