Vdeps is a lightweight Python script that compiles cmake dependencies for you. This is great if you just went to compile them in a separate directory without dealing with the fun task of trying to link the cmakes builds together directly. In the end you just want to build some libraries and copy them into a folder for your project to link, right?
NOTE: Vdeps is vibe coded, without too much code oversight. Intended as a throwaway tool of sorts. Use at your own risk.
vdeps.py builds dependency libraries and tools defined in vdeps.toml, copying artefacts to lib/ and tools/ directories organised by platform and build configuration.
# Build all dependencies
python vdeps.py
# Build specific dependencies by name (case-insensitive)
python vdeps.py nvrhi assimp
# Skip project regeneration if build exists (--build flag)
python vdeps.py --build
python vdeps.py nvrhi --build
# Skip rebuilding when copied outputs still exist and dependency HEAD is unchanged
python vdeps.py --auto-skip
# Combine with --build for fast incremental runs
python vdeps.py --build --auto-skip
# Generate a thin CMake wrapper at vdeps/CMakeLists.txt
python vdeps.py --generate-cmakeTip: add .vdeps-state.json to your project's .gitignore to avoid committing local auto-skip state.
Dependency selection: Build specific dependencies by name. Names are case-insensitive and must match entries in vdeps.toml. Invalid characters are rejected.
--generate-cmake reads vdeps.toml, writes vdeps/CMakeLists.txt, and exits without building anything. It is incompatible with --build, --clean, --auto-skip, positional dependency names, and --llvm. LLVM and runtime options are controlled via CMake cache variables in the generated wrapper, not CLI flags.
--auto-skip only skips for clean git repos under vdeps/; dirty repos or non-git directories fall back to normal builds.
python vdeps.py --generate-cmake creates vdeps/CMakeLists.txt for parent projects to consume with add_subdirectory(vdeps). Generated targets always run vdeps.py --build --auto-skip <dep> so parent CMake builds are fast by default; if you need a forced rebuild or unusual troubleshooting, run vdeps.py directly.
add_subdirectory(vdeps)
add_dependencies(my_app vdeps_nvrhi)You can also depend on the aggregate target if you want all configured dependencies built:
add_subdirectory(vdeps)
add_dependencies(my_app vdeps_all)The generated wrapper exposes cache toggles for MSVC runtime and compiler options:
| Option | Default | Description |
|---|---|---|
VDEPS_USE_LLVM |
OFF | Use Clang/LLVM compiler |
VDEPS_STATIC_RUNTIME |
ON* | Build with /MT (static runtime) |
VDEPS_DYNAMIC_RUNTIME |
OFF | Build with /MD (dynamic runtime) |
*When neither VDEPS_STATIC_RUNTIME nor VDEPS_DYNAMIC_RUNTIME is set, VDEPS_STATIC_RUNTIME defaults to ON.
Build both runtimes for combined packages:
set(VDEPS_STATIC_RUNTIME ON CACHE BOOL "" FORCE)
set(VDEPS_DYNAMIC_RUNTIME ON CACHE BOOL "" FORCE)
add_subdirectory(vdeps)Build with LLVM and dynamic runtime:
set(VDEPS_USE_LLVM ON CACHE BOOL "" FORCE)
set(VDEPS_DYNAMIC_RUNTIME ON CACHE BOOL "" FORCE)
add_subdirectory(vdeps)| Target | Description |
|---|---|
vdeps_all |
Top-level aggregate (depends on enabled variants) |
vdeps_all_mt |
All deps with static runtime (/MT) |
vdeps_all_md |
All deps with dynamic runtime (/MD) |
vdeps_all_llvm_mt |
All deps with LLVM + static runtime |
vdeps_all_llvm_md |
All deps with LLVM + dynamic runtime |
vdeps_<name>_mt |
Individual dep with static runtime |
vdeps_<name>_md |
Individual dep with dynamic runtime |
This wrapper is build orchestration only in v1. It does not create imported CMake targets, propagate include directories, or add link instructions automatically, so linking remains manual.
Dependencies are configured in vdeps.toml:
# Optional: centralise build artefacts
temp_dir = "builds"
[[dependency]]
name = "nvrhi"
rel_path = "nvrhi"
cxx_standard = 20
libs = ["nvrhi_vk", "rtxmu", "nvrhi"]
executables = []
cmake_options = [
"-DNVRHI_INSTALL=OFF",
"win:-DNVRHI_WITH_DX11=OFF",
"linux,mac:-DNVRHI_WITH_VULKAN=ON",
"!win:-DNOT_WINDOWS=ON",
]| Field | Description |
|---|---|
name |
Display name for logging and selective building |
rel_path |
Relative path to dependency in vdeps/ directory |
libs |
Library base names to copy (e.g. ["nvrhi"] matches libnvrhi.a or nvrhi.lib) |
executables |
Executable base names to copy to tools directory |
extra_files |
Specific filenames to copy (e.g. ["slangc.exe", "slang.dll"]) |
cmake_options |
List of CMake flags passed during configuration |
cxx_standard |
C++ standard version (default: 20) |
extra_link_dirs |
Additional linker search paths for this dependency |
build |
If false, skips CMake configure and build steps (default: true) |
install |
List of custom copy rules (see below) |
Variable Substitution: Use ${ROOT_DIR} in cmake_options to reference the absolute path of the directory containing vdeps.py.
Install Rules: Use install to copy files matching a glob pattern to a target directory (lib or tools).
install = [
{ pattern = "bin/*.dll", target = "tools" },
{ pattern = "data/**/*", target = "tools/data" }
]Platform-specific syntax: Use win:, linux:, mac: prefixes for platform-specific items in arrays. Negation with ! and multiple platforms with commas: "win,linux:-DFEATURE=ON", "!win:-DNOT_WIN=ON".
Centralised builds: Add temp_dir = "builds" at top-level to redirect build directories from {dependency}/build_{config} to {temp_dir}/{name}_{config}.
root/
├── vdeps.py
├── vdeps.toml
├── lib/
│ ├── linux_debug/
│ ├── linux_release/
│ ├── win_debug/
│ ├── win_release/
│ ├── win_llvm_debug/
│ ├── win_llvm_release/
│ ├── win_md_debug/
│ ├── win_md_release/
│ ├── win_llvm_md_debug/
│ └── win_llvm_md_release/
└── tools/
├── linux_debug/
├── linux_release/
├── win_debug/
├── win_release/
├── win_llvm_debug/
├── win_llvm_release/
├── win_md_debug/
├── win_md_release/
├── win_llvm_md_debug/
└── win_llvm_md_release/
The _md variants use dynamic MSVC runtime libraries (/MD, /MDd). The _llvm_ prefix indicates Clang/LLVM builds.
- Generator: Ninja
- Compiler: Clang/Clang++
- Library extension:
.a - Executable extension: none
- Warning suppression:
-w(can be overridden viacmake_options)
- Generator: Visual Studio (MultiConfig)
- Compiler: MSVC
- Library extension:
.lib - Executable extension:
.exe - Release builds use
RelWithDebInfofor PDB files - Warning suppression:
/W0(can be overridden viacmake_options)
# Run all tests
./venv/bin/python -m pytest tests/ -v
# Or with coverage
./venv/bin/python -m pytest tests/ -v --cov=vdepsThe test suite uses functional CMake projects with a Python artefact generator (tests/fixtures/vdeps/gen_artifact.py). These mock projects build quickly and test platform-specific behaviour, error handling, and configuration options without requiring actual C++ compilation.
To run specific test categories:
# Platform-specific tests only
./venv/bin/python -m pytest tests/test_vdeps_platforms.py -v
# Configuration tests
./venv/bin/python -m pytest tests/test_vdeps_configuration.py -v- Python 3.10+
- CMake 3.15+
- Ninja (Linux/macOS)
- Visual Studio 2019+ (Windows)
Vdeps is released under the MIT license:
Copyright 2026 UAA Software
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.