Libraries
vix.app can build simple C++ libraries.
Supported library target types:
type = statictype = sharedtype = libraryFor most projects, prefer explicit types:
static -> static library
shared -> shared libraryStatic library
A static library is linked into another executable or library at build time.
Use:
type = staticExample:
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
src/mul.cpp,
]
include_dirs = [
include,
]Static library layout
Recommended layout:
mathlib/
vix.app
include/
mathlib/
math.hpp
src/
add.cpp
mul.cppinclude/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 buildShared library
A shared library is loaded or linked dynamically at runtime.
Use:
type = sharedExample:
name = plugin
type = shared
standard = c++20
sources = [
src/plugin.cpp,
]
include_dirs = [
include,
]Shared library layout
Recommended layout:
plugin/
vix.app
include/
plugin/
plugin.hpp
src/
plugin.cppinclude/plugin/plugin.hpp:
#pragma once
namespace plugin
{
const char *name();
}src/plugin.cpp:
#include <plugin/plugin.hpp>
namespace plugin
{
const char *name()
{
return "plugin";
}
}Build:
vix buildGeneric library
library is also supported:
name = core
type = library
standard = c++20
sources = [
src/core.cpp,
]
include_dirs = [
include,
]Use library when you want Vix to use its default library behavior.
For clearer manifests, prefer:
type = staticor:
type = sharedHeader-only libraries
A header-only library usually does not need sources.
However, vix.app expects source files for a build target.
For a pure header-only library, the simplest V1 approach is usually:
- use it through include_dirs from another app
- or use a normal CMakeLists.txt for package-style library behaviorExample app using a header-only library:
myapp/
vix.app
third_party/
tiny/
include/
tiny/
tiny.hpp
src/
main.cppvix.app:
name = myapp
type = executable
standard = c++20
sources = [
src/main.cpp,
]
include_dirs = [
third_party/tiny/include,
]No links field is needed if the dependency is truly header-only.
Library with public headers
For reusable libraries, keep public headers under include/.
Recommended:
mathlib/
include/
mathlib/
math.hpp
src/
add.cppThen users include:
#include <mathlib/math.hpp>Avoid putting public headers directly in src/.
src/ should mainly contain implementation files and private headers.
Library with private headers
You can use private headers under src/.
Example layout:
mathlib/
vix.app
include/
mathlib/
math.hpp
src/
add.cpp
detail/
helpers.hppvix.app:
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
]
include_dirs = [
include,
src,
]Then src/add.cpp can include:
#include <detail/helpers.hpp>Public users should still include only:
#include <mathlib/math.hpp>Library with compile definitions
You can add compile definitions to a library target.
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
]
include_dirs = [
include,
]
defines = [
MATHLIB_ENABLE_FAST_PATH=1,
]C++ usage:
#ifdef MATHLIB_ENABLE_FAST_PATH
// optimized implementation
#endifLibrary with compile options
You can add compiler options:
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
src/mul.cpp,
]
include_dirs = [
include,
]
compile_options = [
-Wall,
-Wextra,
]Library with packages
Libraries can use packages and links.
Example with Threads:
name = workerlib
type = static
standard = c++20
sources = [
src/worker.cpp,
]
include_dirs = [
include,
]
packages = [
Threads:REQUIRED,
]
links = [
Threads::Threads,
]Remember:
packages finds packages.
links links targets or libraries.Library with output_dir
Use output_dir to place the library under a predictable build folder.
name = mathlib
type = static
standard = c++20
output_dir = lib
sources = [
src/add.cpp,
src/mul.cpp,
]
include_dirs = [
include,
]After build, the library can be placed under:
build-ninja/lib/The exact file name depends on the platform and toolchain.
Examples:
libmathlib.a
libmathlib.so
mathlib.lib
mathlib.dllTesting a library
For vix.app V1, use a separate test executable.
Recommended layout:
mathlib/
vix.app
include/
mathlib/
math.hpp
src/
add.cpp
mul.cpp
tests/
vix.app
test_math.cppRoot vix.app:
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
src/mul.cpp,
]
include_dirs = [
include,
]tests/vix.app:
name = mathlib_tests
type = executable
standard = c++20
sources = [
test_math.cpp,
../src/add.cpp,
../src/mul.cpp,
]
include_dirs = [
../include,
]Run tests:
cd tests
vix runWhy tests include library sources again
In vix.app V1, one manifest describes one target.
So the test executable can include the library implementation files directly:
sources = [
test_math.cpp,
../src/add.cpp,
../src/mul.cpp,
]This avoids introducing a complex multi-target syntax too early.
For advanced library and test setups, use CMakeLists.txt.
Example library test
tests/test_math.cpp:
#include <vix.hpp>
#include <mathlib/math.hpp>
int main()
{
if (mathlib::add(2, 3) != 5)
{
vix::print("add failed");
return 1;
}
if (mathlib::mul(4, 5) != 20)
{
vix::print("mul failed");
return 1;
}
vix::print("all tests passed");
return 0;
}Using a local library from an app
For simple V1 projects, the easiest approach is to include the library source files directly in the app target.
Example layout:
workspace/
app/
vix.app
src/
main.cpp
libs/
mathlib/
include/
mathlib/
math.hpp
src/
add.cppapp/vix.app:
name = calculator
type = executable
standard = c++20
sources = [
src/main.cpp,
../libs/mathlib/src/add.cpp,
]
include_dirs = [
../libs/mathlib/include,
]This is simple and works well for small projects.
For larger projects with several libraries, use a normal CMakeLists.txt.
Shared library notes
Shared libraries are more platform-sensitive than static libraries.
Depending on the operating system, the output may be:
libplugin.so
libplugin.dylib
plugin.dllRuntime loading and library search paths can also differ between platforms.
For simple shared libraries, vix.app is enough.
For advanced shared library packaging, use CMakeLists.txt.
Library naming
The name field defines the target name.
Example:
name = mathlib
type = staticThe target is named:
mathlibThe output file may include platform-specific prefixes or suffixes.
Examples:
libmathlib.a
libmathlib.so
mathlib.libLibrary and vix run
vix run is mainly for executables.
For a library target:
name = mathlib
type = staticuse:
vix buildTo run something, create a test executable or example executable.
Example:
mathlib/
examples/
basic/
vix.app
src/
main.cppexamples/basic/vix.app:
name = mathlib_example
type = executable
standard = c++20
sources = [
src/main.cpp,
../../src/add.cpp,
../../src/mul.cpp,
]
include_dirs = [
../../include,
]Run:
cd examples/basic
vix runExamples for a library
Recommended layout:
mathlib/
vix.app
include/
mathlib/
math.hpp
src/
add.cpp
mul.cpp
examples/
basic/
vix.app
src/
main.cpp
tests/
vix.app
test_math.cppThis keeps each executable target separate:
root/vix.app -> library
examples/basic/vix.app -> example executable
tests/vix.app -> test executableExample executable for a library
examples/basic/vix.app:
name = mathlib_example
type = executable
standard = c++20
sources = [
src/main.cpp,
../../src/add.cpp,
../../src/mul.cpp,
]
include_dirs = [
../../include,
]examples/basic/src/main.cpp:
#include <vix.hpp>
#include <mathlib/math.hpp>
int main()
{
vix::print("2 + 3 =", mathlib::add(2, 3));
vix::print("4 * 5 =", mathlib::mul(4, 5));
return 0;
}Run:
cd examples/basic
vix runWhen to use CMakeLists.txt for libraries
Use CMakeLists.txt when your library needs:
- multiple targets in one project
- separate public/private dependencies
- install rules
- package export files
- CMake config generation
- FetchContent
- CTest integration
- complex examples
- complex dependency graphsvix.app is best for simple libraries and small local workflows.
Common mistakes
Using executable for library code
Incorrect:
name = mathlib
type = executable
sources = [
src/add.cpp,
]If there is no main(), linking will fail.
Correct:
name = mathlib
type = static
sources = [
src/add.cpp,
]Trying to run a library directly
This builds a library:
name = mathlib
type = staticUse:
vix buildnot:
vix rununless you have a test or example executable.
Forgetting include_dirs
If your source uses:
#include <mathlib/math.hpp>and the file is here:
include/mathlib/math.hppyou need:
include_dirs = [
include,
]Including main.cpp in a library
A library target should usually not include main.cpp.
Keep main.cpp for executable targets.
Recommended patterns
Small static library
name = mathlib
type = static
standard = c++20
sources = [
src/add.cpp,
]
include_dirs = [
include,
]Small shared library
name = plugin
type = shared
standard = c++20
sources = [
src/plugin.cpp,
]
include_dirs = [
include,
]Library with tests
mathlib/
vix.app
include/
src/
tests/
vix.app
test_math.cppLibrary with examples
mathlib/
vix.app
include/
src/
examples/
basic/
vix.app
src/
main.cppSummary
Use:
type = staticfor static libraries.
Use:
type = sharedfor shared libraries.
Use:
vix buildto build library targets.
Use separate vix.app files for tests and examples:
tests/vix.app
examples/basic/vix.appFor complex multi-target library projects, use CMakeLists.txt.
Next steps
Continue with: