Build Workflow
A build is not only compilation.
A build is the process that turns a Vix application into something executable, testable, packageable, and deployable.
The simple command is:
vix buildBut the workflow behind it is bigger:
resolve project
-> configure
-> compile
-> link
-> cache when safe
-> report resultThe build workflow must be fast.
But it must be correct first.
The rule
The main rule is:
correct first
fast secondA build tool must never say that a target is up to date when it cannot prove it.
Speed is useful only when trust is preserved.
So the Vix build model is:
reuse only when safe
rebuild when needed
fallback when uncertainThat rule matters everywhere.
What vix build means
When you run:
vix buildyou are asking Vix to:
find the current project
resolve its build input
configure it if needed
build the correct target
reuse valid cache when possible
print useful diagnosticsThe command should work for:
CMake projects
vix.app projects
apps created from templates
projects with registry dependencies
projects using Vix modulesThe user should not need to remember low-level build details for normal workflows.
Project resolution
Before building, Vix resolves the project.
Resolution order:
1. CMakeLists.txt
2. vix.appIf CMakeLists.txt exists, Vix uses the CMake project.
If there is no CMakeLists.txt and vix.app exists, Vix uses the application manifest.
That means the build workflow supports both:
advanced CMake projects
simple vix.app applicationsBuilding a vix.app
For applications, vix.app is the simple path.
Example:
name = "api"
type = "executable"
cpp_standard = "23"
sources = [
"src/main.cpp",
"src/app/AppFactory.cpp",
"src/routes/HealthRoutes.cpp"
]
include_dirs = [
"src"
]
modules = [
"core",
"json",
"http"
]When Vix builds this, the workflow is:
read vix.app
-> validate manifest
-> generate internal CMakeLists.txt
-> configure generated project
-> build targetThe generated project is written under:
.vix/generated/app/The user works with vix.app.
Vix uses generated CMake internally.
This gives a simple application model without losing the power of CMake.
Building a CMake project
If the project already has CMakeLists.txt, Vix keeps that path.
The workflow is:
read CMakeLists.txt
-> use preset or default config
-> configure
-> buildThis is the right path for projects that need:
custom CMake logic
multiple targets
platform-specific rules
external native libraries
advanced linking
install rulesVix does not remove CMake.
It gives CMake projects a better workflow.
Build presets
A build can use presets.
Examples:
vix build --preset dev
vix build --preset releaseA development preset should favor fast iteration.
A release preset should favor final output.
The mental model:
dev = fast local feedback
release = production-ready buildA project can also use CMakePresets.json when advanced CMake configuration is needed.
Default build
The default build should be enough for normal development:
vix buildA developer should not need to pass many flags for the common case.
The command should detect the project, prepare the build directory, and build the app.
For many projects, the expected flow is:
vix install
vix build
vix runBuild directories
Build output should not pollute source code.
Common directories:
build/
build-ninja/
build-release/
.vix/The exact folder can depend on the selected workflow or preset.
Generated Vix state belongs in:
.vix/Package output belongs in:
dist/The source tree should stay readable.
Dependencies before build
If the project uses registry dependencies, install them before building.
vix install
vix buildAfter cloning a project:
git clone https://github.com/example/api.git
cd api
vix install
vix buildvix install reads vix.lock.
It installs exact versions.
It does not update dependencies.
That distinction matters:
vix install = reproduce locked state
vix update = change locked stateModules before build
A vix.app can declare modules:
modules = [
"core",
"json",
"http",
"db"
]These modules affect the build.
If the app says it needs db, the build must include database support.
If the app says it needs http, the HTTP module must be available and linked.
The build should not guess hidden modules.
The app should declare what it needs.
Source files
The build must know what files belong to the target.
In vix.app, that means:
sources = [
"src/main.cpp",
"src/app/AppFactory.cpp",
"src/routes/HealthRoutes.cpp"
]In CMake, that means the source list is defined by CMakeLists.txt.
The rule:
vix.app declares app sources directly
CMakeLists.txt controls advanced source rulesBoth paths must produce a clear target.
Include directories
A simple app can declare include directories:
include_dirs = [
"src",
"include"
]This lets code use clean includes:
#include "app/AppFactory.hpp"
#include "routes/HealthRoutes.hpp"The include model should stay explicit.
Do not depend on accidental include paths.
Build target
A Vix app should have a clear target name.
In vix.app:
name = "api"That name becomes the application target.
When building:
vix buildVix should know which target to build.
In CMake projects, target resolution can come from the CMake project or user options.
The target must not be ambiguous in normal app workflows.
Configure step
Some builds need configuration before compilation.
Configuration is needed when:
build directory does not exist
CMakeLists.txt changed
CMakePresets.json changed
vix.app changed
vix.json changed
vix.lock changed
*.cmake changed
toolchain changed
build preset changedA configure step prepares the build system.
A compile step builds code.
Do not confuse them.
configure = prepare build graph
compile = build source filesReconfigure vs rebuild
Not every change needs the same response.
A source change usually needs rebuild only.
src/main.cpp -> rebuildA header change usually needs rebuild only.
include/App.hpp -> rebuildA config change usually needs reconfigure and rebuild.
CMakeLists.txt -> reconfigure and rebuild
vix.app -> reconfigure and rebuild
vix.lock -> reconfigure and rebuildThis is also the model used by development mode.
Change classification
For development builds, Vix classifies changes.
Ignored paths:
.git
.vix
build
build-dev
build-ninja
build-release
node_modules
.cache
.idea
.vscodeSource files:
.cpp
.cc
.cxx
.cHeader files:
.hpp
.hh
.hxx
.h
.ippConfig files:
CMakeLists.txt
CMakePresets.json
vix.json
vix.toml
vix.lock
*.cmakeThe result is one of:
ignore
rebuild-only
reconfigure-and-rebuildThat is the practical build model.
Object cache
Object cache exists to avoid recompiling work that is already valid.
The idea:
same source
same flags
same compiler
same relevant inputs
-> reuse objectIf any important input changes, the object must not be reused.
Important inputs can include:
source file content
included headers
compiler path
compiler version
compile flags
defines
include paths
target platform
build modeObject cache is useful only when correctness is protected.
Artifact cache
Artifact cache is bigger than object cache.
It can reuse build outputs when the complete input state is still valid.
The idea:
same target input state
-> same artifact
-> reuse safelyArtifacts can include:
executables
libraries
generated outputs
packaged build outputsBut again, the rule is strict:
reuse only when the input identity is provenA wrong cache hit is worse than a slow build.
Build graph
A build graph describes what depends on what.
Example:
main.cpp
-> AppFactory.hpp
-> Config.hpp
-> HealthRoutes.hppAt target level:
api
-> object files
-> linked libraries
-> generated filesA build graph helps Vix answer:
What changed?
What depends on it?
What must rebuild?
What can be reused?This is the base of fast target builds.
Target-aware builds
A target-aware build does not rebuild everything blindly.
It asks:
Which target was requested?
Which files affect that target?
Which tasks are dirty?If only one target is requested, Vix should focus on that target.
This matters in large projects.
A backend with many modules should not rebuild unrelated work when the target does not need it.
The rule:
build what the requested target needs
do not rebuild unrelated workNinja integration
Vix can use Ninja through CMake.
The model:
Vix resolves the project
CMake generates the build graph
Ninja executes build tasks
Vix improves the workflow around itVix does not need to replace Ninja.
Ninja is already good at fast builds.
Vix adds application awareness, dependency workflows, diagnostics, and higher-level commands.
CMake fallback
Fallback is important.
If Vix cannot safely use a direct path, it should use the safer build path.
For scripts:
vix run server.cppVix can compile directly when enough.
But when the file needs modules, dependencies, sanitizers, or project-level config, CMake fallback is safer.
The same rule applies to build workflows:
direct when safe
fallback when neededClean builds
Sometimes you need to remove local generated state.
Use:
vix cleanThis removes project-local cache directories such as:
.vix/
build/It does not remove global Vix state under:
~/.vix/Use clean when the local project state is wrong or stale.
Reset builds
A reset is stronger than clean.
vix resetIt runs:
vix clean
vix installUse reset when dependency state or generated project state is broken.
Typical workflow:
vix reset
vix buildBuild after dependency changes
When dependencies change, rebuild the project.
Examples:
vix add softadastra/json
vix buildvix update --install
vix buildvix remove softadastra/json
vix install
vix buildDependency changes can affect include paths, link targets, modules, and generated integration files.
So the build must treat dependency state as an input.
Build and tests
A build only proves that the code compiles.
It does not prove behavior.
Use:
vix check --testsor:
vix testsA serious workflow should be:
vix build
vix check --testsFor release:
vix build --preset release
vix check --testsBuild and formatting
Formatting is not part of compilation.
But it belongs in the development workflow.
Use:
vix fmtCheck formatting before commit:
vix fmt --checkA clean validation flow:
vix fmt --check
vix build
vix check --testsBuild and packaging
Packaging should happen after a successful build.
vix build --preset release
vix check --tests
vix pack
vix verifyvix pack creates a distributable package.
vix verify checks package integrity.
Do not package broken builds.
Build and production
Production builds should be explicit.
Use:
vix build --preset releaseThen validate:
vix check --testsThen deploy:
vix deployA production deployment can also run its own configured build command.
Example production config can point to:
vix build --preset releaseThe deployment workflow should not rely on an accidental debug build.
Debug builds vs release builds
Development builds favor speed and diagnostics.
Release builds favor optimized output.
Simple model:
| Build | Purpose |
|---|---|
| dev | fast local work |
| debug | debugging and symbols |
| release | optimized production output |
Use the right build for the right stage.
Do not benchmark debug builds.
Do not deploy accidental local builds.
Sanitizer builds
Some builds need sanitizers.
Examples:
address sanitizer
undefined behavior sanitizer
thread sanitizer
leak sanitizerSanitizers are useful for finding bugs.
They can affect flags, linking, and runtime behavior.
That is why scripts or projects using sanitizer modes may need a safer CMake-backed path.
The principle:
sanitizer builds must be explicit and reproducibleBuild diagnostics
Good build diagnostics should show:
project kind
build directory
preset
target
compiler
generator
cache status
configured or reused
number of sources
errors with useful contextA failed build should not leave the developer guessing.
Bad output:
build failedBetter output:
error: build failed
target: api
preset: dev
step: compile
file: src/routes/HealthRoutes.cpp
fix: run vix build -v for detailsA build tool should help you continue.
Verbose build
Verbose mode is useful when normal output is not enough.
Example:
vix build -vVerbose output can show:
resolved project kind
source count
header count
compile tasks
imported compile commands
Ninja tasks
cache hits
cache misses
linker
launcher
jobsUse verbose mode for debugging, not every normal build.
Build failure categories
Most build failures fall into a few categories:
project resolution failed
configuration failed
dependency missing
compile error
link error
generated file missing
toolchain missing
cache invalid
runtime target missingThe fix depends on the category.
Examples:
vix doctor
vix info
vix install
vix reset
vix build -vUse vix doctor for environment issues.
Use vix info for local Vix state.
Use vix reset when project-local state is broken.
Build and vix dev
vix dev uses the build workflow repeatedly.
It watches changes, classifies them, then rebuilds or reconfigures.
The model:
file changed
-> classify
-> rebuild-only or reconfigure-and-rebuild
-> restart appThat means vix dev depends on a correct build model.
If build invalidation is wrong, dev mode becomes unreliable.
Build and vix run
vix run can trigger a build before execution.
For a project:
vix runThe workflow can be:
resolve project
-> build target if needed
-> run targetFor a single file:
vix run main.cppThe workflow can be direct compile or fallback.
The build system supports runtime.
Runtime depends on build correctness.
Build and vix.app
The vix.app build path should be invisible enough to be simple, but visible enough to debug.
The user should know:
vix.app was detected
internal CMake project was generated
target name was resolved
build directory was usedThe generated CMake file is an implementation detail.
But when build fails, Vix should show where it generated the project.
That helps debugging.
Common workflows
Install and build:
vix install
vix buildBuild release:
vix build --preset releaseClean and rebuild:
vix clean
vix buildReset and rebuild:
vix reset
vix buildBuild then test:
vix build
vix check --testsRelease validation:
vix fmt --check
vix build --preset release
vix check --tests
vix pack
vix verifyCommon mistakes
Building before installing dependencies
Wrong after clone:
vix buildCorrect:
vix install
vix buildUsing update when install is needed
Wrong after clone:
vix updateCorrect:
vix installDeploying without release build
Wrong:
vix deployBetter:
vix build --preset release
vix check --tests
vix deployTrusting cache blindly
If something looks wrong:
vix clean
vix buildIf dependency state is also suspicious:
vix reset
vix buildEditing build config during dev and expecting rebuild only
Config changes require reconfigure.
Examples:
vix.app
CMakeLists.txt
CMakePresets.json
vix.lockThese are not normal source changes.
Build checklist
A good Vix build should answer:
Which project was resolved?
Was it CMake or vix.app?
Which target was built?
Which preset was used?
Were dependencies installed?
Was configuration needed?
Was cache used?
What compiler was used?
Where is the output?
What failed if it failed?If a build cannot answer these questions, the output is not good enough.
What you should remember
Build workflow is not only compilation.
It is:
resolve
-> configure
-> compile
-> link
-> cache safely
-> report clearlyFor apps:
vix.app gives the simple build model
CMakeLists.txt gives the advanced build modelFor correctness:
reuse only when safe
fallback when uncertainFor daily work:
vix buildFor release:
vix build --preset release
vix check --testsFor broken local state:
vix reset
vix buildThe core build model:
correct first
fast second
clear always