Drive supported workflows directly through scripts/nvx.py; no Make wrapper
is required.
The portable workflow downloads the pinned Linux archive, verifies its
SHA-256, applies every patch in kernel/patches, and builds Linux plus the
selected guest artifacts in Docker. Alpine remains the default. OpenVMM builds
on the host:
python3 scripts/nvx.py build-guest
python3 scripts/nvx.py build-openvmmnvx verify selects native architecture pins from SOURCE-MANIFEST.json. The
top-level Linux/Alpine pins remain x86_64; architectures.aarch64 supplies the
ARM kernel configuration, patch list and Alpine archive URL/checksum. Common
version and source metadata remain pinned for both architectures. ARM validation
requires the ARM direct-boot settings and the same sandbox protections; it does
not require the x86 xe9 driver.
Build every guest artifact, including the Ubuntu EROFS distro layer, with:
python3 scripts/nvx.py build-guest --guest allThe OpenVMM restore step excludes the compatibility IGVM artifact, which NVX does not build or package, so builds do not depend on unrelated upstream workflow artifacts.
OpenVMM builds do not require access to runtime hypervisor devices. By default,
Windows builds the native MSVC executable and Linux builds the native GNU
target. Both build-openvmm and build accept --backend: kvm selects GNU,
mshv selects the statically linked musl target on Linux, and whp selects
MSVC on Windows. For example, this builds musl without requiring /dev/mshv:
python3 scripts/nvx.py build-openvmm --backend mshvThe combined build command rejects unsupported OS/backend combinations before
producing guest artifacts. Guest-only and source-only commands do not select an
OpenVMM build target.
When invoked through NVX, OpenVMM's custom TTRPC lifecycle, SMP, and snapshot
test uses the ACPI-free, MP-enabled build/vmlinux and
build/initramfs.cpio.gz artifacts. The phase-1 lifecycle and TTRPC interface
tests continue to use OpenVMM's packaged guest artifacts.
On a Linux host, build either initramfs directly:
python3 scripts/nvx.py build-initramfs --guest alpine
python3 scripts/nvx.py build-initramfs --guest ubuntuThe default build produces:
build/vmlinux
build/vmlinux.config
build/vmlinux.provenance.json
build/initramfs.cpio.gz
build/initramfs.cpio.gz.packages.json
build/initramfs.provenance.json
build/openvmm.provenance.json
openvmm/target/release/openvmm[.exe]
Programmatic callers can select the backend and override the output destination
through OpenVmmBuildConfig. Native and
musl builds normalize the newly built executable to that destination before
recording its provenance. Host OS detection and backend validation live in
build.py, not in the configuration object.
Fixed build inputs and defaults live in
build_constants.py. Its namespace
classes group kernel, OpenVMM, Alpine, Ubuntu, initramfs, Docker, cache-tool,
and release settings. For example, Python callers use
KernelBuildConstants.VERSION and AlpineBuildConstants.MINIROOTFS_SHA256;
the previous module-level constants are not re-exported. Shared repository
and artifact directories belong to BuildConstants.
Keep per-invocation choices and overrides in the existing build configuration objects. Environment-dependent cache locations and host-dependent executable selection are still resolved by their helpers when a configuration is created, not frozen into the constants module.
The provenance sidecars bind the kernel to its pinned archive, patch set, input configuration, generated configuration, and output hash; bind the initramfs and package manifest to the pinned Alpine inputs and source files; and bind OpenVMM to the exact clean gitlink revision and executable hash. The Alpine source-file inputs include the constants module. Packaging rejects missing, dirty, stale, or mismatched provenance.
Ubuntu adds:
build/initramfs-ubuntu.cpio.gz
build/initramfs-ubuntu.cpio.gz.packages.json
build/ubuntu-distro.erofs
build/ubuntu-distro.erofs.manifest.json
Prepare the Ubuntu sandbox layer separately on Linux without replacing an existing output:
python3 scripts/nvx.py build-distro-layer \
--guest ubuntu \
--output build/ubuntu-distro.erofsPass --replace only when intentionally rebuilding that path. The native
Ubuntu build requires zstd, and EROFS conversion additionally requires
mkfs.erofs from erofs-utils. The builder verifies Ubuntu Base and every
supplemental .deb before safe extraction and never executes binaries or
maintainer scripts from the Ubuntu root. The Docker builder pins its Debian
base image by digest and installs an exact erofs-utils version so clean EROFS
builds use the same encoder.
Check both Ubuntu outputs for deterministic rebuilds with:
python3 scripts/nvx.py verify-guest-determinism --guest ubuntuRun the two test layers separately:
python3 scripts/nvx.py test-openvmm --backend kvm
python3 scripts/nvx.py test-microvm --backend kvm
python3 scripts/nvx.py test-microvm --backend kvm --guest ubuntuBoth commands need the standard guest build outputs above. The second writes
complete per-scenario logs under
build/test-results/microvm by default.
The Alpine initramfs includes the sandbox PID-1 bootstrap, its container namespace
helpers, the static nvx-device-io benchmark helper, and the static
nvx-port-io restore packet helper under /sbin. The matching kernel enables
virtio-blk, compressed EROFS, overlayfs, ext4 scratch, memory cgroups, and
cgroup BPF. The build fails if olddefconfig drops any required option. The
APK manifest records the blkid and util-linux tools used by the bootstrap
plus the device helper's source and binary SHA-256 values.
The platform configuration also enables Unix-domain sockets for local guest
IPC and seccomp filters for workload syscall policies. Overlayfs does not
unconditionally follow redirect metadata. These are kernel capabilities, not
product-agent configuration; the same requirements are checked after
olddefconfig and when verifying source and generated configurations.
The Ubuntu initramfs uses Ubuntu userland with the NVX kernel. It is not an Ubuntu-kernel or systemd VM. Its distribution-neutral package manifest records the Ubuntu Base and supplemental binary/source identities, license metadata, rootfs SHA-256, and NVX helper provenance.
The native kernel build caches the verified and patched source under
.cache/linux, uses O=build/linux, runs olddefconfig, exports the exact
generated config as build/vmlinux.config, and fails if ACPI is enabled,
PVH remains enabled, or the MP-table, APIC, IOAPIC, and command-line
virtio-mmio requirements are missing. Changing an archive hash or patch
invalidates both source and object caches; changing the input configuration
invalidates the object cache.
Release packaging stages and verifies a complete output before replacing an
existing dist/ version. Its SOURCE-MANIFEST.json records the package
version and exact hashes for OpenVMM, Linux, the generated kernel config, and
the unchanged Alpine initramfs. The OpenVMM section advertises microVM ABI 2,
control-session protocol 1, and contract
nvx-microvm-v2-control-v1; product guest-agent metadata is intentionally not
part of this platform manifest.
A binary release directory has this layout:
bin/openvmm[.exe]
guest/vmlinux
guest/vmlinux.config
guest/initramfs.cpio.gz
guest/initramfs.cpio.gz.packages.json
provenance/openvmm.provenance.json
provenance/initramfs.provenance.json
provenance/vmlinux.provenance.json
licenses/LICENSE-OPENVMM
licenses/COPYING-LINUX
LICENSE
README.md
SOURCE-MANIFEST.json
THIRD_PARTY_NOTICES.md
SHA256SUMS
Packages built with --include-source additionally contain source/.
SHA256SUMS has sorted SHA256 relative/path entries using POSIX separators
for every packaged file, including SOURCE-MANIFEST.json, except
SHA256SUMS itself.
The Linux corresponding-source archive contains the patched
linux-6.18.38/ tree and the exact vmlinux.config used for the distributed
kernel.
On a Linux host with the kernel build dependencies installed, run from the archive root:
mkdir build
cp vmlinux.config build/.config
make -C linux-6.18.38 O="$PWD/build" olddefconfig
make -C linux-6.18.38 O="$PWD/build" -j"$(nproc)" vmlinuxThe normal repository workflow performs the same build through
scripts/nvx.py build-kernel or the Docker artifact target.