TriBITS Build Reference
This page is a reference, not a tutorial. It documents the variables, macros, patterns, and troubleshooting techniques for TriBITS builds. Use the table of contents to jump to what you need. For explanations and walkthroughs, see the Developers Guide and Guides.

Key Terms and Glossary
Understanding the terminology is half the battle with any build system. These terms have specific meanings in TriBITS.
Package. The fundamental unit of organization. A directory with a CMakeLists.txt that calls tribits_package(), a dependency declaration, and optionally libraries and tests.
Subpackage. A subdivision of a package. Has its own dependency list and can be enabled independently. Useful for large packages with separable concerns.
TPL (Third-Party Library). An external dependency not managed by TriBITS. Found using CMake find modules.
SE Package (Software Engineering Package). The older name for what is now just called a package. You may encounter this term in older documentation or code comments.
Forward Dependencies. Packages that depend on a given package. If A depends on B, then A is a forward dependency of B. "Enable forward deps" means "also enable everything that uses this package."
Upstream/Downstream. Upstream packages are dependencies. Downstream packages are forward dependencies. Data and build order flow from upstream to downstream.
Test Category. A classification that controls when tests run: BASIC (every commit), NIGHTLY (scheduled), HEAVY (on demand).
Superbuild. A build that spans multiple repositories, treating all their packages as part of one project.
Configuration Variables and Typical Toggles
These are the CMake cache variables that control a TriBITS build. Set them with -D on the cmake command line or in a configuration file.
Package Enable/Disable
# Enable a specific package
-D <Project>_ENABLE_<PackageName>=ON
# Enable all packages
-D <Project>_ENABLE_ALL_PACKAGES=ON
# Enable forward dependencies of enabled packages
-D <Project>_ENABLE_ALL_FORWARD_DEP_PACKAGES=ON
# Enable optional dependencies of enabled packages (default ON)
-D <Project>_ENABLE_ALL_OPTIONAL_PACKAGES=ON
# Disable a specific package even if it would be auto-enabled
-D <Project>_ENABLE_<PackageName>=OFF
The enable logic follows this priority: explicit settings override auto-enable, and auto-enable follows the dependency graph. If you explicitly disable a package that another enabled package requires, configure will fail with an error message explaining the conflict.
Build Type and Compiler
# Standard CMake build type
-D CMAKE_BUILD_TYPE=Debug|Release|RelWithDebInfo|MinSizeRel
# Compiler selection
-D CMAKE_C_COMPILER=gcc
-D CMAKE_CXX_COMPILER=g++
-D CMAKE_Fortran_COMPILER=gfortran
# Compiler flags (appended to defaults)
-D CMAKE_CXX_FLAGS="-Wall -Wextra"
# Build shared libraries
-D BUILD_SHARED_LIBS=ON
Testing Controls
# Enable tests for all enabled packages
-D <Project>_ENABLE_TESTS=ON
# Test category filter
-D <Project>_TEST_CATEGORIES=BASIC|NIGHTLY|HEAVY
# Enable examples (treated separately from tests)
-D <Project>_ENABLE_EXAMPLES=ON
# Parallel test execution
-D CTEST_PARALLEL_LEVEL=8
TPL Configuration
# Enable a TPL
-D TPL_ENABLE_MPI=ON
-D TPL_ENABLE_Boost=ON
# Specify TPL installation path
-D Boost_ROOT=/opt/boost-1.82
-D MPI_BASE_DIR=/usr/lib/x86_64-linux-gnu/openmpi
# Disable a TPL even if packages request it
-D TPL_ENABLE_CUDA=OFF
Multi-Repository
# List of extra repositories
-D <Project>_EXTRA_REPOSITORIES="Repo1;Repo2"
# Path to extra repos list file
-D <Project>_EXTRAREPOS_FILE=cmake/ExtraRepositoriesList.cmake
Output and Debugging
# Verbose configure output
-D <Project>_VERBOSE_CONFIGURE=ON
# Generate dependency graph
-D <Project>_DEPS_DEFAULT_DOT_FILE=deps.dot
# Dump variables after configure
-D <Project>_DUMP_PACKAGE_DEPENDENCIES=ON
Dependency Declaration Patterns
Dependencies are declared in each package's cmake/Dependencies.cmake file using tribits_package_define_dependencies().
Minimal Declaration
tribits_package_define_dependencies(
LIB_REQUIRED_PACKAGES CoreUtils
)
This package requires CoreUtils to build its library. Nothing else.
Full Declaration
tribits_package_define_dependencies(
LIB_REQUIRED_PACKAGES CoreUtils MathLib
LIB_OPTIONAL_PACKAGES AdvancedSolver Visualization
TEST_REQUIRED_PACKAGES TestingFramework
TEST_OPTIONAL_PACKAGES BenchmarkSuite
LIB_REQUIRED_TPLS BLAS LAPACK
LIB_OPTIONAL_TPLS MPI CUDA
)
Subpackage Dependencies
Subpackages can depend on each other (within the same parent) or on external packages:
# In BigPackage_Core/cmake/Dependencies.cmake
tribits_package_define_dependencies(
LIB_REQUIRED_TPLS Boost
)
# In BigPackage_IO/cmake/Dependencies.cmake
tribits_package_define_dependencies(
LIB_REQUIRED_PACKAGES BigPackageCore
LIB_OPTIONAL_TPLS HDF5
)
TPL Find Modules
External dependencies are located using find modules. TriBITS provides a standard pattern:
tribits_tpl_find_include_dirs_and_libraries(MyTPL
REQUIRED_HEADERS mytpl.h
REQUIRED_LIBS_NAMES mytpl
)
For TPLs with standard CMake find modules, you can delegate to them. Projects like LLVM provide well-maintained CMake config files that TriBITS can use through standard find_package() calls within the TPL find module.
Testing and Install Rules
Adding Tests
The most common patterns:
# Simple test: build and run an executable
tribits_add_executable_and_test(
MyTest
SOURCES test_main.cpp
CATEGORIES BASIC
)
# Test with MPI
tribits_add_executable_and_test(
MyParallelTest
SOURCES test_parallel.cpp
NUM_MPI_PROCS 4
CATEGORIES NIGHTLY
)
# Test with specific pass criteria
tribits_add_test(my_app
NAME regression_check
ARGS "--input=regression_data.xml"
PASS_REGULAR_EXPRESSION "All checks passed"
CATEGORIES BASIC
)
# Multi-step advanced test
tribits_add_advanced_test(
IntegrationTest
TEST_0 EXEC setup_tool ARGS "--init"
TEST_1 EXEC my_app ARGS "--run"
TEST_2 EXEC verify_tool ARGS "--check"
CATEGORIES NIGHTLY
)
Install Targets
Libraries and headers declared through tribits_add_library() are automatically installed. The install prefix is set by CMAKE_INSTALL_PREFIX.
cmake --build build --target install
# or
cmake --install build --prefix /opt/myproject
Installed packages generate CMake config files so that downstream projects can find them with find_package().
Common Failure Modes and Fixes
This section documents the error patterns you are most likely to encounter, along with their causes and fixes.
"Package X not found"
Cause: The package is not listed in PackagesList.cmake, or its directory does not exist.
Fix: Add the package to the list file and ensure the directory and CMakeLists.txt exist.
"Circular dependency detected"
Cause: Package A depends on B, and B depends on A (directly or transitively).
Fix: Break the cycle. Extract shared code into a third package that both A and B can depend on. Circular dependencies in the package graph are never correct.
"TPL X not found"
Cause: The TPL is required but its headers or libraries were not found in standard locations.
Fix: Set the TPL root directory: -D <TPLName>_ROOT=/path/to/tpl. Or disable the TPL if it is optional: -D TPL_ENABLE_<TPLName>=OFF.
"Cannot enable Package X because required dependency Y is disabled"
Cause: You explicitly disabled a package that another enabled package requires.
Fix: Either enable the dependency or disable the package that requires it. The framework will not silently build with missing required dependencies.
Build succeeds locally but fails in CI
Cause: Usually an implicit dependency that is not declared. The package uses headers or libraries from another package but does not list it in Dependencies.cmake. It works locally because both happen to be enabled.
Fix: Declare the dependency. Build with only the target package enabled (disable everything else) to find undeclared dependencies.
Tests pass locally but fail in CI
Cause: Common causes include:
- Hard-coded file paths.
- Reliance on specific compiler behavior.
- Tests that depend on execution order.
- Timing-sensitive assertions.
- Resource assumptions (memory, disk space, network).
Fix: Make tests self-contained. Use relative paths, avoid timing assertions where possible, and clean up test artifacts.
Incremental build after dependency change
Cause: After changing Dependencies.cmake, the build directory may have stale cache entries.
Fix: Delete the build directory and reconfigure from scratch. CMake does not always detect dependency graph changes cleanly.
How to Read Build Output
TriBITS builds produce a lot of output. Here is how to read it efficiently.
Configure Phase
Look for these sections:
- Package enablement summary. A table showing which packages are enabled and why (explicitly, auto-enabled, disabled).
- TPL detection. Which TPLs were found and where.
- Warnings. Any packages that requested optional dependencies that are not available.
Build Phase
Standard CMake build output. Look for:
- Compilation errors. The first error is usually the important one. Later errors often cascade from the first.
- Link errors. Undefined symbols usually mean a missing dependency declaration.
- Warnings. Treat warnings seriously. They often become errors on other compilers or with stricter flags.
Test Phase
CTest output. Look for:
- Test summary. Total, passed, failed, timeout, not run.
- Failed tests. CTest lists them at the end. Use
ctest --rerun-failedto re-run only the failures. - Timeout tests. A test that times out is either too slow for its category or hung. Check the test's timeout setting.

FAQ
Q: How do I find all configuration variables for a specific package? A: Run configure with verbose output: -D <Project>_VERBOSE_CONFIGURE=ON. The output shows all variables that the package defines and uses. You can also look at the package's CMake files directly.
Q: Can I use ccache with TriBITS? A: Yes. Set -D CMAKE_CXX_COMPILER_LAUNCHER=ccache. It works transparently with the TriBITS build because TriBITS uses standard CMake targets.
Q: How do I run just one test? A: Use CTest filtering: ctest -R <test_name>. The -R flag is a regex filter on the test name.
Q: What is the difference between tribits_add_test and tribits_add_executable_and_test? A: tribits_add_executable_and_test creates both the executable and the test in one call. tribits_add_test creates a test that runs an existing executable. Use the combined version for simple cases. Use the separate version when one executable is used by multiple tests with different arguments.
Q: How do I add a new TPL to the project? A: Create a find module (e.g., cmake/tpls/FindTPL<Name>.cmake), add the TPL to TPLsList.cmake, and add the TPL dependency to the packages that need it. The find module tells TriBITS how to locate the TPL's headers and libraries.
Q: How do I debug a configure failure? A: Start with verbose configure. If that is not enough, look at CMakeError.log and CMakeOutput.log in the build directory. These files contain the raw output from compiler checks and find modules.