3.2. Build Variables and Environment Files
The build environment should be explicit, shell-specific, and temporary. The supplied env files keep the book's variables out of the user's normal login setup and clear common host build overrides before work begins.
~/.profile, ~/.zshrc, or config.fish. When the build shell ends, the book-specific environment should end with it.
A hand-built system is easier to reason about when the environment is narrow and intentional. Exporting build variables in a normal interactive shell and forgetting about them is a reliable way to create later confusion, because the next unrelated package build or shell session inherits choices that belonged only to this project.
For that reason, this book uses shell-specific env files. They set the variables the build needs, clear the host overrides most likely to leak into toolchain work, and leave room for local customization without forcing everyone into the same directory names or mirror choices.
Provided Files
The repository includes one base env file for each supported shell and one matching example override file for local customization:
- scripts/build-env.sh
- scripts/build-env.zsh
- scripts/build-env.fish
- scripts/build-env.local.sh.example
- scripts/build-env.local.zsh.example
- scripts/build-env.local.fish.example
The base files establish a predictable baseline. The example override files exist for values that are site-specific or personal, such as a local source mirror, a different root directory, or custom compiler flags that should be kept separate from the defaults.
Variables Used by the Book
The environment files use LBI_ and LWI_ prefixes so the variables are obviously tied to Linux by Intent and less likely to collide with unrelated tooling.
LBI_ROOT: top-level working directory for the build.LBI_SOURCES: where source archives and unpacked trees are kept.LBI_SYSROOT: target system root while the build is being assembled.LBI_TOOLS: helper toolchain prefix used before the final system takes over.LBI_BOOT: chosen boot mount point inside the target layout.LBI_ESP_MOUNT: where an ESP is mounted when one is used.LBI_ARCH: target architecture component used when composing the default target triple.LBI_TARGET: target triple for cross and staged builds.LWI_MAKE_JOBS: preferred parallel job count for tools that require a numeric value.LWI_MAKE_FLAGS: preferred make-style parallel flags used bymake,bmake,ninja, andcmake --buildexamples.LWI_CFLAGS,LWI_CXXFLAGS, andLBI_CUSTOM_LDFLAGS: optional local tuning hooks that stay outside the default build policy.
Stopping Host Variable Leakage
The supplied env files explicitly clear common build-time variables before defining the book's defaults. In practice, that means host settings such as CC, CXX, CPPFLAGS, CFLAGS, CXXFLAGS, LDFLAGS, LD_LIBRARY_PATH, PKG_CONFIG_PATH, PKG_CONFIG_LIBDIR, and DESTDIR do not quietly bleed into the bootstrap unless the reader chooses to set them again on purpose.
The goal is not to pretend the host environment does not exist. The goal is to stop accidental host preferences from impersonating book policy.
Representative Defaults
unset CC CXX CPPFLAGS CFLAGS CXXFLAGS LDFLAGS
unset LD_LIBRARY_PATH PKG_CONFIG_PATH PKG_CONFIG_LIBDIR DESTDIR
export LBI_ROOT="${LBI_ROOT:-$HOME/linux-by-intent}"
export LBI_SOURCES="${LBI_SOURCES:-$LBI_ROOT/sources}"
export LBI_TOOLS="${LBI_TOOLS:-$LBI_ROOT/tools}"
export LBI_BOOT="${LBI_BOOT:-/boot}"
export LBI_ESP_MOUNT="${LBI_ESP_MOUNT:-$LBI_SYSROOT/boot/efi}"
export LBI_ARCH="${LBI_ARCH:-x86_64}"
export LBI_TARGET="${LBI_TARGET:-$LBI_ARCH-lbi-linux-musl}"
export LWI_MAKE_JOBS="${LWI_MAKE_JOBS:-$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '1')}"
export LWI_MAKE_FLAGS="${LWI_MAKE_FLAGS:--j$LWI_MAKE_JOBS}"
The fish variant expresses the same policy with fish-native syntax, and the zsh variant follows the same defaults while preserving normal zsh behavior. The values themselves may be changed, but they should be changed in one of the provided env files or in a local override file, not spread across login startup files and half-remembered shell history.
Custom Variables
Local customization belongs in the matching example override file. That keeps personal choices visible and contained instead of silently becoming the documented default for everyone else.
export LWI_CFLAGS="-O2 -pipe"
export LWI_CXXFLAGS="$LWI_CFLAGS"
export LBI_CUSTOM_LDFLAGS=""
export LBI_BOOTLOADER_ID="LinuxByIntent"
Readers who already have their own variable naming scheme may keep using it if they want, but the book will speak in terms of the LBI_ variables so that examples, notes, and scripts stay internally consistent.
Reusable Build-System Functions
The base env files also define helper functions for the three most common build systems used in this project:
lbi_configurefor Autotools-style./configureprojects.lbi_mesonfor Meson projects.lbi_cmakefor CMake projects.
Each helper applies the custom directory layout defaults from section 3.1 under the /system prefix (/system/binaries, /system/systembinaries, /system/libraries, /system/headers, /system/configuration, /system/variable, and documentation paths under /system/documentation) so package installs follow the book's intended structure.
When installing from the host build environment, use DESTDIR="$LBI_ROOT" with packages configured by these helpers. The helpers already place the runtime prefix under /system.
All three helpers accept extra flags. Extra arguments are forwarded directly to the underlying tool, so you can add project-specific options without rewriting the common layout flags each time.
For lbi_meson and lbi_cmake, the first positional argument may be used as the build directory. If omitted, they default to build.
# Autotools
lbi_configure --build="$LBI_TARGET" --disable-nls
# Meson (explicit build directory)
lbi_meson build --buildtype=release -Db_lto=true
# CMake (default build directory, extra generator/flags)
lbi_cmake -G Ninja -DCMAKE_BUILD_TYPE=Release
Makeflags and Parallel Jobs
Set LWI_MAKE_FLAGS for build commands throughout the book, and keep LWI_MAKE_JOBS for tools that require a numeric job value.
Typical setup:
export LWI_MAKE_JOBS="$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '1')"
export LWI_MAKE_FLAGS="-j$LWI_MAKE_JOBS"
Choosing LBI_CUSTOM_* Values
If you want to tune builds, do it deliberately and keep notes about why. The safest path is to start simple, build once, and only then add aggressive options.
In practice, most readers are choosing between a few repeatable profiles rather than inventing flags from scratch:
| Profile | LWI_CFLAGS |
LWI_CXXFLAGS |
LBI_CUSTOM_LDFLAGS |
Best fit | Main caution |
|---|---|---|---|---|---|
| Recommended starting point | -O2 -pipe |
$LWI_CFLAGS |
(empty) | First full build, stable troubleshooting, and easy comparison with upstream defaults. | Usually not the absolute fastest result. |
| Portable x86-64 | -O2 -pipe -mtune=generic |
$LWI_CFLAGS |
(empty) | The image may move between different x86-64 systems. | Gives up some CPU-specific optimization. |
| Native CPU tuning | -O2 -pipe -march=native |
$LWI_CFLAGS |
(empty) | The built system will stay on one known machine or CPU family. | Less portable; failures can be harder to compare across hosts. |
| Debug-heavy build | -O0 -g3 |
$LWI_CFLAGS |
(empty) | You are chasing a toolchain, linker, or package-level failure. | Produces much slower and larger binaries. |
| Clang ThinLTO | -O2 -pipe -flto=thin |
$LWI_CFLAGS |
-fuse-ld=lld |
You are building with Clang and deliberately optimizing for runtime performance. | Longer builds, higher toolchain sensitivity, and a hard dependency on lld. |
| Size-aware linking | -O2 -pipe |
$LWI_CFLAGS |
-Wl,--as-needed -Wl,-O1 |
You want modest link-time cleanup without changing the basic compile profile. | Can expose fragile upstream link ordering. |
Practical rules:
- Start with the recommended row unless you can clearly explain why another profile helps.
- Keep
LWI_CXXFLAGSaligned withLWI_CFLAGSunless you are isolating a C++-specific failure. - If a package breaks under LTO, native tuning, or extra linker flags, retry with plain
-O2 -pipebefore assuming the package itself is broken. - For Clang-based ThinLTO builds, keep
-flto=thinin both compile flag variables and pair it with-fuse-ld=lldinLBI_CUSTOM_LDFLAGS.