// internals
Building
Both architectures, from one tree.
x86_64
make # → visor_x64.efi
The Makefile finds the gnu-efi headers and crt0-efi-x86_64.o across
distro layouts. If yours is unusual:
make GNU_EFI_INC=/path/to/efi CRT0=/path/to/crt0-efi-x86_64.o
Missing gnu-efi stops the build early with an explanatory message and the per-distro install command, not a cryptic compiler error.
Modular builds
Since 1.5.6 the build is driven from the feature registry in
features/features.json. A PROFILE picks a canned
feature set; FEATURES fine-tunes it flag-style:
make PROFILE=minimal
make PROFILE=ricer FEATURES=-blur,+capture
make PROFILE=custom FEATURES=bls,pointer,auditioning_boot
Features are listed with make list-features (which also shows
the active profile and per-feature on/off state), and dependencies via
make list-all-features-deps. Dropping a feature swaps in its
no-op stub; features another feature depends on pull along with
dependencies. make check-features re-validates the registry, the
dependency graph, and the stub list against the real tree. The full
features.json blurbs are what the installer &
visor CLI present when choosing between profiles.
AArch64
tools/setup_gnuefi_aarch64.sh # once: cross-builds gnu-efi for arm64
make ARCH=aarch64 # → visor_aa64.efi
Needs aarch64-linux-gnu-gcc. Distro gnu-efi packages ship x86-64
objects only, so the setup script cross-builds gnu-efi from
gnu-efi-src/ and stages crt0/libs/linker script where the Makefile
expects them. Builds combine ARCH= with the
PROFILE/FEATURES machinery; the built-in audio driver
(src/audio/hda.c) compiles to no-op stubs on AArch64 — the boot
game remains x86_64.
What the build does
- Resolves features: a
PROFILEturns into a feature set, thenFEATURES=+name,-nameoverrides apply (with dependency closure), and every off feature pulls in its stub fromsrc/stubs/. - Compiles the feature-selected
src/**/*.cfreestanding:-ffreestanding -fpic -fshort-wchar -fno-stack-protector -mno-red-zone(x86) /-mstrict-align(arm),-Wall -Wextra -O2, objects intobuild/<arch>/. Version and the embeddedVISORFT1manifest come fromPKGBUILDand thefeatures/registry via-DVISOR_VERSIONand generated code. - Links a shared object against gnu-efi with the arch linker script (
src/visor_x86_64.lds/ gnu-efi's arm one) and version scriptsrc/efi.vers— now includingsrc/security/tcg2.candsrc/boot/loader_iface.c. objcopyconverts it to a PE (pei-x86-64/pei-aarch64-little, subsystem 10 = EFI application).- x86 only: rewrites the
.relocsection with a minimal valid block and verifies its PageRVA — some binutils write a broken relocation block that firmware rejects; the build catches this instead of producing an unbootable image. - Docs & tools:
makealso validatesboot.conf.schema.jsongeneration (viatools/tag_schema.py); host toolstools/vbg_encode.py(needsffmpeg+python-numpy) andvisor convertare installed to/usr/share/visor/toolswhen packaging.
Build rules of the house
- Zero warnings on
makeandmake ARCH=aarch64. Always. - RELATIVE-only relocations. After any change, verify:
Non-relative relocations (from float literals, some initializers, or accidental libc calls) produce a binary that some firmware silently refuses to boot.readelf -r build/x86_64/visor.so | grep R_X86_64 | grep -v R_X86_64_RELATIVE # must be empty - No floating point anywhere. The compiler flags don't forbid it — discipline does. Fixed-point (Q16) for anything fractional.
Other targets
| Target | Purpose |
|---|---|
make clean | Remove objects and binaries. |
make install | Build then run ./install.sh. |
make list-features | Show the active PROFILE/FEATURES, every feature with its on/off state, and the available profiles. |
make list-all-features | List all feature names, and make list-all-features-deps their dependencies. |
make check-features | Validate features/features.json, the dependency graph, and stubs against the real tree. |
make bakefont FONT=/path/font.ttf FONT_PX=64 | Re-bake src/gui/font_jetbrains.c from a TTF (needs Python + Pillow). |
make BUILD_DIR=/tmp/visor-build | Build with objects outside the tree. |