xtc/docs/BUILD.md

10 KiB

Building xtc with CMake

The root CMakeLists.txt is the authoritative build. C99 engine/model/DSP and public C APIs remain in include/xtc and src; C++17 is used for the optional FLTK interface and SDK examples. The small root Makefile only forwards common commands to CMake/CTest; it contains no source lists or compilation rules. Direct CMake builds need no Make wrapper. CMake does not download SDKs or install system dependencies.

Configure, build and test

Requirements: CMake 3.25+, a C99 compiler, Python 3.12+ for build/test/release tools, a POSIX toolchain with threads, math and dynamic loading, and a CMake backend such as Ninja or Unix Makefiles. C++17 is required when GUI/SDK targets are enabled. pkg-config discovers optional JACK; FLTK discovery tries pkg-config then fltk-config. LADSPA uses its installed development header. Missing optional development files do not prevent the core from building.

From the source root:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel
ctest --test-dir build --output-on-failure
./build/xtc-check
./build/xtc  # when FLTK was found

All binaries and the static libxtc.a are in the chosen binary directory. The default build includes offline test binaries and plugin fixtures. CTest runs offline, fault-injection, plugin, recovery, capacity/endurance, and available GUI tests; live JACK tests require explicit opt-in. GUI tests use Xvfb and startup checks also require xdotool. No physical ports are connected by tests. CTest runs source-relative fixtures with an explicit working directory. Assertions stay enabled in optimized test builds.

Use a new build directory when changing compiler, generator or instrumentation. For Ninja, add -G Ninja to the configure command. CMake also writes compile_commands.json for editors and analysis tools. In CLion, open the root project and select a CMake profile/preset; do not import a Makefile project.

Optional presets separate configurations:

cmake --preset debug
cmake --build --preset debug --parallel
ctest --preset debug

release, minimal and sanitize presets follow the same three commands. Release enables optimized builds and source/binary prefix maps. Minimal disables FLTK, JACK and LADSPA. Sanitize selects Clang ASan/UBSan for offline C tests; it does not enable GUI or physical-device tests. Existing GUI sanitizer caveats and fontconfig leak suppressions are described in the integration notes.

Quick Make shortcuts

With GNU Make installed, make (or make build) configures and builds; make test/make check also runs CTest. make gui builds the FLTK app, make run builds and launches it, and make clean cleans products while keeping the cache. make configure only configures, and make help lists shortcuts.

Defaults are BUILD_DIR=build, BUILD_TYPE=Debug and JOBS=4. For example:

make BUILD_DIR=build/release BUILD_TYPE=Release JOBS=8
make BUILD_DIR=build/minimal CMAKE_ARGS='-G Ninja -DXTC_BUILD_GUI=OFF -DXTC_WITH_JACK=OFF'
make test CTEST_ARGS='-R ^core$'

Use a fresh binary directory when changing generator/compiler. Extra configure flags go in CMAKE_ARGS; extra CTest flags go in CTEST_ARGS. These shortcuts use the same CMake targets and cache as the direct commands above. Keep source lists, dependencies, SDK and packaging rules in CMake.

Configuration

Cache option Default Meaning
BUILD_TESTING ON Build/register the test suite
XTC_BUILD_JUCE_GUI OFF Build the JUCE workstation frontend (xtc-juce), independently of FLTK; requires XTC_JUCE_ROOT
XTC_BUILD_GUI ON Discover FLTK and build the application when available
XTC_WITH_JACK ON Discover/build the JACK/PipeWire backend
XTC_WITH_LADSPA ON Enable LADSPA when the system header exists
XTC_ENABLE_LIVE_TESTS OFF Register software JACK loopback and GUI/JACK workflows
XTC_SANITIZE OFF Address/undefined sanitizers, frame pointers
XTC_REPRODUCIBLE OFF Remove source/binary directory paths and debug information
XTC_BUILD_JUCE OFF Build externally supplied JUCE integration
XTC_BUILD_STEINBERG OFF Build externally supplied official VST3 SDK examples

Use -DNAME=VALUE during configuration, not Make variables. Standard CMake settings include CMAKE_C_COMPILER, CMAKE_CXX_COMPILER, CMAKE_BUILD_TYPE, CMAKE_C_FLAGS, CMAKE_CXX_FLAGS and CMAKE_EXE_LINKER_FLAGS. CMake propagates includes, definitions and link dependencies through targets. Core users can link xtc::core inside this build; installed consumers use pkg-config xtc.

A fully offline minimal configuration:

cmake -S . -B build/minimal -G Ninja -DCMAKE_BUILD_TYPE=Release \
  -DXTC_BUILD_GUI=OFF -DXTC_WITH_JACK=OFF -DXTC_WITH_LADSPA=OFF
cmake --build build/minimal --parallel
ctest --test-dir build/minimal --output-on-failure

This path needs no C++ compiler, FLTK, JACK or LADSPA development files. CLAP and VST3 C headers stay pinned in third_party; VST2 uses original declarations. No external plugin or SDK is included in normal packages. See LICENSES.md.

Focused tests and tools

Build before invoking CTest, or use check, which builds the test dependencies:

cmake --build build --target check --parallel
ctest --test-dir build --output-on-failure -R '^(core|realtime|modern-plugins)$'
ctest --test-dir build --output-on-failure -L gui
cmake --build build --target test-reliability test-recording test-scale test-soak
cmake --build build --target analyze
cmake --build build --target quality-preview builtin-preview

The xtc-gui target explicitly includes the sequencer master, track/header, clip, velocity and ruler implementations, plus command, instrument and waveform support files. See the component map when adding GUI sources; update cmake/Gui.cmake alongside new implementation files.

Each registered root test also has a test-NAME build target (for example test-core, test-gui, test-track-fx). test-builtins aliases test-builtin. gui builds the optional main application. Preview targets write WAVs below the binary directory without playback. Screenshot commands are in the gallery. These commands assume configuration has already completed; feature-specific docs use the same convention.

To qualify live software routing against an existing JACK-compatible server:

cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON
cmake --build build --parallel
ctest --test-dir build --output-on-failure -L live
./build/test_jack 30  # optional longer software loopback run

Live tests are serialized. They neither start/reconfigure the server nor establish physical-device acceptance. See AUDIO_ENGINE.md.

Developer targets include benchmark, benchmark-compare, benchmark-project, benchmark-project-compare, test-stress, test-stress-plugins, test-plugins-real and check-development. The latter combines the normal suite, Clang static analysis and a separate sanitizer build. debug, release and test-sanitize convenience targets configure/build/test child directories; prefer presets when selecting the directory explicitly. Benchmark/stress cache variables are XTC_BENCHMARK_BLOCKS, XTC_BENCHMARK_MAX_REGRESSION, XTC_BENCHMARK_BASELINE, XTC_PROJECT_BENCHMARK_BASELINE and XTC_STRESS_ROUNDS. Run benchmarks without concurrent testing/instrumentation for meaningful timing.

For ThreadSanitizer, use a separate configuration with -DCMAKE_C_FLAGS='-g -O1 -fsanitize=thread' and -DCMAKE_EXE_LINKER_FLAGS=-fsanitize=thread, build test_realtime/test_audio, and run those binaries. Tool/runtime support depends on the host.

SDKs, installation and release

See JUCE.md and STEINBERG.md for optional SDK configuration, licenses and qualification limits. Both now build within the root CMake project; the JUCE bridge links the same PIC C core target.

cmake -S . -B build/release -DCMAKE_BUILD_TYPE=Release -DXTC_REPRODUCIBLE=ON \
  -DCMAKE_INSTALL_PREFIX=/usr
cmake --build build/release --parallel
ctest --test-dir build/release --output-on-failure
DESTDIR="$PWD/build/stage" cmake --install build/release --prefix /usr
DESTDIR="$PWD/build/stage" cmake --build build/release --target uninstall

For uninstall, configure with -DCMAKE_INSTALL_PREFIX=/usr first when that is the desired permanent prefix, or invoke the generated xtc-install.cmake with -DCMAKE_INSTALL_PREFIX=/usr -DXTC_UNINSTALL=ON -P explicitly. The --prefix install override does not persist in CMake's cache. Prefer setting the prefix at configure time for a matching install/uninstall pair. Standard DESTDIR staging never enters installed metadata. The audited Python installer retains exact owned-file inventory, atomic file replacement and symlink protection.

test-install and test-install-layout stage into temporary directories and compile installed C/C++ consumers. dist exports indexed files; test-release rebuilds two exports; package-binary (also aliased as package) and test-package stage and verify a local Linux archive. See RELEASING.md for layout/manifest details.

Clean products with cmake --build build --target clean; to discard the cache, remove only the selected build directory. Never configure in the source tree. Historical validation entries in ROADMAP describe the build used at that time; Phase 108 records the CMake migration and its verified results.

Optional JUCE workstation frontend

See src/gui/JUCE/README.md for the component map and licence requirements. The SDK is supplied by the user; no download occurs.

cmake -S . -B build/juce-gui -DCMAKE_BUILD_TYPE=Debug \
  -DXTC_BUILD_GUI=OFF -DXTC_BUILD_JUCE_GUI=ON -DXTC_JUCE_ROOT=/path/to/JUCE
cmake --build build/juce-gui --parallel 4 --target xtc-juce test_juce_gui
./build/juce-gui/xtc-juce examples/projects/playback-test.xtc
ctest --test-dir build/juce-gui -R juce-gui --output-on-failure -j1

XTC_BUILD_GUI=ON builds both frontends. XTC_BUILD_JUCE continues to mean JUCE plugin/processor examples and can be enabled independently or alongside the workstation frontend. A missing SDK is a configuration error only when a JUCE option is enabled. The existing default FLTK build is unchanged.