vix.app Build Planning
vix.app changes an important part of vix build.
Before vix.app, a project was usually a CMake project.
That meant one directory often represented everything:
project directory
CMake source directory
build identity
default target nameFor many CMake projects, this works because the project root contains:
CMakeLists.txtand the build system can configure directly from that directory.
With vix.app, the model changes.
The user project directory and the CMake source directory are no longer always the same thing.
The key distinction
For a normal CMake project:
userProjectDir = cmakeSourceDirFor a vix.app project:
userProjectDir = project root
cmakeSourceDir = project/.vix/generated/appThis distinction is the foundation of correct build planning.
If Vix confuses these two paths, the build may still work in small cases, but other systems can break:
target detection
build directories
snapshots
artifact cache
watch mode
export paths
diagnostics
vix run executable lookupSo vix.app requires a more explicit build plan.
What build planning means
Build planning is the phase where Vix decides:
which project is being built
which preset is active
where the build directory is
which source directory CMake should configure
which target should be built
which logs should be written
whether reconfigure is needed
which cache state applies
which executable should be resolved after buildIt is the bridge between project resolution and build execution.
Project resolution answers:
What kind of project is this?Build planning answers:
How should this project be built?The old simple assumption
The old assumption was:
plan.projectDir is the projectThat works when:
plan.projectDir/CMakeLists.txtexists.
Then Vix can configure with:
cmake -S plan.projectDir -B plan.buildDirThe default target can be guessed from:
plan.projectDir.filename()The executable can be searched by that name.
For a normal CMake project, this is acceptable.
Why that breaks with vix.app
For a vix.app project, the real project root contains:
vix.app
src/
include/
assets/But it does not contain:
CMakeLists.txtVix generates that file under:
.vix/generated/app/CMakeLists.txtSo if the build plan stores only one projectDir, there are two bad choices.
Bad choice 1: projectDir is the user project
If:
plan.projectDir = myapp/then CMake configure would try:
cmake -S myapp -B myapp/build-ninjaBut myapp/ has no CMakeLists.txt.
The configure step fails.
Bad choice 2: projectDir is the generated CMake directory
If:
plan.projectDir = myapp/.vix/generated/app/then CMake configure works:
cmake -S myapp/.vix/generated/app -B myapp/build-ninjaBut now other parts of the build may think the generated directory is the real project.
That can cause problems.
The default target may become:
appinstead of the manifest name.
Exports may go to:
.vix/generated/app/instead of the user project root.
Snapshots may inspect the wrong directory.
Watch mode may watch generated files instead of source files.
The fix is to stop using one path for two meanings.
The correct build plan
A correct build plan separates the identities:
userProjectDir
cmakeSourceDir
defaultTargetName
generatedFromVixAppFor a CMake project:
userProjectDir = myapp/
cmakeSourceDir = myapp/
defaultTargetName = myapp
generatedFromVixApp = falseFor a vix.app project:
userProjectDir = myapp/
cmakeSourceDir = myapp/.vix/generated/app/
defaultTargetName = manifest.name
generatedFromVixApp = trueThis is the clean model.
Every build operation can now use the correct value.
userProjectDir
userProjectDir is the real project root.
It should be used for user-facing project operations.
Examples:
build directory placement
local metadata
.env lookup
watch mode
project snapshots
artifact cache state
exported binaries
resource source paths
user diagnosticsFor vix.app, this remains:
myapp/even though CMake configures from:
myapp/.vix/generated/app/cmakeSourceDir
cmakeSourceDir is the directory passed to:
cmake -SFor a CMake project:
cmakeSourceDir = myapp/For a vix.app project:
cmakeSourceDir = myapp/.vix/generated/app/Only the configure step should need this path directly.
Conceptually:
configure:
use cmakeSourceDir
build state:
use userProjectDirdefaultTargetName
defaultTargetName is the target Vix builds when the user does not pass an explicit target.
For CMake projects, it can usually be:
project folder nameFor vix.app, it must be:
manifest.nameExample:
folder: hello-project/
manifest name: helloThe target should be:
hellonot:
hello-projectand not:
appThis matters for:
cmake --build --target
vix run executable lookup
artifact names
diagnostic messagesgeneratedFromVixApp
generatedFromVixApp tells the build system that the active CMake source was generated.
This helps with diagnostics.
For example, Vix can print:
Using project directory:
myapp/
Using generated CMake source:
myapp/.vix/generated/app/It also helps commands avoid treating generated paths as user-authored paths.
Build directory placement
Build directories should stay under the user project directory.
For example:
myapp/build-ninja/
myapp/build-dev/
myapp/build-release/They should not be placed under:
myapp/.vix/generated/app/build-ninja/The generated CMake directory is not the project root.
It is internal metadata.
Configure planning
The configure command should use:
cmakeSourceDirConceptually:
cmake -S <cmakeSourceDir> -B <buildDir>For CMake:
cmake -S myapp -B myapp/build-ninjaFor vix.app:
cmake -S myapp/.vix/generated/app -B myapp/build-ninjaThis is the only place where the generated CMake source directory must be treated as the source directory.
Build planning
The build command should use:
buildDir
defaultTargetNameConceptually:
cmake --build <buildDir> --target <defaultTargetName>For vix.app:
cmake --build myapp/build-ninja --target helloif the manifest says:
name = helloThe build target should not be derived from:
.vix/generated/appbecause that directory name is not the application target.
Reconfigure planning
A build system needs to decide when CMake configure must run again.
For vix.app, the configure signature should include the generated CMake input and the manifest state.
Important inputs include:
vix.app content
generated CMake content
CMake variables
preset
toolchain
compiler launcher
linker settings
target triple
package configurationIf the manifest changes, Vix should regenerate the internal CMake project and reconfigure when necessary.
Project fingerprint
A project fingerprint helps decide whether a build can be reused.
For CMake projects, the fingerprint can include CMake configuration files.
For vix.app, the fingerprint should include:
vix.app
generated CMakeLists.txt
important build optionsBut this should not make Vix forget the real project root.
The fingerprint may inspect the CMake source directory, but cache state and build outputs still belong to the user project directory.
Snapshots
Snapshots should describe user project inputs.
For vix.app, this should start from:
userProjectDirnot:
cmakeSourceDirThe generated CMake directory is derived output.
The source of truth is the manifest and project files.
A snapshot should care about:
vix.app
src/
include/
resources
lock files
dependency metadatanot only generated CMake.
Artifact cache planning
Artifact cache identity should use stable project identity.
For a vix.app project, the target identity should come from:
defaultTargetNamenot:
cmakeSourceDir.filename()If cmakeSourceDir is:
.vix/generated/appthen the filename is:
appThat is not a useful artifact name.
The manifest target name is the correct identity.
Object cache planning
The object cache should be based on the actual compile inputs:
source file content
header dependencies
compiler identity
compiler flags
include directories
defines
target triple
build typevix.app can help here because it gives Vix direct structured data.
In the current generated CMake path, Vix can still import compile commands.
In a future native path, Vix can create compile tasks directly from the manifest.
Graph planning
A build graph represents tasks and dependencies.
For a generated CMake project, Vix can import:
compile_commands.json
build.ninja
dependency filesFor a future native vix.app build, Vix can generate the graph directly from:
sources
include_dirs
defines
compile_options
link_options
links
resourcesThat is why the manifest is important.
It is not only a configuration shortcut.
It can become build graph input.
vix.app as a future native build path
The current path is:
vix.app
-> generated CMake
-> CMake configure
-> CMake buildThe future path can be:
vix.app
-> BuildGraph
-> ObjectCache
-> Scheduler
-> LinkThis is possible because vix.app is declarative and limited.
Vix does not have to interpret arbitrary CMake logic.
It can directly create build tasks.
Why native planning matters
CMake is powerful, but it has overhead:
configure step
generate step
build system files
cache state
indirection through generated rulesFor many projects, this is acceptable.
But for simple vix.app projects, Vix can eventually avoid some of that overhead.
The goal is not to compile C++ magically faster.
The goal is to avoid unnecessary work:
do not reconfigure when inputs are unchanged
do not regenerate when manifest is unchanged
do not recompile clean objects
do not relink unchanged targets
restore cached artifacts when validCompatibility path vs fast path
The clean long-term model is:
CMakeLists.txt -> compatibility path
vix.app -> fast pathThe compatibility path keeps existing projects working.
The fast path lets Vix optimize projects it understands directly.
This split is more realistic than trying to replace CMake for every C++ project.
vix build with CMake projects
For a normal CMake project, planning stays close to the existing model:
resolve project root
select preset
create build directory
configure CMake
build selected target
run cache checksCMake remains the source of truth.
Vix can still improve:
diagnostics
cache
output style
artifact reuse
target-aware buildsBut it should not try to understand arbitrary CMake better than CMake itself.
vix build with vix.app projects
For vix.app, planning has more direct knowledge.
The plan can know:
target name
target type
sources
include directories
defines
packages
links
resources
output directoryToday, that data is used to generate CMake.
Later, it can be used to generate a native build graph.
The important part is that the build plan keeps this information structured.
vix run and build planning
vix run depends on build planning too.
It needs to know:
which target to build
where the build output is
which executable to run
what project directory to useFor vix.app, vix run should use:
targetName = manifest.nameThen it searches common locations such as:
build-ninja/<target>
build-ninja/bin/<target>
build-ninja/src/<target>This is why build planning and run planning must agree on the target name.
Export planning
When Vix exports or copies a final binary, it should use:
userProjectDirnot:
cmakeSourceDirFor vix.app, exporting into:
.vix/generated/app/would be wrong.
The generated CMake folder is not the user-facing output location.
Watch planning
Watch mode should watch:
userProjectDirFor vix.app, this includes:
vix.app
src/
include/
assets/Watching only:
.vix/generated/app/would miss real source changes.
Diagnostics planning
Diagnostics should show the correct layer.
For manifest errors, point to:
vix.appFor source errors, point to:
src/main.cpp
include/...For generated CMake configure errors, point to:
.vix/generated/app/CMakeLists.txtFor user-facing project context, print:
Project directory: myapp/
Generated CMake source: myapp/.vix/generated/app/
Build directory: myapp/build-ninja/
Target: helloThis makes the build easier to debug.
A clean plan object
A practical build plan should contain at least:
userProjectDir
cmakeSourceDir
projectDir
defaultTargetName
generatedFromVixApp
preset
buildDir
configureLog
buildLog
signature
cmakeVars
launcher
fastLinkerFlag
projectFingerprintprojectDir can remain for backward compatibility.
New code should prefer the more specific fields:
userProjectDir for real project operations
cmakeSourceDir for CMake configure
defaultTargetName for target selectionBackward compatibility
The plan can evolve without breaking existing code by keeping:
projectDirbut treating it as the user project directory.
Then new fields provide clearer meaning.
This avoids large risky rewrites while fixing the vix.app path model.
Common planning mistakes
Using cmakeSourceDir as the project root
Wrong:
project root = .vix/generated/appCorrect:
project root = userProjectDir
CMake source = cmakeSourceDirGuessing target from folder name
Wrong for vix.app:
target = projectDir.filename()Correct:
target = defaultTargetNameExporting to generated directory
Wrong:
.vix/generated/app/myappCorrect:
myapp/myappor another user-facing output path.
Watching generated files only
Wrong:
watch .vix/generated/appCorrect:
watch userProjectDirPlanning checklist
For any vix.app build, verify:
1. userProjectDir points to the real project root.
2. cmakeSourceDir points to .vix/generated/app.
3. buildDir is under userProjectDir.
4. defaultTargetName equals manifest.name.
5. cmake -S uses cmakeSourceDir.
6. cmake --build uses defaultTargetName when no target is provided.
7. snapshots use userProjectDir.
8. exports use userProjectDir.
9. watch mode uses userProjectDir.
10. diagnostics distinguish generated files from user files.Why this matters
Build planning is not only about making the current generated CMake path work.
It is also preparing Vix for a native build engine.
If the plan keeps project identity clean, then Vix can later switch a vix.app project from:
generated CMake executionto:
native BuildGraph executionwithout changing the user-facing manifest.
The user still writes:
vix.appOnly the execution engine changes.
Conclusion
vix.app forced Vix to make build planning more precise.
A generated project has two important paths:
the user project directory
the generated CMake source directoryIt also has a target name that comes from the manifest, not from the folder name.
Keeping these values separate makes vix build more correct today.
It also creates the foundation for a faster native build path later.
vix.app starts as generated CMake.
vix.app can become native BuildGraph input.
The build plan is the bridge between both.