Migrating from CMake to vix.app
This guide shows how to migrate a simple CMakeLists.txt project to vix.app.
vix.app is not a replacement for every CMake project.
It is a simpler entry point for projects that do not need custom CMake logic.
When migration makes sense
Migrating to vix.app makes sense when your CMake project is simple.
Good cases:
- one executable
- one static library
- one shared library
- simple source list
- simple include directories
- simple compile definitions
- simple package discovery
- simple target links
- simple resourcesFor example:
hello/
CMakeLists.txt
src/
main.cppcan usually become:
hello/
vix.app
src/
main.cppWhen to keep CMake
Keep CMakeLists.txt when your project needs advanced build logic.
Examples:
- many targets in one file
- custom commands
- generated sources
- install rules
- CTest integration
- FetchContent
- CPM.cmake
- custom toolchains
- advanced dependency discovery
- platform-specific build logic
- package export filesThe rule is simple:
Use vix.app for simple targets.
Use CMakeLists.txt for full control.Important resolution rule
Vix resolves projects in this order:
1. CMakeLists.txt
2. vix.appIf both files exist, Vix uses CMakeLists.txt.
So if you want Vix to use vix.app, remove or rename the CMakeLists.txt.
Example:
mv CMakeLists.txt CMakeLists.txt.bakThen run:
vix build
vix runMinimal executable migration
Original project:
hello/
CMakeLists.txt
src/
main.cppOriginal CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
project(hello LANGUAGES CXX)
add_executable(hello
src/main.cpp
)
target_compile_features(hello PRIVATE cxx_std_20)Equivalent vix.app:
name = hello
type = executable
standard = c++20
sources = [
src/main.cpp,
]Then remove or rename CMakeLists.txt:
mv CMakeLists.txt CMakeLists.txt.bakBuild and run:
vix build
vix runMigrating include directories
Original CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
project(myapp LANGUAGES CXX)
add_executable(myapp
src/main.cpp
src/app.cpp
)
target_include_directories(myapp PRIVATE
include
)Equivalent vix.app:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
src/app.cpp,
]
include_dirs = [
include,
]Project layout:
myapp/
vix.app
include/
myapp/
app.hpp
src/
main.cpp
app.cppMigrating compile definitions
Original CMake:
target_compile_definitions(myapp PRIVATE
MYAPP_VERSION="1.0.0"
MYAPP_ENABLE_LOGGING=1
)Equivalent vix.app:
defines = [
MYAPP_VERSION="1.0.0",
MYAPP_ENABLE_LOGGING=1,
]Complete manifest:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
src/app.cpp,
]
include_dirs = [
include,
]
defines = [
MYAPP_VERSION="1.0.0",
MYAPP_ENABLE_LOGGING=1,
]Migrating compile options
Original CMake:
target_compile_options(myapp PRIVATE
-Wall
-Wextra
-Wpedantic
)Equivalent vix.app:
compile_options = [
-Wall,
-Wextra,
-Wpedantic,
]Complete manifest:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
]
compile_options = [
-Wall,
-Wextra,
-Wpedantic,
]Migrating link options
Original CMake:
target_link_options(myapp PRIVATE
-Wl,--as-needed
)Equivalent vix.app:
link_options = [
"-Wl,--as-needed",
]Quote values that contain commas.
Migrating target links
Original CMake:
target_link_libraries(myapp PRIVATE
m
)Equivalent vix.app:
links = [
m,
]Complete manifest:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
]
links = [
m,
]Migrating find_package
Original CMake:
find_package(Threads REQUIRED)
target_link_libraries(myapp PRIVATE
Threads::Threads
)Equivalent vix.app:
packages = [
Threads:REQUIRED,
]
links = [
Threads::Threads,
]Important:
packages -> find_package(...)
links -> target_link_libraries(...)packages does not link targets automatically.
Migrating fmt
Original CMake:
find_package(fmt REQUIRED)
target_link_libraries(myapp PRIVATE
fmt::fmt
)Equivalent vix.app:
packages = [
fmt:REQUIRED,
]
links = [
fmt::fmt,
]Migrating Boost components
Original CMake:
find_package(Boost REQUIRED COMPONENTS system filesystem)
target_link_libraries(myapp PRIVATE
Boost::system
Boost::filesystem
)Equivalent vix.app:
packages = [
"Boost:COMPONENTS=system,filesystem:REQUIRED",
]
links = [
Boost::system,
Boost::filesystem,
]Quote package values that contain commas.
Migrating a static library
Original CMake:
cmake_minimum_required(VERSION 3.24)
project(mathlib LANGUAGES CXX)
add_library(mathlib STATIC
src/add.cpp
src/mul.cpp
)
target_include_directories(mathlib PUBLIC
include
)
target_compile_features(mathlib PUBLIC cxx_std_20)Equivalent vix.app:
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
src/mul.cpp,
]
include_dirs = [
include,
]Build:
vix buildMigrating a shared library
Original CMake:
cmake_minimum_required(VERSION 3.24)
project(plugin LANGUAGES CXX)
add_library(plugin SHARED
src/plugin.cpp
)
target_include_directories(plugin PUBLIC
include
)
target_compile_features(plugin PUBLIC cxx_std_20)Equivalent vix.app:
name = plugin
type = shared
standard = c++20
sources = [
src/plugin.cpp,
]
include_dirs = [
include,
]Build:
vix buildMigrating output directories
Original CMake:
set_target_properties(myapp PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)Equivalent vix.app:
output_dir = binComplete example:
name = myapp
type = executable
standard = c++20
output_dir = bin
sources = [
src/main.cpp,
]The output can be placed under:
build-ninja/bin/myappMigrating copied resources
Original CMake:
add_custom_command(TARGET myapp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets
$<TARGET_FILE_DIR:myapp>/assets
)Equivalent vix.app:
resources = [
assets,
]Complete example:
name = myapp
type = executable
standard = c++20
output_dir = bin
sources = [
src/main.cpp,
]
resources = [
assets,
]Migrating copied config files
Original CMake:
add_custom_command(TARGET myapp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/data/config.json
$<TARGET_FILE_DIR:myapp>/config/config.json
)Equivalent vix.app:
resources = [
"data/config.json=config/config.json",
]Full migration example
Original project:
server/
CMakeLists.txt
include/
server/
server.hpp
src/
main.cpp
server.cpp
public/
index.htmlOriginal CMakeLists.txt:
cmake_minimum_required(VERSION 3.24)
project(server LANGUAGES CXX)
find_package(Threads REQUIRED)
add_executable(server
src/main.cpp
src/server.cpp
)
target_compile_features(server PRIVATE cxx_std_20)
target_include_directories(server PRIVATE
include
)
target_compile_definitions(server PRIVATE
SERVER_VERSION="1.0.0"
)
target_compile_options(server PRIVATE
-Wall
-Wextra
)
target_link_libraries(server PRIVATE
Threads::Threads
)
set_target_properties(server PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
add_custom_command(TARGET server POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/public
$<TARGET_FILE_DIR:server>/public
)Equivalent vix.app:
name = server
type = executable
standard = c++20
output_dir = bin
sources = [
src/main.cpp,
src/server.cpp,
]
include_dirs = [
include,
]
defines = [
SERVER_VERSION="1.0.0",
]
compile_options = [
-Wall,
-Wextra,
]
packages = [
Threads:REQUIRED,
]
links = [
Threads::Threads,
]
resources = [
public,
]Then rename the old CMake file:
mv CMakeLists.txt CMakeLists.txt.bakBuild and run:
vix build
vix runCMake to vix.app mapping
| CMake | vix.app |
|---|---|
project(myapp) | name = myapp |
add_executable(myapp ...) | type = executable |
add_library(name STATIC ...) | type = static |
add_library(name SHARED ...) | type = shared |
| source list | sources = [...] |
target_include_directories | include_dirs = [...] |
target_compile_definitions | defines = [...] |
target_compile_options | compile_options = [...] |
target_link_options | link_options = [...] |
target_compile_features | compile_features = [...] |
find_package(...) | packages = [...] |
target_link_libraries(...) | links = [...] |
| post-build copy | resources = [...] |
| target output directory | output_dir = ... |
Things that do not map directly
Some CMake features do not have a direct vix.app equivalent.
Examples:
- custom commands
- generated sources
- install rules
- package export files
- FetchContent
- CTest
- toolchain-specific branches
- many targets in one file
- generator expressions
- custom functions and macrosIf your project depends on these, keep CMakeLists.txt.
Step-by-step migration checklist
- Identify the main target.
add_executable(...)
add_library(...)- Copy the target name to
name.
name = myapp- Convert the target type.
type = executableor:
type = staticor:
type = shared- Convert source files.
sources = [
src/main.cpp,
]- Convert include directories.
include_dirs = [
include,
]- Convert definitions.
defines = [
MYAPP_VERSION="1.0.0",
]- Convert compile options.
compile_options = [
-Wall,
-Wextra,
]- Convert packages.
packages = [
Threads:REQUIRED,
]- Convert linked libraries.
links = [
Threads::Threads,
]- Convert resources if needed.
resources = [
assets,
]- Rename
CMakeLists.txt.
mv CMakeLists.txt CMakeLists.txt.bak- Build.
vix build- Run.
vix runVerify the generated CMake
For vix.app projects, Vix generates an internal CMake project under:
.vix/generated/app/CMakeLists.txtYou can inspect it when debugging.
Do not edit it manually.
If you need to change the build, edit:
vix.appDebugging migration issues
Use verbose output:
vix build -vUse raw CMake configure output:
vix build --cmake-verbosePass extra CMake options:
vix build -- -DCMAKE_PREFIX_PATH=/path/to/prefixCommon migration mistakes
Keeping CMakeLists.txt
If both files exist:
CMakeLists.txt
vix.appVix uses CMakeLists.txt.
To test vix.app, rename the CMake file:
mv CMakeLists.txt CMakeLists.txt.bakForgetting links
This is not enough:
packages = [
fmt:REQUIRED,
]You also need:
links = [
fmt::fmt,
]Missing include directories
If your source includes:
#include <myapp/app.hpp>and the file is under:
include/myapp/app.hppyou need:
include_dirs = [
include,
]Including generated sources
If your CMake project generates source files during the build, vix.app may not be the right fit.
Use CMake for generated-source workflows.
Migrating too much too early
Do not try to migrate a large complex CMake project all at once.
Start with small apps, examples, demos, or libraries.
Recommended migration targets
Good first migration targets:
- examples
- demos
- simple CLI tools
- small libraries
- test apps
- prototype projectsRisky migration targets:
- monorepos
- SDKs with install rules
- projects using FetchContent heavily
- projects with many generated files
- projects with many platform-specific branchesSummary
vix.app can replace simple CMake files.
It maps common CMake patterns to a small manifest:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
]
include_dirs = [
include,
]But it should not replace complex CMake projects.
Use this rule:
Start simple with vix.app.
Keep CMake when you need full control.Next steps
Continue with: