Sources and Includes
vix.app uses sources and include_dirs to describe the files that belong to your target.
These two fields are usually enough to describe the structure of a simple C++ project.
sources = [
src/main.cpp,
src/app.cpp,
]
include_dirs = [
include,
]Basic layout
A recommended project layout looks like this:
myapp/
vix.app
include/
myapp/
app.hpp
src/
main.cpp
app.cppvix.app:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
src/app.cpp,
]
include_dirs = [
include,
]sources
The sources field lists the source files that should be compiled.
sources = [
src/main.cpp,
]For multiple files:
sources = [
src/main.cpp,
src/app.cpp,
src/server.cpp,
]Inline arrays are also supported:
sources = [src/main.cpp, src/app.cpp]Source paths are relative to vix.app
All source paths are relative to the directory that contains vix.app.
Example:
myapp/
vix.app
src/
main.cppCorrect:
sources = [
src/main.cpp,
]Incorrect:
sources = [
myapp/src/main.cpp,
]because vix.app is already inside myapp/.
Source file validation
Vix checks that source files exist before generating the internal CMake project.
If a source file does not exist, Vix reports an error like:
vix.app source file not found: src/main.cppFix the path or create the missing file.
include_dirs
The include_dirs field lists directories used by #include.
include_dirs = [
include,
]Example:
myapp/
vix.app
include/
myapp/
app.hpp
src/
main.cppsrc/main.cpp:
#include <myapp/app.hpp>
int main()
{
return 0;
}vix.app:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
]
include_dirs = [
include,
]Include paths are also relative to vix.app
Example:
myapp/
vix.app
third_party/
asio/
include/
asio.hppCorrect:
include_dirs = [
third_party/asio/include,
]Then in C++:
#include <asio.hpp>Header files do not need to be listed in sources
Usually, header files are not listed under sources.
Correct:
sources = [
src/main.cpp,
src/app.cpp,
]
include_dirs = [
include,
]You do not need:
sources = [
src/main.cpp,
src/app.cpp,
include/myapp/app.hpp,
]Headers are included through include_dirs.
Example with a header
Project layout:
hello/
vix.app
include/
hello/
message.hpp
src/
main.cppinclude/hello/message.hpp:
#pragma once
#include <string>
namespace hello
{
inline std::string message()
{
return "Hello from vix.app";
}
}src/main.cpp:
#include <vix.hpp>
#include <hello/message.hpp>
int main()
{
vix::print(hello::message());
return 0;
}vix.app:
name = hello
type = executable
standard = c++20
sources = [
src/main.cpp,
]
include_dirs = [
include,
]Build and run:
vix build
vix runExample with multiple source files
Project layout:
server/
vix.app
include/
server/
server.hpp
router.hpp
src/
main.cpp
server.cpp
router.cppvix.app:
name = server
type = executable
standard = c++20
sources = [
src/main.cpp,
src/server.cpp,
src/router.cpp,
]
include_dirs = [
include,
]include/server/server.hpp:
#pragma once
namespace server
{
int run();
}src/server.cpp:
#include <vix.hpp>
#include <server/server.hpp>
namespace server
{
int run()
{
vix::print("server running");
return 0;
}
}src/main.cpp:
#include <server/server.hpp>
int main()
{
return server::run();
}Using src as an include directory
Some projects include headers from src/.
Example:
myapp/
vix.app
src/
main.cpp
internal/
config.hppsrc/main.cpp:
#include <internal/config.hpp>Then add src to include_dirs:
include_dirs = [
src,
]However, for public headers, prefer:
include/Use src/ for internal implementation headers.
Recommended include structure
For reusable code, prefer this structure:
myapp/
include/
myapp/
app.hpp
config.hpp
src/
app.cpp
main.cppThen include headers like this:
#include <myapp/app.hpp>This avoids name collisions with other libraries.
Recommended:
include/myapp/app.hppAvoid:
include/app.hppfor larger projects.
Quoted paths
Use quotes when a path contains spaces or special characters.
sources = [
"src/with space.cpp",
]include_dirs = [
"third_party/my lib/include",
]For clean projects, avoid spaces in file names when possible.
Inline arrays
For very small projects, inline arrays are fine:
sources = [src/main.cpp]
include_dirs = [include]For bigger projects, prefer multi-line arrays:
sources = [
src/main.cpp,
src/app.cpp,
src/server.cpp,
]
include_dirs = [
include,
third_party/asio/include,
]Multi-line arrays are easier to read and review in Git diffs.
Static library example
Project layout:
mathlib/
vix.app
include/
mathlib/
math.hpp
src/
add.cpp
mul.cppvix.app:
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
src/mul.cpp,
]
include_dirs = [
include,
]include/mathlib/math.hpp:
#pragma once
namespace mathlib
{
int add(int a, int b);
int mul(int a, int b);
}src/add.cpp:
#include <mathlib/math.hpp>
namespace mathlib
{
int add(int a, int b)
{
return a + b;
}
}src/mul.cpp:
#include <mathlib/math.hpp>
namespace mathlib
{
int mul(int a, int b)
{
return a * b;
}
}Build:
vix buildTest source paths
When a vix.app file is inside tests/, paths are relative to tests/.
Example:
mathlib/
include/
mathlib/
math.hpp
src/
add.cpp
tests/
vix.app
test_add.cpptests/vix.app:
name = mathlib_tests
type = executable
standard = c++20
sources = [
test_add.cpp,
../src/add.cpp,
]
include_dirs = [
../include,
]Correct:
sources = [
test_add.cpp,
../src/add.cpp,
]Incorrect:
sources = [
tests/test_add.cpp,
src/add.cpp,
]because the manifest is already inside tests/.
Example source paths
If vix.app is here:
project/vix.appthen these paths are resolved from project/:
sources = [
src/main.cpp,
src/app.cpp,
]If vix.app is here:
project/tests/vix.appthen these paths are resolved from project/tests/:
sources = [
test_app.cpp,
../src/app.cpp,
]Third-party headers
For header-only third-party libraries, add the include directory.
Example:
myapp/
third_party/
json/
include/
nlohmann/
json.hppvix.app:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
]
include_dirs = [
third_party/json/include,
]C++:
#include <nlohmann/json.hpp>No links entry is needed for a true header-only library.
Generated files
If your project uses generated source files, vix.app may not be enough.
For example:
schema.proto -> generated .cpp/.hppor:
codegen tool -> generated source filesIn that case, use one of these approaches:
- generate the files before running vix build
- commit generated files if appropriate
- use a normal CMakeLists.txt for full controlvix.app is designed for simple explicit source lists.
Common mistakes
Source path missing src/
Incorrect:
sources = [
main.cpp,
]Correct:
sources = [
src/main.cpp,
]when your file is located under src/.
Missing include_dirs
If your code says:
#include <myapp/app.hpp>and your file is here:
include/myapp/app.hppyou need:
include_dirs = [
include,
]Listing headers as sources
Usually unnecessary:
sources = [
src/main.cpp,
include/myapp/app.hpp,
]Prefer:
sources = [
src/main.cpp,
]
include_dirs = [
include,
]Wrong relative path in tests
If tests/vix.app contains:
sources = [
src/add.cpp,
]but the real file is:
../src/add.cppthe build will fail.
Correct:
sources = [
../src/add.cpp,
]Including main.cpp in tests
Avoid this in test manifests:
sources = [
test_app.cpp,
../src/main.cpp,
../src/app.cpp,
]This can create duplicate main() errors.
Prefer:
sources = [
test_app.cpp,
../src/app.cpp,
]Recommended patterns
Small app
hello/
vix.app
src/
main.cppsources = [
src/main.cpp,
]App with reusable logic
myapp/
vix.app
include/
myapp/
app.hpp
src/
main.cpp
app.cppsources = [
src/main.cpp,
src/app.cpp,
]
include_dirs = [
include,
]Library
mathlib/
vix.app
include/
mathlib/
math.hpp
src/
add.cpp
mul.cppsources = [
src/add.cpp,
src/mul.cpp,
]
include_dirs = [
include,
]Tests
mathlib/
tests/
vix.app
test_math.cppsources = [
test_math.cpp,
../src/add.cpp,
../src/mul.cpp,
]
include_dirs = [
../include,
]Summary
Use sources for files that must be compiled.
Use include_dirs for directories used by #include.
Recommended structure:
project/
vix.app
include/
project/
public.hpp
src/
main.cpp
implementation.cppRecommended manifest:
name = project
type = executable
standard = c++20
sources = [
src/main.cpp,
src/implementation.cpp,
]
include_dirs = [
include,
]Next steps
Continue with: