CMake
The ThreadPool module provides a CMake package and an exported target for use from CMake projects.
The installed target is:
vix::threadpoolA minimal project needs:
find_package(vix_threadpool CONFIG REQUIRED)
target_link_libraries(app
PRIVATE
vix::threadpool
)The target carries the ThreadPool include directory, C++20 requirement, and native thread dependency.
Minimal project
Given:
my-app/
├── CMakeLists.txt
└── main.cppCMakeLists.txt can be:
cmake_minimum_required(VERSION 3.20)
project(my_app LANGUAGES CXX)
find_package(vix_threadpool CONFIG REQUIRED)
add_executable(my_app
main.cpp
)
target_link_libraries(my_app
PRIVATE
vix::threadpool
)Then:
#include <vix/threadpool/all.hpp>
int main()
{
vix::threadpool::ThreadPool pool(4);
auto future = pool.submit([](){
return 42;
});
return future.get() == 42 ? 0 : 1;
}The application does not need to manually add ThreadPool include directories or thread linker flags.
Package name and target name
The standalone installed CMake package is named:
vix_threadpoolTherefore use:
find_package(vix_threadpool CONFIG REQUIRED)The imported library target is:
vix::threadpoolTherefore link with:
target_link_libraries(app
PRIVATE
vix::threadpool
)These names serve different purposes:
vix_threadpool
↓
CMake package name
vix::threadpool
↓
CMake target used by consumersDo not link the archive manually
An installed standalone package contains a static library such as:
lib/libvix_threadpool.aApplication CMake files should not normally link that path directly.
Avoid:
target_link_libraries(app
PRIVATE
/some/path/libvix_threadpool.a
)Prefer:
find_package(vix_threadpool CONFIG REQUIRED)
target_link_libraries(app
PRIVATE
vix::threadpool
)The imported target carries the package's usage requirements.
C++20
ThreadPool requires C++20.
The CMake target exports:
cxx_std_20as a public compile feature.
When an application links:
target_link_libraries(app
PRIVATE
vix::threadpool
)CMake knows that the consumer must support C++20.
You can also state the application's own requirement explicitly:
target_compile_features(app
PRIVATE
cxx_std_20
)This is useful when C++20 is a direct requirement of the application itself.
Minimum CMake version
The ThreadPool standalone project declares:
cmake_minimum_required(VERSION 3.20)and the module manifest also specifies:
minimum CMake version: 3.20Use CMake 3.20 or newer when building the module itself.
A consumer project can choose its own minimum version according to the rest of its build, but using CMake 3.20 or newer keeps it aligned with the ThreadPool module.
Native thread dependency
ThreadPool uses CMake's standard threads package:
find_package(Threads REQUIRED)The library links publicly to:
Threads::ThreadsThe installed package config also contains:
include(CMakeFindDependencyMacro)
find_dependency(Threads REQUIRED)Therefore consumer projects do not need to repeat:
find_package(Threads REQUIRED)just to satisfy ThreadPool.
This is handled by:
find_package(vix_threadpool CONFIG REQUIRED)Transitive thread linking
The exported target contains:
INTERFACE_LINK_LIBRARIES = Threads::ThreadsTherefore:
target_link_libraries(app
PRIVATE
vix::threadpool
)also gives the application the native thread-linking requirements needed by the module.
On platforms where additional thread flags are required, CMake's Threads::Threads target handles them.
Do not manually add platform-specific flags such as:
-pthreadwhen using the exported CMake target unless the application independently requires custom handling.
Include directories
The target exports the module's installed include directory.
After installation, headers are available under:
include/vix/threadpool/For example:
include/vix/threadpool/ThreadPool.hpp
include/vix/threadpool/Future.hpp
include/vix/threadpool/TaskOptions.hpp
include/vix/threadpool/ParallelFor.hpp
include/vix/threadpool/all.hppConsumer code can therefore write:
#include <vix/threadpool/all.hpp>without adding a manual include path.
Umbrella header
For general ThreadPool use, include:
#include <vix/threadpool/all.hpp>This is the ThreadPool module umbrella header installed by the standalone package.
For narrower compilation dependencies, individual public headers can also be included:
#include <vix/threadpool/ThreadPool.hpp>
#include <vix/threadpool/Future.hpp>Both styles use the include directory exported by vix::threadpool.
Installed package layout
A standalone installation has the effective structure:
<prefix>/
├── include/
│ └── vix/
│ └── threadpool/
│ ├── all.hpp
│ ├── ThreadPool.hpp
│ ├── Future.hpp
│ └── ...
├── lib/
│ ├── libvix_threadpool.a
│ └── cmake/
│ └── vix_threadpool/
│ ├── vix_threadpoolConfig.cmake
│ ├── vix_threadpoolConfigVersion.cmake
│ ├── vix_threadpoolTargets.cmake
│ └── vix_threadpoolTargets-<config>.cmakeThe exact library directory can depend on the platform and GNUInstallDirs.
Applications should rely on find_package() rather than hard-coding this layout.
Static library
The current ThreadPool source tree contains implementation .cpp files.
The standalone build therefore creates:
add_library(vix_threadpool STATIC ...)and exports it to consumers as:
vix::threadpoolThe installed artifact is consequently a static library on the current module build.
The module manifest also describes its library type as:
staticSource target and namespaced alias
Inside the ThreadPool source build, the actual CMake target is:
vix_threadpoolThe project creates the namespaced alias:
add_library(vix::threadpool ALIAS vix_threadpool)Application code should normally depend on:
vix::threadpoolrather than the implementation target name.
This keeps source-tree and installed-package usage consistent.
Add ThreadPool with add_subdirectory
When the ThreadPool source is directly part of another CMake source tree, it can be added with:
add_subdirectory(path/to/threadpool)
target_link_libraries(app
PRIVATE
vix::threadpool
)For example:
my-project/
├── CMakeLists.txt
├── app/
│ └── main.cpp
└── external/
└── threadpool/
├── CMakeLists.txt
├── include/
└── src/The root build can contain:
cmake_minimum_required(VERSION 3.20)
project(my_project LANGUAGES CXX)
add_subdirectory(external/threadpool)
add_executable(app
app/main.cpp
)
target_link_libraries(app
PRIVATE
vix::threadpool
)No find_package(vix_threadpool) is needed in this form because the target is created directly by add_subdirectory().
Installed package vs source tree
Use:
find_package(vix_threadpool CONFIG REQUIRED)when ThreadPool has already been installed as a package.
Use:
add_subdirectory(...)when the ThreadPool source tree is directly included in the current CMake build.
Both forms expose the same consumer target:
vix::threadpoolThis is the main CMake integration contract.
Building ThreadPool standalone
From the module source directory:
cmake -S . -B build
cmake --build buildThe default build creates the ThreadPool library.
The project options for:
examples
tests
benchmarksare disabled by default.
Install the standalone package
A normal installation can be created with:
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/desired/prefix
cmake --build build
cmake --install buildThis installs:
library
public headers
CMake package config
CMake version file
exported target filesunder the selected prefix.
Custom installation prefix
For example:
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/.local"
cmake --build build
cmake --install buildThe package is then installed below:
$HOME/.localA consumer must make that prefix discoverable by CMake when it is outside the normal search paths.
CMAKE_PREFIX_PATH
One way to expose a custom installation is:
cmake -S . -B build \
-DCMAKE_PREFIX_PATH="$HOME/.local"The consumer can then use the normal:
find_package(vix_threadpool CONFIG REQUIRED)You can also provide multiple package prefixes through the normal CMake CMAKE_PREFIX_PATH mechanism.
Direct package directory
CMake can also be pointed directly to the package directory:
cmake -S . -B build \
-Dvix_threadpool_DIR=/prefix/lib/cmake/vix_threadpoolThat directory must contain:
vix_threadpoolConfig.cmakeThis is useful for debugging package discovery, but a prefix-based configuration is usually easier to move between environments.
Package configuration
The installed package configuration performs three main operations:
include(CMakeFindDependencyMacro)
find_dependency(Threads REQUIRED)
include(
"${CMAKE_CURRENT_LIST_DIR}/vix_threadpoolTargets.cmake"
)It then calls:
check_required_components(vix_threadpool)The exported targets file defines:
vix::threadpoolas the imported target.
Exported target properties
The installed vix::threadpool target exports the important consumer requirements:
target type:
STATIC IMPORTED
compile feature:
cxx_std_20
include directory:
<install-prefix>/include
link dependency:
Threads::ThreadsThe physical library location is provided by the configuration-specific exported target file.
Consumers should use those target properties through target_link_libraries() rather than reproducing them manually.
Package version
The standalone ThreadPool CMake project currently declares:
project(
vix_threadpool
VERSION 0.1.0
LANGUAGES CXX
)The generated package version file uses:
COMPATIBILITY SameMajorVersionTherefore version-aware discovery is supported.
For example:
find_package(
vix_threadpool 0.1
CONFIG
REQUIRED
)asks CMake for a package version compatible with that requested version under the generated same-major-version policy.
For most applications that only need the installed ThreadPool package, this remains sufficient:
find_package(vix_threadpool CONFIG REQUIRED)Build examples
Examples are disabled by default.
Enable them with:
cmake -S . -B build \
-DVIX_THREADPOOL_BUILD_EXAMPLES=ON
cmake --build buildThe option is:
VIX_THREADPOOL_BUILD_EXAMPLESwith default value:
OFFExample targets
The module's example build currently includes programs for:
basic_post
custom_config
metrics
parallel_for
parallel_for_each
parallel_map
parallel_reduce
periodic_task
shutdown
submit_future
task_cancellation
task_group
task_priority
task_timeoutEach example links:
target_link_libraries(example
PRIVATE
vix::threadpool
)and requests:
cxx_std_20Build tests
Tests are disabled by default.
Enable them with:
cmake -S . -B build \
-DVIX_THREADPOOL_BUILD_TESTS=ONThe option is:
VIX_THREADPOOL_BUILD_TESTSwith default:
OFFWhen enabled, the root module build performs:
include(CTest)
enable_testing()
add_subdirectory(tests)when the tests directory is available.
Build benchmarks
Benchmarks are also disabled by default.
Enable them with:
cmake -S . -B build \
-DVIX_THREADPOOL_BUILD_BENCHMARKS=ONThe option is:
VIX_THREADPOOL_BUILD_BENCHMARKSwith default:
OFFEnable several development targets
For local module development:
cmake -S . -B build \
-DVIX_THREADPOOL_BUILD_EXAMPLES=ON \
-DVIX_THREADPOOL_BUILD_TESTS=ON \
-DVIX_THREADPOOL_BUILD_BENCHMARKS=ONThen:
cmake --build buildThese options affect development artifacts.
They are not required by applications consuming vix::threadpool.
Compiler warnings
When the module itself is compiled with a non-MSVC compiler, its CMake build enables:
-Wall
-Wextra
-Wpedanticfor the ThreadPool target.
These options are:
PRIVATETherefore they do not propagate to consumer targets.
An application chooses its own warning configuration independently.
Position-independent code
The module build sets:
CMAKE_POSITION_INDEPENDENT_CODE ONfor its build.
This affects how the ThreadPool library is compiled but does not require consumer projects to copy that setting merely to link the library.
Sanitizer integration
The module source CMake contains support for:
VIX_ENABLE_SANITIZERSon non-MSVC builds.
When that surrounding option is enabled, the ThreadPool target adds:
-fno-omit-frame-pointer
-fsanitize=address,undefinedfor compilation and:
-fsanitize=address,undefinedfor linking.
VIX_ENABLE_SANITIZERS is not declared as a ThreadPool-specific option in this module.
The ThreadPool build only reacts to it when the variable is already enabled by the surrounding build.
ThreadPool-specific options
The standalone module declares three ThreadPool-specific CMake options:
| Option | Default | Purpose |
|---|---|---|
VIX_THREADPOOL_BUILD_EXAMPLES | OFF | Build example executables |
VIX_THREADPOOL_BUILD_TESTS | OFF | Build tests |
VIX_THREADPOOL_BUILD_BENCHMARKS | OFF | Build benchmarks |
They do not change the public runtime API or consumer target name.
No external library dependency beyond threads
The module manifest currently declares:
deps = []At the CMake level, the runtime's explicit platform dependency is:
Threads::ThreadsThere is no required Boost, fmt, or other external C++ package in the standalone ThreadPool target.
Consumer dependency discovery is therefore:
vix_threadpool
↓
Threadsfor the current standalone package.
Standalone export
When ThreadPool is built outside the Vix umbrella build, its installation exports:
vix_threadpoolTargetsto:
lib/cmake/vix_threadpoolwith:
NAMESPACE vix::and the library's export name is:
threadpoolThose pieces combine to produce the installed target:
vix::threadpoolUmbrella build
The module also supports being built as part of the larger Vix source tree.
When:
VIX_UMBRELLA_BUILDis enabled, ThreadPool uses the umbrella export set:
VixTargetsinstead of installing its own standalone:
vix_threadpoolTargetsexport.
In this mode, standalone ThreadPool package configuration files are not generated by this module.
The owning Vix build is responsible for its package export.
The target available inside the build remains:
vix::threadpoolStandalone headers vs umbrella installation
In standalone mode, ThreadPool installs its public headers itself:
include/vix/threadpool/When built under:
VIX_UMBRELLA_BUILDthe module skips its own header-directory installation step.
Header installation is then handled by the surrounding Vix build.
This avoids duplicate installation logic between the module and the umbrella package.
Do not depend on internal export-set names
Application projects should not use:
vix_threadpoolTargets
VixTargetsdirectly.
Those are package-generation details.
Consumer code should depend only on the public target:
vix::threadpoolRecommended installed-package CMake
For a normal standalone installed package:
cmake_minimum_required(VERSION 3.20)
project(my_app LANGUAGES CXX)
find_package(vix_threadpool CONFIG REQUIRED)
add_executable(my_app
main.cpp
)
target_link_libraries(my_app
PRIVATE
vix::threadpool
)No additional ThreadPool CMake configuration is required.
Multiple application source files
A normal larger application works in the same way:
cmake_minimum_required(VERSION 3.20)
project(server LANGUAGES CXX)
find_package(vix_threadpool CONFIG REQUIRED)
add_executable(server
src/main.cpp
src/Service.cpp
src/JobProcessor.cpp
)
target_link_libraries(server
PRIVATE
vix::threadpool
)
target_compile_features(server
PRIVATE
cxx_std_20
)Application headers can then use ThreadPool normally:
#include <vix/threadpool/ThreadPool.hpp>or:
#include <vix/threadpool/all.hpp>Link through another library
If an application library exposes ThreadPool types in its public interface:
add_library(job_runtime
src/JobRuntime.cpp
)
target_link_libraries(job_runtime
PUBLIC
vix::threadpool
)then consumers of job_runtime inherit the ThreadPool usage requirements.
If ThreadPool appears only inside implementation files:
target_link_libraries(job_runtime
PRIVATE
vix::threadpool
)is usually more appropriate.
Choose PUBLIC or PRIVATE according to the application's own CMake interface design.
Troubleshooting package discovery
If CMake reports that it cannot find:
vix_threadpoolConfig.cmakefirst verify that ThreadPool was installed.
The package should contain a directory resembling:
<prefix>/lib/cmake/vix_threadpool/Then configure the consumer with the installation prefix:
cmake -S . -B build \
-DCMAKE_PREFIX_PATH=/prefixor the exact package directory:
cmake -S . -B build \
-Dvix_threadpool_DIR=/prefix/lib/cmake/vix_threadpoolTroubleshooting missing target
After a successful:
find_package(vix_threadpool CONFIG REQUIRED)this target should exist:
if (NOT TARGET vix::threadpool)
message(FATAL_ERROR "vix::threadpool target is unavailable")
endif()If it does not exist, the package installation or exported target files are incomplete or inconsistent.
The current standalone package configuration explicitly includes:
vix_threadpoolTargets.cmakewhich defines that imported target.
Troubleshooting missing library file
The generated imported target configuration refers to the installed static archive.
If CMake reports that:
vix::threadpoolreferences a library file that does not exist, the package installation is incomplete.
Reinstall the module rather than manually editing the generated target files:
cmake --build build
cmake --install buildThe exported CMake files include validation for referenced installed artifacts.
Troubleshooting C++ standard errors
If compiler errors indicate missing C++20 language features, verify:
compiler supports C++20and that the application actually links the exported target:
target_link_libraries(app
PRIVATE
vix::threadpool
)The target carries:
cxx_std_20as an interface compile feature.
Verified standalone consumer contract
The standalone package has been validated with the following consumer pattern:
find_package(vix_threadpool CONFIG REQUIRED)
target_link_libraries(app
PRIVATE
vix::threadpool
)and:
#include <vix/threadpool/all.hpp>
int main()
{
vix::threadpool::ThreadPool pool(2);
auto future = pool.submit([](){
return 42;
});
return future.get() == 42 ? 0 : 1;
}The installed package provides the include path, static library, C++20 requirement, and Threads::Threads dependency required by the consumer.
CMake integration summary
The installed integration path is:
install vix_threadpool
↓
vix_threadpoolConfig.cmake
↓
find_dependency(Threads)
↓
vix_threadpoolTargets.cmake
↓
vix::threadpool
↓
consumer targetThe important properties are:
- The standalone package name is
vix_threadpool. - Use
find_package(vix_threadpool CONFIG REQUIRED)for an installed standalone package. - The public consumer target is
vix::threadpool. - The source-tree target is
vix_threadpoolwith the aliasvix::threadpool. - Prefer the namespaced target in consumer code.
- The current module builds as a static library because implementation sources are present.
- The current standalone library artifact is
libvix_threadpool.aon the validated Unix-like installation. - The target requires C++20.
- The target exports its public include directory.
- The target publicly links
Threads::Threads. - The installed package resolves the Threads dependency automatically with
find_dependency(). - Public headers are installed under
include/vix/threadpool/. <vix/threadpool/all.hpp>is the module umbrella header.- The module itself requires CMake 3.20 or newer.
- Standalone package versioning currently uses version
0.1.0withSameMajorVersioncompatibility. add_subdirectory()can be used when the ThreadPool source tree is directly part of another CMake build.- Both installed and source-tree usage expose
vix::threadpool. - Examples, tests, and benchmarks are disabled by default.
- Their options are
VIX_THREADPOOL_BUILD_EXAMPLES,VIX_THREADPOOL_BUILD_TESTS, andVIX_THREADPOOL_BUILD_BENCHMARKS. VIX_ENABLE_SANITIZERSis consumed when supplied by a surrounding build, but is not declared as a ThreadPool-specific option.- The module has no additional required C++ package dependency beyond the platform thread abstraction represented by
Threads::Threads. - Standalone installation exports
vix_threadpoolTargets. - Umbrella builds instead participate in
VixTargets. - Standalone package config generation and standalone header installation are skipped when
VIX_UMBRELLA_BUILDis active. - Consumer projects should not depend directly on export-set names or physical library paths.
Continue with API Reference for a compact index of the public ThreadPool types, functions, enums, and headers.