Repository navigation
Developer Build and Configuration
CoreTrace is a CMake C++20 project producing a single executable, ctrace. Dependencies are
integrated through FetchContent and ExternalProject, one CMake module per dependency in
cmake/.
mkdir -p build && cd build
cmake .. -DUSE_THREAD_SANITIZER=OFF -DUSE_ADDRESS_SANITIZER=OFF
make -j4
./ctrace --help| Option | Default | Effect |
|---|---|---|
USE_THREAD_SANITIZER |
OFF |
Build with ThreadSanitizer |
USE_ADDRESS_SANITIZER |
OFF |
Build with AddressSanitizer |
CORETRACE_WERROR |
ON |
Treat compiler warnings as errors |
USE_EXTERNAL_CLI11 |
OFF |
Fetch CLI11 instead of using the vendored header |
ENABLE_TSCANCODE |
OFF |
Build tscancode as an external project |
ENABLE_FLAWFINDER |
OFF |
Build flawfinder as an external project |
ENABLE_PYTHON_ANALYZER |
OFF |
Build the Python analyzer as a bundled standalone binary |
CORETRACE_VERSION_OVERRIDE |
— | Force the embedded version string |
CORETRACE_PYTHON_ANALYZER_SOURCE_DIR |
— | Build a local analyzer checkout instead of the pinned tag |
ThreadSanitizer and AddressSanitizer cannot be enabled together.
The CLI parser backend is no longer selectable: PARSER_TYPE, the getopt backend and the parser
factory are gone, and CLI11 is used directly in src/App/Config.cpp.
| Dependency | Pin |
|---|---|
nlohmann/json |
v3.11.3 (release archive) |
coretrace-stack-analyzer |
v0.22.0 |
coretrace-log |
main |
cpp-httplib |
v0.14.3 |
CLI11 (when USE_EXTERNAL_CLI11=ON) |
v2.3.2 |
| Dependency | Pin | Option |
|---|---|---|
coretrace-TscanCode |
master |
ENABLE_TSCANCODE |
flawfinder |
master |
ENABLE_FLAWFINDER |
coretrace-python-analyzer |
pinned tag | ENABLE_PYTHON_ANALYZER |
cmake/ikos.cmake exists but its include() is commented out of CMakeLists.txt: IKOS is not
built by default.
Version resolution is centralized at configure time (cmake/CoreTraceVersion.cmake):
- release builds receive an explicit version string from CI, so published binaries print the exact GitHub release tag;
- local Git builds resolve it from
git describe --tags --dirty --always --match 'v*'; - without Git metadata the build falls back to
dev.
cmake .. -DCORETRACE_VERSION_OVERRIDE=v0.74.0
./ctrace --version-DENABLE_PYTHON_ANALYZER=ON builds
coretrace-python-analyzer into a
standalone executable with Nuitka, staged in build/libexec/coretrace/
and installed to <prefix>/libexec/coretrace/. It embeds its own Python runtime, so people
running ctrace need neither Python nor any package.
Building it needs Python ≥ 3.11 with Nuitka (python3 -m pip install nuitka), a C compiler, and
patchelf on Linux.
cmake .. -DENABLE_PYTHON_ANALYZER=ON -DPython3_EXECUTABLE=/path/to/python3The Linux release archives (amd64, arm64) run on any distribution with glibc 2.34 or newer: RHEL 9 and its rebuilds (Rocky, Alma), Amazon Linux 2023, Ubuntu 22.04+, Debian 12+, Fedora 35+.
-
ctraceis built on Ubuntu 22.04 and carries its own libstdc++. - The Python analyzer is built on Rocky Linux 9.
- Each archive is unpacked and run on bare Rocky Linux 9, Ubuntu 22.04, Debian 12 and Ubuntu 24.04 images, with no compiler and no LLVM, before it is published.
- Each architecture builds on a native runner (
ubuntu-24.04andubuntu-24.04-arm): emulating arm64 through QEMU took about 25 minutes for the LLVM-linked analyzer, native takes a few.
| Workflow | What it does |
|---|---|
build.yml |
Builds on ubuntu-24.04 and macos-14 with LLVM/Clang 20 and ENABLE_PYTHON_ANALYZER=ON, then runs the -h smoke test, ctest, and the F7 async harness |
clang-format.yml |
Installs clang-format 17 and runs scripts/format-check.sh
|
license-compliance.yml |
Enforces Apache-2.0 header integrity |
release-binaries.yml |
Builds and validates the Linux release archives, then attaches them to the GitHub release |
The F7 async harness (tests/BTP-STACK-ANALYZER-F7) drives cppcheck and the stack analyzer in
both scheduling modes and compares diagnostic fingerprints. Its speed-up assertion is disabled
in CI (--min-speedup-ratio 0): a timing claim is not reliable on a shared runner, and the
fingerprints are the point.
Warnings are errors in CI (CORETRACE_WERROR=ON, the default).
./scripts/format.sh # format in place
./scripts/format-check.sh # verify only
cmake --build build --target format
cmake --build build --target format-checkTarget version: clang-format 17, the version used in CI.
Every input path — config file, HTTP request, CLI — fills the same ProgramConfig
(include/Config/config.hpp) through the same loader, so validation and normalization are
identical everywhere.
built-in defaults < config file (--config / params.config) < CLI options / request params
↓
shipped defaults fill what is still empty
-
buildConfig()parses the command line with CLI11 from the option table insrc/App/Config.cpp. Each entry declares its CLI spelling, its kind, and the config section and key it lands in — the help text is generated from that same table. - When
--configis given, the file is loaded first. - CLI values are turned into a sectioned JSON document and applied through
applyToolConfigObject(), the loader the file goes through. -
applyShippedDefaults()fills what remains empty, see Shipped Defaults.
Loader diagnostics name the internal section key; they are rewritten to the option the user typed (CLI) or the flat parameter the client sent (HTTP) before being shown.
The configuration loader never exits the process: it returns an error that the front end turns
into an exit code (1 for a usage or configuration error).
The file is sectioned, one section per struct of ProgramConfig: analysis, files, output,
runtime, server, stack_analyzer, tools, plus a schema_version gate (currently 1).
config/tool-config.json is the canonical default file, and docs/configuration.md is the
full reference: type, default, allowed values, impact and CLI equivalent for every key. It is
kept next to the code rather than duplicated here.
Relative paths in the file are resolved from the config file's directory.
The pre-section layout still loads, and each occurrence prints a
Deprecated config key '<key>' in '<where>': use '<canonical>'. warning:
| Legacy | Replacement |
|---|---|
root invoke
|
analysis.invoke |
root input
|
files.input |
| root stack-analyzer keys | stack_analyzer.* |
tools.ctrace_stack_analyzer.* |
stack_analyzer.* |
Inside the file, precedence is: the stack_analyzer section, then the legacy root keys, then
the legacy tools entry.
"tools": {
"paths": { "cppcheck": "/usr/local/bin/cppcheck" },
"args": { "cppcheck": ["--disable=style"] }
}A path may be a bare command name resolved through PATH, or an absolute path. Tools absent
from the map fall back to their own name. args are appended verbatim after the options
CoreTrace derives, so they can override them.