Migrated from Make to CMake.

This commit is contained in:
Johannes Findeisen 2026-11-06 19:05:14 +01:00
commit b6ba093000
52 changed files with 1276 additions and 1210 deletions

View file

@ -109,12 +109,9 @@ implemented.
## Verification
make test includes deterministic WAV/graph samples, resampling/overlap/trim,
CTest includes deterministic WAV/graph samples, resampling/overlap/trim,
malformed inputs, missing/relinked assets, SPSC concurrency/overflow/cleanup,
and record -> save/reopen -> exact playback through the backend callback. make
test-gui covers the workflow and rollback with a fake backend. make
test-gui-jack records/reopens a silent take using real JACK callbacks. make
test-jack-audio routes only two software clients: known source -> recorded WAV
and record -> save/reopen -> exact playback through the backend callback. The CTest gui test covers the workflow and rollback with a fake backend. The CTest gui-jack test records/reopens a silent take using real JACK callbacks. The CTest jack-audio test routes only two software clients: known source -> recorded WAV
-> saved/reopened project -> graph playback -> capture assertion. Physical
input/output, device latency, slow-disk endurance and server loss during a real
recording remain unverified.
@ -139,7 +136,7 @@ never modified. A trailing partial frame is ignored. This handles xtc's
canonical 44-byte mono float32 header only, not arbitrary damaged WAVs. Recovery
is explicit and control-thread only; no orphan scan runs during playback.
`make test-recording` simulates 30 minutes at 8 kHz with repeated ring wrapping
`cmake --build build --target test-recording` simulates 30 minutes at 8 kHz with repeated ring wrapping
and draining, destination races/symlinks, a child-local disk-size limit, prefix
recovery and incomplete/missing asset reopening. `test-recovery` retains process
kill coverage; `test_audio` covers saturation and concurrent drain. This is
@ -224,7 +221,7 @@ claimed. Source files should remain unchanged during a session; reopen after
external replacement. Cache allocation failure omits previews without changing
music metadata.
`make test-audio-editing` verifies exact split/gain/fade playback, odd blocks,
`cmake --build build --target test-audio-editing` verifies exact split/gain/fade playback, odd blocks,
seeks, shortened media tails, one-frame files, source/project limits, capacity
rollback, duplication/fade inheritance, persistence/invalid metadata, undo, peak
bins after source removal and byte-identical source preservation. GUI tests

View file

@ -150,13 +150,13 @@ maps and physical recording-offset calibration remain unsupported.
## Verification and Listening
```
make all test gui test-reliability test-workflow test-gui test-gui-jack
make test-jack test-jack-audio test-jack-midi test-performance
make test-sanitize analyze
make quality-preview
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --parallel && cmake --build build --target check gui test-reliability test-workflow test-gui test-gui-jack
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-jack test-jack-audio test-jack-midi test-performance
cmake --build build --target test-sanitize analyze
cmake --build build --target quality-preview
```
`test_quality` is part of `make test`. It covers a sample-rate/tempo matrix up
`test_quality` is part of `cmake --build build --target check`. It covers a sample-rate/tempo matrix up
to 768 kHz and the maximum project tick, conversion errors, old/new tempo
snapshots for both audio and MIDI, exact offset/on/off order, sample boundary
behavior, raw versus faded endpoints, media ends shorter than rounded clip ends,
@ -174,8 +174,8 @@ the existing fontconfig-only suppression; core leak checks are unsuppressed.
Physical-device listening and human listening acceptance are **not yet
verified**.
`make quality-preview` writes ignored build artifacts `quality-raw.wav` and
`quality-smooth.wav` in BUILD_DIR using `examples/quality_preview.c`. Compare at
`cmake --build build --target quality-preview` writes ignored build artifacts `quality-raw.wav` and
`quality-smooth.wav` in the selected binary directory using `examples/quality_preview.c`. Compare at
moderate playback level: first listen to the three-note phrase endings, then the
constant clip at two seconds, then a mid-period tone stop near three seconds.
Check that fades reduce edge clicks, do not add noise and do not unexpectedly

View file

@ -1,325 +1,188 @@
# Build Baseline
# Building xtc with CMake
The existing layout is retained: public C headers in `include/xtc`, C
implementation modules under `src`, optional C++ GUI under `src/gui`, and tests
under `tests`. `src/main.c` is a minimal headless startup/shutdown check; it
does not initialize audio devices or open a GUI.
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
## Commands
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:
```sh
make clean all test
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel
ctest --test-dir build --output-on-failure
./build/xtc-check
make debug
make gui
./build/xtc # when FLTK was found
```
`all` builds the static C library and startup check. `test` runs the existing
core/offline tests, concurrent plan-handoff stress, JACK fault injection (when
JACK headers are available), and the startup check. `debug` builds and tests
separately in `build/debug`. `gui` builds the FLTK shell with backend controls
and status. The shell starts with a silent graph and never connects physical
ports. Generated files remain under `build` and header changes trigger rebuilds.
Compiler, flags, `BUILD_DIR`, `PKG_CONFIG`, `FLTK_CONFIG`, and installation
`PREFIX` can be overridden through Make variables. C uses C99; GUI uses C++17.
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.
## Inspected Linux Toolchain (2026-10-26)
Optional presets separate configurations:
| Component | Available version | Role |
```sh
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](../tests/integration/README.md).
## 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:
```sh
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 |
| --- | --- | --- |
| GCC / G++ | 16.2.1 | C core and optional C++ GUI |
| GNU Make | 4.4.1 | Build and test driver |
| pkg-config | 3.0.10 | Development package discovery |
| FLTK | 1.4.5 | Optional GUI; discovered through `fltk-config` |
| JACK | 3.1609.0 (pkg-config) | Optional JACK backend (PipeWire compatibility library) |
| ALSA | 1.2.16.1 (pkg-config) | Future MIDI candidate; not linked yet |
| Clang | 23.1.3 | Alternative compiler / diagnostics |
| `BUILD_TESTING` | `ON` | Build/register the test suite |
| `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 |
Valgrind is also available. The core tests use a small in-tree C test harness
and require no external test framework. FLTK has no `fltk.pc` on this host; the
Makefile tries pkg-config first, then `fltk-config`.
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`.
---
## Dependencies and Licensing
The offline core needs the C runtime and math library. Optional JACK support is
selected with pkg-config; missing JACK does not prevent core/tests from
building. Realtime publication uses GCC/Clang lock-free atomic builtins in C99.
Tests also use POSIX threads. Backend consumers must link JACK explicitly;
backend objects are pulled from the static library only when used. The
repository is MIT licensed. The optional GUI uses maintained FLTK 1.4 (LGPL with
FLTK's static-linking exception); its platform link flags come from the
installed package. Distribution still requires review of all linked dependencies
and notices. The installed PipeWire JACK library is MIT; traditional JACK client
libraries use LGPL licensing. See decision 0004 for the dependency choice and
caveats. ALSA remains a future MIDI candidate. No packages or system settings
are changed by these build commands.
---
## Backend Verification
A fully offline minimal configuration:
```sh
make all test gui debug
make test-jack
# Extended live run after building the integration binary:
./build/test_jack 30
# Verify optional build without JACK metadata, in a separate directory:
make BUILD_DIR=build/nojack PKG_CONFIG=false all test
# Address/undefined sanitizers (non-realtime tests only):
make BUILD_DIR=build/sanitize CC=clang CFLAGS='-O1 -g -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude -fsanitize=address,undefined -fno-omit-frame-pointer' LDFLAGS='-fsanitize=address,undefined' all test
# Thread sanitizer for publication/reclamation:
make BUILD_DIR=build/tsan CC=cc CFLAGS='-O1 -g -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude -fsanitize=thread' LDFLAGS='-fsanitize=thread' build/tsan/test_realtime
./build/tsan/test_realtime
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
```
Normal, sanitizer and no-JACK tests pass. ThreadSanitizer reports no race in
2,000 concurrent submissions. The 30-second live loopback test passed at 48 kHz
with zero xruns and ten restart cycles; see tests/integration/README.md. Live
server termination/format changes were not performed on the shared server;
fault-injection tests cover those notification paths. No packages installed or
system/device configuration changed. Sanitizers are not enabled in the live
callback qualification run.
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](LICENSES.md).
---
## Focused tests and tools
## GUI Shell Verification
Build before invoking CTest, or use `check`, which builds the test dependencies:
```sh
make clean all test gui debug test-gui test-gui-jack
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
```
`test-gui` needs Xvfb and `xvfb-run`, uses a fake C backend and requires no JACK
server. `test-gui-jack` needs a running server; it creates no physical routes.
Both passed, including repeated active-client close and reconnect. The GUI also
builds without JACK metadata and reports unsupported backend support at startup.
A live keyboard/visual smoke run passed under Xvfb. Clang ASan/UBSan GUI tests
passed with a suppression limited to the installed fontconfig library's
exit-time font allocations; see tests/integration/README.md for the distinction
and command. No compiler warnings remain with GCC or Clang. Core/backend tests
pass with unsuppressed ASan/UBSan. No packages or system configuration changed.
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](../screenshots/README.md). These commands assume configuration
has already completed; feature-specific docs use the same convention.
---
## Graph Editor Verification
To qualify live software routing against an **existing** JACK-compatible server:
```sh
make clean all test gui debug test-gui test-gui-jack
make BUILD_DIR=build/nojack PKG_CONFIG=false all test gui test-gui
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
```
The normal suite adds test_graph_edits for stable IDs, dense snapshots,
transactional rejection/deletion/disconnect and known rendered samples before
and after edits. Core/backend/realtime tests pass under unsuppressed Clang
ASan/UBSan; ThreadSanitizer passes the concurrent handoff test with revision-to-
gain checks. GUI ASan/UBSan tests pass with the existing fontconfig-only leak
suppression. Live GUI tests build a connected graph, adopt accepted edits during
playback, reject cycles, reconnect and close active clients. Mouse/visual smoke
checks cover node creation, wiring, cycle rejection, dragging and deletion. No
physical routes, new dependencies or system changes are introduced.
Live tests are serialized. They neither start/reconfigure the server nor
establish physical-device acceptance. See [AUDIO_ENGINE.md](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.
## Project Verification
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](JUCE.md) and [STEINBERG.md](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.
```sh
make clean all test gui debug test-gui test-gui-jack
make BUILD_DIR=build/nojack PKG_CONFIG=false all test gui test-gui
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
```
The suite adds test_project: track/clip limits, stable IDs, trims, integer
transport conversion, exact file roundtrip with graph rendering, exhaustive
fixture truncations, byte mutations, failed saves and temporary cleanup. GUI
tests cover region gestures, zoom, save/load and backend rollback. Live JACK
tests verify playhead advance, pause and resume without creating routes. The
updated core and GUI tests pass Clang ASan/UBSan (the GUI uses the existing
fontconfig-only LSan suppression). An Xvfb/xdotool visual check created a track
and region, moved it one bar and zoomed the canvas. No dependencies were added.
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.
Audio assets and recording are supported. Silent arrangement regions, fixed
tempo/4/4, no undo, no persisted GUI layout, and unverified physical-device
playback/endurance remain explicit limits.
`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](RELEASING.md) for layout/manifest details.
---
## Audio Verification
```sh
make all test gui debug test-gui test-gui-jack test-jack-audio
make BUILD_DIR=build/nojack PKG_CONFIG=false all test gui test-gui
make BUILD_DIR=build/tsan CC=cc CFLAGS='-O1 -g -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude -fsanitize=thread' LDFLAGS='-fsanitize=thread' build/tsan/test_audio build/tsan/test_realtime
./build/tsan/test_audio
./build/tsan/test_realtime
```
No new dependency is required for WAV import, recording or playback. New audio
sources remain C99; only GUI controls use C++/FLTK. test_audio covers decoder
samples, truncations/nonfinite/unsupported input, resampling, trim/overlap,
missing assets and concurrent recording. test_backend records known callback
input, saves/reopens and checks exact graph output. Project tests cover v1
migration and 1024 maximum-length asset paths in a valid v2 file.
The live test-jack-audio target connects only its software clients and checks
record -> WAV -> saved/reopened project -> graph playback. GUI/JACK tests also
record, finalize, save and reopen a take without hardware routing. Clang
ASan/UBSan passes the core and GUI tests (GUI retains the existing
fontconfig-only LSan suppression). ThreadSanitizer passes the concurrent
recorder and existing realtime handoff tests. Hardware capture/playback, disk
endurance and real server loss during recording remain unverified. See
AUDIO_FILES.md.
---
## MIDI Verification
```sh
make all test gui debug test-gui test-gui-jack test-jack-audio test-jack-midi
make BUILD_DIR=build/nojack PKG_CONFIG=false all test gui test-gui
```
`test_midi` adds exact sample scheduling, trim/seek/panic, block independence,
voice capacities, stable notes and v3 malformed-file/roundtrip/v2 migration
coverage. Backend fault injection checks event offsets, dropped/malformed input,
disconnection, xruns, missing output buffers and stop/restart cleanup. GUI tests
draw/move/resize notes, save/reopen and render them. The live MIDI target
connects only software clients and checks on/off, panic, disconnect, and
saved-note playback/seek. It needs an existing JACK-compatible server. No
hardware routes or system changes are made. MIDI recording/SMF and physical
devices are deferred.
A fresh `build/verify` build passed all targets above with no compiler warnings.
The no-JACK core/GUI suite and Clang ASan/UBSan core/GUI suite also passed; GUI
leak checking uses only the existing fontconfig suppression documented in the
integration README. Physical MIDI and audio devices remain unverified.
---
## Mixer Verification
```sh
make all test gui debug test-gui test-gui-jack test-jack-audio test-jack-midi
make BUILD_DIR=build/nojack PKG_CONFIG=false all test gui test-gui
```
`test_mixer` covers stereo gain/pan, mute/solo, sample automation, block
independence, WAV and graph routing, v4 persistence failures and bounded
history. GUI tests add automation mouse edits, mixer keys, history
rollback/branching and save/reopen. The existing live MIDI test now uses two
software capture ports and checks hard-right saved-note playback and output
meter snapshots; mono audio record/play acceptance remains covered. A native
Xvfb mouse smoke check confirms sliders and automation drawing. See MIXER.md for
capacities and deferred features.
The fresh verification build, no-JACK core/GUI suite and Clang ASan/UBSan
core/GUI suite passed without compiler warnings. GUI leak checking retains only
the existing fontconfig suppression. ThreadSanitizer also passed the recorder
concurrency and realtime publication tests. Physical devices and long-running
stereo performance remain unverified.
---
## Release Preparation
```sh
make all test gui debug test-gui test-gui-jack test-jack test-jack-audio test-jack-midi
make test-install test-recovery test-performance
make test-release
```
Core test now includes native ABI/lifecycle/retirement and the native-gain
example. Optional release tests use Python 3.12+ standard library, Git for
indexed source exports, GNU/LLVM deterministic ar and temporary directories. No
live prefix is installed. test-install checks core/GUI files, a prefix
containing spaces, headless CLI, pkg-config C/C++ consumers, exact/idempotent
uninstall and preservation of unrelated files. test-release compares two clean
exported optimized builds and repacked archives byte-for-byte. test-recovery
kills private child writers and forces a child-local write limit, checking
complete finalized destinations and explicit orphan temporaries. Performance
timings are reported, not used as a universal realtime guarantee. See
RELEASING.md, RECOVERY.md and PERFORMANCE.md.
Verification passed a fresh warning-enabled core/debug/GUI build, all software
JACK targets, staged install/uninstall, recovery and performance tests. No-JACK
core/GUI/install checks and Clang ASan/UBSan core/GUI checks also passed (the
GUI retains only its existing fontconfig leak suppression). TSan recorder and
realtime-handoff checks passed. Two independent optimized source exports and
their repacked source archives were byte-identical on this toolchain.
---
## Reliability Audit
Run `make test-reliability` for the core suites, allocation-failure sweep,
callback allocation/free guard and native reclamation checks. Run
`make test-sanitize` for Clang ASan/UBSan/leak checks and `make analyze` for
Clang static analysis of all core sources. These need installed development
tools; the allocation guard uses a GNU-compatible linker. See
[RELIABILITY.md](RELIABILITY.md) for ownership, audit findings, full
verification commands and remaining limits.
---
## Workflow Acceptance
`make test-workflow` requires FLTK/JACK development files, Xvfb and an existing
JACK-compatible server. It does not start/configure the server or connect
physical devices. See [WORKFLOW.md](WORKFLOW.md) for the full GUI composition
acceptance sequence and transport semantics.
---
## Audio Quality
`make test-quality` runs exact timing, source-boundary, gain-ramp, event-order
and numeric/layout tests (also included in `make test`). `make quality-preview`
builds the C example and writes raw/smoothed listening WAVs into BUILD_DIR
without playing them or configuring devices. See
[AUDIO_QUALITY.md](AUDIO_QUALITY.md).
Parameter-processor and plugin checks:
`make test-processor test-plugins test-gui-plugins`. The latter two need the
system LADSPA development header; real-plugin acceptance is separate
(`make test-plugins-real`, paths listed in PLUGIN_HOSTING.md). With no
`ladspa.h`, the ordinary core/GUI still builds and plugin operations return
UNSUPPORTED; existing plugin metadata can still be loaded/saved. To exercise
that configuration explicitly, use a fresh BUILD_DIR with
`CPPFLAGS=-DXTC_DISABLE_LADSPA JACK_AVAILABLE=`. No dependency is downloaded.
Link static consumers with `-lm -ldl` plus the backend dependencies when used.
See LICENSES.md for header/plugin licensing and decision 0009 for rationale.
Recording stress/recovery is available with `make test-recording`.
Developer qualification: `make check-development` runs the core build,
regressions, scale/virtual endurance, benchmark-gate checks, Clang analysis and
ASan/UBSan. Run `make benchmark benchmark-project` separately without contention
or sanitizers for timing reports. Optional `make test-stress-plugins` requires
installed LADSPA headers; `make test-stress` supports minimal builds too.
---
## Installation Layouts
`make test-install test-install-layout` verifies default and custom layouts in
throwaway staging directories, C/C++ installed consumers, examples and exact
removal. Override `PREFIX`, `exec_prefix`, `bindir`, `libdir`, `includedir`,
`datarootdir`, `datadir`, `docdir`, `pkgconfigdir`, `licensedir`, `examplesdir`
or `desktopdir` as needed. `DESTDIR` adds staging separately; pass the same
layout to uninstall. See RELEASING.md for commands and RELEASE_NOTES.md for
upgrades.
Modern plugin adapters build in C99 using the pinned header-only CLAP and VST3 C
APIs under third_party; there is no network build or SDK runtime. VST2
compatibility uses original ABI declarations. `make test-modern-plugins` runs
original shared-library fixtures without a server;
`make test-gui-modern-plugins` adds GUI/browser/undo/reopen tests under Xvfb.
The fixtures also run in `make test` and therefore in sanitizer/release builds.
Notices are installed with LICENSE.
The GUI uses a header-only FLTK theme and existing drawing primitives; no new
GUI dependency or generated asset is required. `make test-gui-instruments` also
exercises sidebar track creation, rollback, undo/reopen and minimum/large
layouts. See WORKSPACE.md for the default size and manual visual verification.
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.

View file

@ -38,7 +38,7 @@ fixed presets. Readers still accept formats 1–12. Older xtc builds reject form
allocation, file access, library loading, locking or GUI calls.
Validation:
`make BUILD_DIR=build/builtins all gui test test-gui-instruments test-gui-modern-plugins test-gui-plugins analyze`
`cmake --build build/builtins --parallel && cmake --build build/builtins --target gui check test-gui-instruments test-gui-modern-plugins test-gui-plugins analyze`
(join onto one line). `test-builtins` checks impulse tails, dry mix, feedback
bounds, block partition consistency, note release/panic and instrument/effect
project round trips.
@ -47,7 +47,7 @@ project round trips.
## Acceptance Checks
`make BUILD_DIR=build/builtin-acceptance all gui test test-reliability test-gui builtin-preview`
`cmake --build build/builtin-acceptance --parallel && cmake --build build/builtin-acceptance --target gui check test-reliability test-gui builtin-preview`
checks all four device identities and GUI paths without external plugin
binaries. The reliability runner fails each internal preparation allocation in
turn and forbids allocation/free, direct file I/O and blocking locks during
@ -57,7 +57,7 @@ cover voice exhaustion, sustain, repeated notes, partitioning and transport
reset/seek/panic. The existing portability suite verifies older project
migrations.
For repeatable manual listening, run `make builtin-preview` and audition
For repeatable manual listening, run `cmake --build build --target builtin-preview` and audition
`build/builtin-{0,1,2,3}.wav` at a conservative level: 0 is Soft Keys, 1 Sub
Bass, 2 Delay and 3 Reverb. Each six-second file includes held tones or two
impulses followed by silence for tails. Check onset/release, unwanted
@ -164,7 +164,7 @@ Tests compare whole/split blocks, tempo-synced impulse placement, left-to-right
energy, bounded extreme feedback/diffusion and graph/direct stereo output
(including the engine's subnormal-to-zero policy). GUI tests save/reopen both
identities; callback guards and ASan/UBSan cover processing.
`make builtin-preview` also writes files 5/6 for repeatable listening; human
`cmake --build build --target builtin-preview` also writes files 5/6 for repeatable listening; human
listening remains pending.
---

View file

@ -46,7 +46,7 @@ and the project tempo. Repeated render/save/reopen, odd block partition, exact
endpoints, seek/plan replacement, sustain/retrigger and controller ramp tests:
```sh
make test test-control test-plugins test-gui-plugins test-plugins-real
cmake --build build --target check test-control test-plugins test-gui-plugins test-plugins-real
```
Physical controller devices and listening remain unqualified; no tempo map,

View file

@ -106,7 +106,7 @@ edits do not request extra approval. No operation here deletes source media.
## Evidence and Manual Procedure
`make all test gui test-gui-plugins test-reliability analyze test-workflow test-gui-jack`
`cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --parallel && cmake --build build --target check gui test-gui-plugins test-reliability analyze test-workflow test-gui-jack`
covers core commands, grouped gestures/batches, backend rollback, selection
retention, take undo/redo and real software JACK state restoration. The GUI
fixture injects history-reservation failure before graph/map/import publication

View file

@ -61,10 +61,10 @@ process exit. Normal close/reconnect paths permit retry and release ownership
only after successful close. The entry point catches C++ exceptions before
process exit. Backend operations return C error codes throughout.
Tests: `make test-gui` runs real widgets/callbacks/timers against a fake C
Tests: `cmake --build build --target test-gui` runs real widgets/callbacks/timers against a fake C
backend under Xvfb, including control errors, startup without JACK, partially
initialized handles, server/format notifications, view switching, retrying
close, and timer removal. `make test-gui-jack` additionally requires a running
close, and timer removal. `cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-gui-jack` additionally requires a running
JACK-compatible server, tests repeated start/stop, reconnect and active-client
close, and creates no routes. Physical playback is outside this shell. See
BUILD.md and the integration test README for sanitizer limitations and keyboard
@ -214,7 +214,7 @@ finalizing a take (and is refused during recording). Home stops and returns to
zero. Failed candidate installation now refreshes the actual backend state even
when the previous document is retained.
`make test-workflow` uses a live JACK-compatible backend and Xvfb, with exact
`cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-workflow` uses a live JACK-compatible backend and Xvfb, with exact
stereo render comparisons across destruction/recreation of the GUI and live
playhead/meter/transport checks. `test-gui` covers stop/seek failure and
recording guards. No project files need manual editing for this workflow.

View file

@ -172,7 +172,7 @@ Adapt this to an existing repository instead of replacing it blindly.
xtc/
├── README.md
├── LICENSE
├── Makefile
├── CMakeLists.txt
├── docs/
│ ├── ARCHITECTURE.md
│ ├── AUDIO_ENGINE.md
@ -624,8 +624,8 @@ make an edit partially visible if it fails validation.
### Build system
Use a straightforward Makefile unless the existing repository has a sound reason
to use another build system.
Use the root CMake project and CTest. Keep SDK integrations optional and
all generated output in separate build directories.
The build must:
@ -736,7 +736,7 @@ feature is exciting.
### Repository and design baseline
- Inspect the repository and available toolchain.
- Create or update architecture documentation and the Makefile.
- Create or update architecture documentation and the CMake project.
- Verify C compiler, C++ compiler, FLTK, audio development headers, and test
tools.
- Record dependency and licensing decisions.
@ -851,7 +851,7 @@ Start with the **repository and design baseline** only.
development packages, `pkg-config`, and test tools.
3. Do not install packages or modify system configuration without permission.
4. Propose the smallest initial source tree compatible with this brief.
5. Add or update the Makefile and documentation only as needed.
5. Add or update the CMake project and documentation only as needed.
6. Create a minimal program that builds and exits cleanly; do not yet implement
a full audio engine or GUI.
7. Build it and run its tests.

View file

@ -17,8 +17,9 @@ normal builds or automatically installed. The integration uses:
Synthesis is the real xtc **Soft Keys** implementation, called through
`xtc_plugin_*`. C++ remains confined to the optional integration. The SDK build
uses a separate PIC build of the C archive with JACK/FLTK disabled; the installed
application and existing build directories are not modified.
links the root CMake PIC C archive through target dependencies; standalone SDK
configuration adds the same CMake core with JACK/FLTK disabled. SDK targets do
not install plugins or modify other binary directories.
## Screenshots
@ -43,10 +44,11 @@ before distributing those binaries. No SDK source or JUCE-linked binary is added
to the normal xtc install/package targets.
JUCE requires C++17 and its Linux development dependencies, including ALSA,
Fontconfig/FreeType and X11 libraries. CMake >= 3.25 and GNU Make build these
Fontconfig/FreeType and X11 libraries. CMake >= 3.25 and a backend such as Ninja build these
examples. Xvfb runs automated checks without a desktop. The SDK's `juceaide`
tool is compiled at configure time. Builds are substantially heavier than the
C-only core. Browser/network features are disabled; normal builds never fetch
C-only core. JUCE’s bundled codec C sources use GNU C11; the xtc core stays
strict C99. Browser/network features are disabled; normal builds never fetch
SDKs or install system packages. Only the inspected SDK revision has been
qualified; use the documented revision for reproducibility.

View file

@ -26,9 +26,11 @@ redistributing dependencies. The default install uses system shared libraries.
| HarfBuzz, Wayland, libdecor, xkbcommon | MIT-family licenses; check each shipped package. |
| X11 libraries | MIT/X11-family notices. |
| D-Bus | AFL-2.1 OR GPL-2.0-or-later. |
| Python 3 | PSF-2.0; optional build/test/package scripts use only the standard library. Not an application runtime dependency. |
| Python 3 | PSF-2.0; build/test/package scripts use only the standard library. Not an application runtime dependency. |
GNU Make, GCC/Clang, binutils, pkg-config and optional Xvfb/xdotool/sanitizers
CMake (BSD-3-Clause), a backend such as Ninja (Apache-2.0) or GNU Make
(GPL-3.0-or-later), GCC/Clang, binutils, pkg-config and optional
Xvfb/xdotool/sanitizers
are build/test tools, not shipped dependencies. New Python tooling needs Python
3.12+ for safe tar extraction in release tests; this host has Python 3.14.8. No
packages were installed and no application dependency was added.

View file

@ -1,15 +1,15 @@
# Linux Setup and Installation
Use a C99 compiler, C++17 compiler for the GUI, GNU Make, binutils and
Use a C99 compiler, C++17 compiler for the GUI, CMake 3.25+, a CMake backend, binutils and
pkg-config. The core needs only the C/math runtime. FLTK 1.4 development files
enable the GUI; JACK-compatible development files enable the optional audio/MIDI
backend. Packaging/install tests additionally use Python 3.12+ (standard library
only). No command starts a server, installs dependencies or changes system
backend. Build/test/install tooling uses Python 3.12+ (standard library only). No command starts a server, installs dependencies or changes system
settings.
```sh
make all test
make gui
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel
ctest --test-dir build --output-on-failure
./build/xtc
```
@ -31,17 +31,20 @@ files.
## Staged Installation
Core-only installation retains the original `make install` behavior and now adds
xtc-check, pkg-config metadata, license and documentation. install-gui adds the
GUI executable and desktop launcher. Defaults to PREFIX=/usr/local:
CMake installation includes the core, xtc-check, pkg-config metadata, licenses
and documentation. `XTC_INSTALL_GUI` defaults on when FLTK was found, adding the
application and desktop launcher. Use `-DXTC_INSTALL_GUI=OFF` for core-only
installation. The prefix defaults to `/usr/local`:
```sh
make install-gui DESTDIR="$PWD/build/stage" PREFIX=/usr
make uninstall DESTDIR="$PWD/build/stage" PREFIX=/usr
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr
cmake --build build --parallel
DESTDIR="$PWD/build/stage" cmake --install build
DESTDIR="$PWD/build/stage" cmake --build build --target uninstall
```
Review staged contents before using a package manager or choosing a writable
live prefix. For a user installation, use an absolute PREFIX such as
live prefix. For a user installation, use an absolute `CMAKE_INSTALL_PREFIX` such as
`$HOME/.local` and ensure its bin is in PATH. Prefixes containing spaces are
tested; shell metacharacters/newlines, quotes, dollar signs and backslashes are
not supported. No root installation is performed by tests. Uninstall from the
@ -59,15 +62,16 @@ C/C++ consumers use `pkg-config --cflags --libs --static xtc` plus the chosen
compiler; expose PREFIX/lib/pkgconfig through PKG_CONFIG_PATH when needed.
Static backend consumers need JACK if that optional backend was built; the pc
file records its private dependency. Public headers contain no JACK/FLTK types.
To build without optional libraries, set PKG_CONFIG=false FLTK_CONFIG=false.
To build without optional libraries, configure with `-DXTC_BUILD_GUI=OFF
-DXTC_WITH_JACK=OFF -DXTC_WITH_LADSPA=OFF`.
Python is not needed to run the installed executables or library.
---
## Binary/Development Archive
`make package` creates a system-linked Linux archive plus SHA-256 sidecar below
BUILD_DIR; `make test-package` verifies its contents. It includes usr/bin,
`cmake --build build --target package-binary` creates a system-linked Linux archive plus SHA-256 sidecar below
the selected binary directory; `cmake --build build --target test-package` verifies its contents. It includes usr/bin,
headers/static library/pkg-config metadata, desktop file (when FLTK is present),
manuals, baseline and MIT license. No shared library, third-party plugin, media,
service or dependency installer is bundled. `BINARY_MANIFEST.json` lists file
@ -80,8 +84,8 @@ extract the archive with two leading path components stripped
(`xtc-VERSION-linux- ARCH/usr`), placing bin/include/lib/share directly under
that prefix. Put its bin on PATH and lib/pkgconfig on PKG_CONFIG_PATH. The
archive's pkg-config prefix is relative to its installed location; normal
`make install` retains explicit PREFIX. Use the matching source's uninstall with
that PREFIX, or review the manifest before removing its files. Unknown/unrelated
`cmake --build build --target install` retains its configured prefix. Use the matching source's uninstall with
that prefix, or review the manifest before removing its files. Unknown/unrelated
files are retained by source uninstall. This local tar package is not a
pacman/RPM/deb registration or public distribution.
@ -90,5 +94,5 @@ without opening a server or executing a plugin. `xtc --diagnose` works
headlessly as well. Missing runtime GUI libraries are loader errors: install the
distribution's compatible dependencies or rebuild the core-only configuration.
Build without optional libraries using a fresh directory,
`PKG_CONFIG=false FLTK_CONFIG=false CPPFLAGS=-DXTC_DISABLE_LADSPA`. No system
`cmake -S . -B build/minimal -DXTC_BUILD_GUI=OFF -DXTC_WITH_JACK=OFF -DXTC_WITH_LADSPA=OFF`. No system
setting or package is changed by tests.

View file

@ -2,7 +2,7 @@
## Supported Development Target
Initial target: x86_64 Artix/Arch-family Linux with glibc, GNU Make, GCC/Clang,
Initial target: x86_64 Artix/Arch-family Linux with glibc, CMake 3.25+ and a backend such as Ninja, GCC/Clang,
FLTK 1.4 and a JACK-compatible client/server. The inspected host uses GCC
16.2.1, FLTK 1.4.5 and the dependencies in LICENSES.md.
Core-only/no-JACK/no-LADSPA builds are checked too. Build on the destination
@ -19,16 +19,16 @@ only. No dependency is fetched automatically.
bump, Git tag, public upload or external release is performed by local
targets.
2. Run warning-enabled
`make all test gui test-plugins test-plugins-real test-gui-plugins test-workflow test-gui-jack test-jack-midi test-recording test-recovery test-reliability test-scale analyze`
`cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --parallel && cmake --build build --target check gui test-plugins test-plugins-real test-gui-plugins test-workflow test-gui-jack test-jack-midi test-recording test-recovery test-reliability test-scale analyze`
where dependencies exist.
3. Use a separate BUILD_DIR for ASan/UBSan/leak runs and another for optional-
3. Use a separate CMake binary directory for ASan/UBSan/leak runs and another for optional-
dependency builds. GUI leak checks use only the documented fontconfig
suppression; core tests use none. Run publication/recording race tests as
described in RELIABILITY.md. Sanitizers are not latency qualification.
4. Run `make benchmark test-performance test-stress`; compare on matching
4. Run `cmake --build build --target benchmark test-performance test-stress`; compare on matching
host/compiler/flags against a reviewed baseline. Investigate regressions; do
not weaken thresholds or replace evidence without explanation.
5. Run `make test-install test-release test-package`. Inspect archive manifests,
5. Run `cmake --build build --target test-install test-release test-package`. Inspect archive manifests,
hashes, dynamic dependency names and licenses. Source exports rebuild twice
with identical artifacts on this host. Repeat binary packaging compares
bytes.

View file

@ -74,11 +74,11 @@ zoom yet. Note edits participate in project snapshot undo/redo.
## Verification
`make test` checks exact onset/off samples, block partition independence, trim,
`cmake --build build --target check` checks exact onset/off samples, block partition independence, trim,
seek, panic, channel handling, voice/event limits, persistence migration and
malformed files, plus callback fault recovery. `make test-gui` draws, moves and
malformed files, plus callback fault recovery. `cmake --build build --target test-gui` draws, moves and
resizes notes with FLTK events, then saves/reopens and renders them.
`make test-jack-midi` uses only software MIDI/audio ports to verify live on/off,
`cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-jack-midi` uses only software MIDI/audio ports to verify live on/off,
panic, disconnection and saved/reopened scheduled playback. JACK port discovery
may lag activation under PipeWire; the test waits before connecting. Physical
MIDI devices, bridge/device loss behind an unchanged port, latency and
@ -138,10 +138,10 @@ on/off/control messages execute in caller/JACK order, with no implicit priority
reordering. The renderer rejects malformed/unsorted/out-of-range events before
touching output or runtime; raw velocity-zero note-ons decode to note-off.
`make test-composition` covers filters, property preservation, triplet rounding,
`cmake --build build --target test-composition` covers filters, property preservation, triplet rounding,
repeats/fresh IDs, rejected batch rollback, capacity, undo snapshots,
equal-offset live order, adjacent/overlapping notes, exact block partitions and
seek chase. `make test-gui` covers mouse edits and the new commands with
seek chase. `cmake --build build --target test-gui` covers mouse edits and the new commands with
undo/redo and engine reinstallation. Listening and physical MIDI-device
validation remain pending.

View file

@ -124,8 +124,8 @@ The code is built with warnings enabled and tested. Reproduce the core,
transaction and allocation-failure checks with:
```sh
make BUILD_DIR=build/roadmap-audit all gui test-reliability
make BUILD_DIR=build/roadmap-audit test-gui-modern-editing
cmake --build build/roadmap-audit --parallel && cmake --build build/roadmap-audit --target gui test-reliability
cmake --build build/roadmap-audit --target test-gui-modern-editing
```
The full GUI, instrument/effect plugin fixtures, software JACK lifecycle, Clang

View file

@ -1,7 +1,7 @@
# Native C Processor API, Version 1
`xtc_native.h` defines a small compile-time extension boundary for trusted C99
sources, effects and instruments. Build `make build/native-gain` and run it for
sources, effects and instruments. Build `cmake --build build --target native-gain` and run it for
a complete graph-effect example in `examples/native_gain.c`. This is a source
API for this release, not a promise of binary compatibility across
builds/platforms. There is no module scanner, dynamic loader, SDK dependency or
@ -90,7 +90,7 @@ policy must precede serialized native extensions or external plugin hosting.
Tests cover ABI/size/field rejection, descriptor copying, aliased buffers,
prepare/process failures, stereo compile cleanup, retirement/destruction outside
processing, event offsets, seek note reset, source ports, instrument-buffer
graph routing and unsupported-save preservation. Run `make test`.
graph routing and unsupported-save preservation. Run `cmake --build build --target check`.
---
@ -99,7 +99,7 @@ graph routing and unsupported-save preservation. Run `make test`.
`xtc_processor.h` is the public C99 parameter-only extension interface (ABI 2).
It complements the ABI 1 graph adapter without changing its layout or behavior.
`examples/processors.c` implements a mono gain effect and a monophonic MIDI sine
instrument using only public headers; `make test-processor` builds and exercises
instrument using only public headers; `cmake --build build --target test-processor` builds and exercises
both. The instrument has immediate note-off and no voice stealing/release tail.
Descriptors have an exact ABI version and structure size, a persistent

View file

@ -41,7 +41,7 @@ termination remain unqualified.
## Matrix, Capacity and Contention Checks
`make benchmark` records 24 warmed graph cases: 2/16/64/256 nodes, mono/stereo,
`cmake --build build --target benchmark` records 24 warmed graph cases: 2/16/64/256 nodes, mono/stereo,
44.1k/31, 48k/128 and 96k/1024. Each reports control-thread compile time
separately from 300 process calls, mean/p99/max, block deadline, mean load, and
paired graph buffer bytes. Timing, sorting, allocation and logging happen
@ -51,10 +51,10 @@ CPU/compiler/flags/kernel and all measurements. Copy a new run only after
reviewing changes and conditions.
```sh
make benchmark test-performance test-scale test-stress
make benchmark-compare BENCHMARK_MAX_REGRESSION=1.5
cmake --build build --target benchmark test-performance test-scale test-stress
cmake -S . -B build -DXTC_BENCHMARK_MAX_REGRESSION=1.5 && cmake --build build --target benchmark-compare
# Select a baseline from this same host/compiler/flags:
make benchmark-compare BENCHMARK_BASELINE=/path/to/performance.json
cmake -S . -B build -DXTC_BENCHMARK_BASELINE=/path/to/performance.json && cmake --build build --target benchmark-compare
```
Comparison rejects mismatched CPU/architecture/compiler/flags or missing cases.
@ -64,7 +64,7 @@ Repeat surprising results under comparable load; do not silently replace the
baseline to make a regression disappear. Scheduling, clocks, thermal state and
shared-machine contention still affect results. No real-time scheduling/pinning
or external profiler is required. CPU-pressure runs are correctness checks, not
comparable timing baselines. Tests/benchmark outputs live below BUILD_DIR.
comparable timing baselines. Tests/benchmark outputs live below the selected binary directory.
Initial matrix (Threadripper 1920X, GCC 16.2.1, -O2, 300 blocks): 256-node
stereo 48k/128 mean 353.214 us, p99 396.495 us, load .132; 96k/1024 mean
@ -118,13 +118,13 @@ graph matrix separately scales nodes and chain connections from 2 to 256. These
synthetic cases do not qualify every possible dense graph or plugin chain.
```sh
make benchmark benchmark-project
make benchmark-compare
make benchmark-project-compare
cmake --build build --target benchmark benchmark-project
cmake --build build --target benchmark-compare
cmake --build build --target benchmark-project-compare
# Baselines must match the current CPU/compiler/flags and workload.
make benchmark-project-compare PROJECT_BENCHMARK_BASELINE=/path/to/report.json
cmake -S . -B build -DXTC_PROJECT_BENCHMARK_BASELINE=/path/to/report.json && cmake --build build --target benchmark-project-compare
./build/test_performance 10000 64 128
make test-benchmark-tools
cmake --build build --target test-benchmark-tools
```
Both matrices report wall-clock mean/p99/max processing duration and the count
@ -154,10 +154,10 @@ on machine timing. Do not replace a failing baseline without investigating.
## Endurance, Faults and Callback Audit
```sh
make test-soak test-stress test-stress-plugins
make test-stress STRESS_ROUNDS=10
cmake --build build --target test-soak test-stress test-stress-plugins
cmake -S . -B build -DXTC_STRESS_ROUNDS=10 && cmake --build build --target test-stress
./build/test_soak 10000000
make check-development
cmake --build build --target check-development
```
`test-soak` renders exactly 1,000,000 alternating 31/128/1,024-frame stereo
@ -210,7 +210,7 @@ introduced without a separate correctness/performance justification.
Reproduce in an isolated build (GNU gprof must already be installed):
```sh
make BUILD_DIR=build/profile CFLAGS='-O2 -g -pg -std=c99 -Iinclude' LDFLAGS=-pg build/profile/test_performance
cmake -S . -B build/profile -DCMAKE_C_FLAGS='-O2 -g -pg -std=c99 -Iinclude' -DCMAKE_EXE_LINKER_FLAGS=-pg && cmake --build build/profile --target test_performance
GMON_OUT_PREFIX="$PWD/build/profile/gmon" ./build/profile/test_performance 10000 64 128
gprof build/profile/test_performance build/profile/gmon.* > build/profile/profile.txt
```

View file

@ -92,8 +92,8 @@ binary/version identities.
## Repeatable Acceptance
```sh
make all test gui test-plugins test-gui-plugins analyze
make test-plugins-real
cmake --build build --parallel && cmake --build build --target check gui test-plugins test-gui-plugins analyze
cmake --build build --target test-plugins-real
```
The first plugin target builds an original MIT shared-library fixture with gain,
@ -269,8 +269,8 @@ inside the callback. CLAP process errors and VST3 failure results silence a
block. VST2 has no process error return.
```sh
make all test gui test-modern-plugins test-gui-modern-plugins
make test-sanitize analyze
cmake --build build --parallel && cmake --build build --target check gui test-modern-plugins test-gui-modern-plugins
cmake --build build --target test-sanitize analyze
```
Original CLAP/VST2/VST3 shared-library fixtures exercise exact in-place and

View file

@ -230,7 +230,7 @@ project Save intentionally replaces the selected document. In-memory models and
the existing destination are preserved on load failure. No automatic
unknown-field stripping or media deletion occurs.
`make test-portability test test-plugins test-recovery test-recording` covers
`cmake --build build --target test-portability check test-plugins test-recovery test-recording` covers
checked-in v1–v10 fixtures (including missing v5/v6 plugins), current exact
roundtrips, moved-folder playback from a different cwd, missing media retention,
unknown records, every truncation and deterministic byte mutations, malformed
@ -265,7 +265,7 @@ source references; splitting keeps the original ID on the left, gives the right
a fresh ID/source offset, retains outer explicit fades and clears inner ones. No
waveform cache or source audio is serialized. Checked-in v1–v7 migrations, v8
exact roundtrips, malformed new metadata and byte-mutation tests cover the
format change (`make test test-portability test-audio-editing`).
format change (`cmake --build build --target check test-portability test-audio-editing`).
---
@ -369,13 +369,13 @@ destination. Plugin binaries and state are not bundled. JACK availability,
sample rate, block limits and device routing are runtime dependencies; loading
metadata does not restore device connections.
`make test` includes v1–v10 migration, malformed/truncated/mutated/oversized
`cmake --build build --target check` includes v1–v10 migration, malformed/truncated/mutated/oversized
input, retained-state diagnostics, CLI dependency inspection, and deterministic
save faults at flush, file sync, close, rename and directory sync. Pre-rename
faults preserve the old bytes and remove the temporary. After rename, a sync
failure reports I/O while leaving a complete new document; inspect it before
retrying. Fault wrappers are linked into tests only. These tests complement
killed-writer coverage in `make test-recovery`; they do not qualify power-cut
killed-writer coverage in `cmake --build build --target test-recovery`; they do not qualify power-cut
behavior.
---

View file

@ -51,7 +51,7 @@ There is no autosave, crash journal, automatic orphan recovery or persisted Undo
history. Existing finalized files are protected against the tested process-level
failures; unsaved edits/in-flight takes can still be lost.
`make test-recovery` uses temporary directories and child processes only. It
`cmake --build build --target test-recovery` uses temporary directories and child processes only. It
forces an EFBIG-style write failure with a child-local file-size limit, kills
eight project writers while temporaries are visible, and kills a recorder after
draining but before finalization. Complete old/new destinations and explicit
@ -69,7 +69,7 @@ recorder recovery path before destruction, or use the GUI's reported path.
float32 WAV from complete on-disk frames, ignoring a trailing partial frame. It
never changes the source or overwrites an existing destination. This supersedes
the earlier lack of a WAV recovery tool described above. See AUDIO_FILES.md for
format/ownership/size limits and `make test-recording`.
format/ownership/size limits and `cmake --build build --target test-recording`.
---
@ -95,7 +95,7 @@ native plugin code; LADSPA has no runtime error-return channel.
## Save Diagnostics
`make test-project-diagnostics` deterministically injects flush, file-sync,
`cmake --build build --target test-project-diagnostics` deterministically injects flush, file-sync,
close, rename and directory-sync errors. Pre-rename failures retain the previous
bytes and clean temporary files. Post-rename sync errors leave a complete new
file and return failure; there is no rollback after replacement. Load

View file

@ -3,29 +3,32 @@
Source packaging, staged install/uninstall and repeatable builds are testable.
It does not turn the prototype into a production-qualified DAW. The version
remains 0.1.0; no tag, external release or binary publication is created by
`make dist` or `make release`.
`cmake --build build --target dist` or `cmake --build build --target release`.
---
## Build and Package
```sh
make release
make test-install
make test-recovery test-performance
make dist
make test-release
cmake --preset release
cmake --build --preset release --parallel
ctest --preset release
cmake --build build/release --target test-install test-install-layout
cmake --build build/release --target dist test-release
cmake --build build/release --target test-package
```
release builds optimized, warning-enabled C/C++ code, tests and the optional GUI
in BUILD_DIR/release with no debug paths, a source-prefix map, deterministic ar
metadata and FLTK include/define flags rather than distribution-specific LTO
flags. It retains assertions so the test harness actually runs. dist creates
BUILD_DIR/xtc-0.1.0.tar.gz using Python's standard library. It includes only Git
indexed regular files (working-tree contents, including staged new files), plus
a source manifest; stage intended files first and check `git diff --cached`.
Untracked files, ignored build output and .git are excluded. Exported archives
can reproduce themselves without Git using SOURCE_MANIFEST.json.
The release preset builds optimized, warning-enabled C/C++ code, test binaries
and the available GUI in `build/release`, with source/binary prefix maps,
no debug information, deterministic archive metadata and assertions retained.
FLTK discovery takes include/define flags without overriding the project's
optimization settings. `dist` creates `xtc-0.1.0.tar.gz` below the binary
directory using Python's standard library. It includes only Git-indexed regular
files (working-tree contents, including staged new files), plus a source
manifest; stage intended files first and check `git diff --cached`. Untracked
files, ignored build output and .git are excluded. Exported archives reproduce
themselves without Git using SOURCE_MANIFEST.json. The `test-release` tool uses
CMake and CTest in two independent exported trees, without invoking Make.
Archive order, permissions, ownership, gzip filename and timestamps are
normalized. SOURCE_DATE_EPOCH defaults to 0; set an unsigned 32-bit epoch
@ -34,8 +37,8 @@ from a clean checkout and record its commit/hash externally. Do not treat a
dirty-tree archive as an attested release. No artifact is uploaded by these
targets.
test-release unpacks the source into two different temporary paths, runs release
in each, compares libxtc.a/xtc-check/optional xtc SHA-256 values, and repacks
test-release unpacks the source into two different temporary paths, configures
a reproducible Release build and runs CTest in each, compares libxtc.a/xtc-check/optional xtc SHA-256 values, and repacks
each export to compare archive bytes. This verifies reproducibility for the same
host, compiler, flags and dependency versions. It does not promise bit-identical
output across distributions, compilers or library updates.
@ -66,11 +69,11 @@ shared-library extension ABI in this release.
## Local Binary Packaging and Installed Workflow
`make test-package` builds the release, stages installation only in a temporary
`cmake --build build/release --target test-package` uses the selected build and stages installation only in a temporary
DESTDIR, writes a normalized Linux binary/development archive, checks its
SHA-256 sidecar and per-file manifest, relocatable pkg-config paths and headless
commands. Same-host repeated packaging is byte-identical; dependency versions
and toolchain still determine binary compatibility. `make test-install` now
and toolchain still determine binary compatibility. `cmake --build build --target test-install` now
repeats installation to verify repair/upgrade of owned files while preserving an
unrelated sentinel, then compiles both C99 and C++17 installed consumers that
create MIDI, save/reopen and compare nonzero exact rendering. Removal remains
@ -88,21 +91,28 @@ pending.
## Release Workflow
Installation now shares one explicit file inventory with uninstallation.
GNU-style `exec_prefix`, `bindir`, `libdir`, `includedir`, `datarootdir`,
`datadir`, `docdir`, `pkgconfigdir` and the xtc-specific `licensedir`,
`examplesdir`, `desktopdir` can be overridden alongside `PREFIX`/`DESTDIR`.
Paths must be absolute POSIX paths; spaces are supported. Do not include DESTDIR
in a directory variable: staging is applied separately and never embedded in
pkg-config metadata. Staging refuses parent symlinks that escape DESTDIR. Use
exactly the same variables for removal.
Installation shares the existing explicit owned-file inventory with removal.
Use CMake's `CMAKE_INSTALL_PREFIX`, `CMAKE_INSTALL_BINDIR`,
`CMAKE_INSTALL_LIBDIR`, `CMAKE_INSTALL_INCLUDEDIR`, `CMAKE_INSTALL_DATAROOTDIR`
and `CMAKE_INSTALL_DOCDIR`. xtc-specific cache entries are
`XTC_INSTALL_LICENSEDIR`, `XTC_INSTALL_EXAMPLESDIR`, `XTC_INSTALL_DESKTOPDIR`
and `XTC_INSTALL_PKGCONFIGDIR`. Relative directories resolve beneath the prefix;
absolute directories are supported. Spaces work; control characters, quotes,
dollar signs, backslashes and `..` are rejected by the audited layout helper.
`DESTDIR` is a separate staging environment variable. The same cache and prefix
must be used for uninstall; a `cmake --install --prefix` override is temporary.
The internal `XTC_INSTALL_BUILD_DIR` setting lets packaging/test drivers stage
already-built inputs using a temporary configuration without modifying the
caller's cache. SDK products are never in this inventory.
```sh
make BUILD_DIR=build/release-check all test gui
make BUILD_DIR=build/release-check test-install test-install-layout
make PREFIX=/usr DESTDIR=/tmp/xtc-stage libdir=/usr/lib64 install-gui
make PREFIX=/usr DESTDIR=/tmp/xtc-stage libdir=/usr/lib64 uninstall
make test-release test-package
cmake -S . -B build/release-check -DCMAKE_BUILD_TYPE=Release \
-DXTC_REPRODUCIBLE=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib64
cmake --build build/release-check --parallel
ctest --test-dir build/release-check --output-on-failure
cmake --build build/release-check --target test-install test-install-layout
DESTDIR=/tmp/xtc-stage cmake --install build/release-check
DESTDIR=/tmp/xtc-stage cmake --build build/release-check --target uninstall
```
Core install includes the static library, public headers, `xtc-check`,
@ -114,7 +124,7 @@ metadata; custom live layouts are tested separately. Existing owned file
symlinks are replaced, not followed; installation is atomic per file, not a
transaction over the entire prefix.
`make dist` now writes a `.sha256` sidecar as well as the normalized source
`cmake --build build --target dist` now writes a `.sha256` sidecar as well as the normalized source
archive. Record that hash, the reviewed commit, version and build/dependency
conditions with release logs. `test-release` verifies the hash, builds/tests two
fresh source exports and compares artifacts and repacks. It validates exported

View file

@ -94,11 +94,11 @@ formal proof.
From the repository root:
```sh
make BUILD_DIR=build/audit all gui test-reliability test-recovery
make BUILD_DIR=build/audit test-sanitize
make analyze
make BUILD_DIR=build/audit test-gui test-gui-jack test-jack test-jack-audio test-jack-midi
make BUILD_DIR=build/nojack PKG_CONFIG=false all test-reliability gui
cmake --build build/audit --parallel && cmake --build build/audit --target gui test-reliability test-recovery
cmake --build build/audit --target test-sanitize
cmake --build build --target analyze
cmake -S . -B build/audit -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build/audit --target test-gui test-gui-jack test-jack test-jack-audio test-jack-midi
cmake -S . -B build/nojack -DXTC_WITH_JACK=OFF && cmake --build build/nojack --parallel && cmake --build build/nojack --target test-reliability gui
```
`test-sanitize` needs installed Clang and runs core, allocation-failure and
@ -141,10 +141,10 @@ stop/close handles faults or missing callbacks. See AUDIO_QUALITY.md.
## Repeatable Development Checks
`make check-development` combines normal tests, capacity/endurance,
`cmake --build build --target check-development` combines normal tests, capacity/endurance,
deterministic benchmark-gate tests, static analysis and ASan/UBSan (including
scale and soak). `make test-stress` repeats project/backend/publication faults
under CPU contention; `make test-stress-plugins` adds the original LADSPA
scale and soak). `cmake --build build --target test-stress` repeats project/backend/publication faults
under CPU contention; `cmake --build build --target test-stress-plugins` adds the original LADSPA
failure fixture. The reliability callback guard now also rejects common host
file I/O and blocking mutex/condition calls. It audits directly linked host
code, not arbitrary dynamic-plugin internals. See PERFORMANCE.md for exact

View file

@ -1,5 +1,9 @@
# Roadmap
Build commands in Phases 0–107 are historical qualification records from the
Makefile era. The current supported commands are in [BUILD.md](BUILD.md);
Phase 108 replaces that build with CMake and CTest.
## Phase 0 — Baseline
### Goal
@ -3500,6 +3504,77 @@ building JUCE's standalone wrapper does not establish hardware acceptance.
---
## Phase 108 — Complete CMake Build Migration
### Goal
Replace the hand-written root Makefile with a full CMake project and CTest,
preserving C99/C++17 boundaries, optional dependencies, SDK examples, fixtures,
developer tools and the audited installation/release workflows. This explicitly
requested build migration can proceed alongside remaining hardware/platform
qualification in earlier phases.
### Tasks and acceptance criteria
- [x] Define target-based core, CLI, GUI, example and plugin-fixture builds with
warnings, generated dependencies and optional JACK/FLTK/LADSPA discovery.
- [x] Register offline/unit/integration and GUI checks with CTest; keep live
JACK workflows opt-in and retain linker-based fault injection.
- [x] Provide separate debug/release/minimal/sanitizer presets, screenshot,
analysis, benchmark, stress and focused test targets.
- [x] Build optional Steinberg/JUCE SDK examples through root CMake; eliminate
JUCE's recursive Make dependency while retaining standalone SDK entry points.
- [x] Preserve staged install/uninstall, configurable layouts, pkg-config,
license inventory, reproducible source exports and binary-package checks.
- [x] Remove the root Makefile and update current documentation, examples,
third-party build guidance and agent instructions to use CMake/CTest.
- [x] Validate GNU Makefiles and Ninja, a minimal C-only build, GUI checks,
sanitizer tests, SDK interoperability and release/install/package workflows.
### Implementation status
Completed on 2026-11-06 with CMake 4.4.5, GCC 16.2.1, Clang 23.1.4 and
both Unix Makefiles and Ninja. The original build-rule Makefile was removed; see
[BUILD.md](BUILD.md), [RELEASING.md](RELEASING.md) and
[third-party guidance](../third_party/README.md).
Validation:
- Debug CMake build with JACK/FLTK: all 55 registered offline/GUI tests passed.
- Ninja Release build with GUI/JACK/LADSPA disabled: all 41 tests passed; the
configuration enabled only C, and `BUILD_TESTING=OFF` also built successfully.
- Clang ASan/UBSan: all 42 offline tests passed, including one million virtual
playback blocks. Clang static analysis passed for all C core sources.
- Default/custom staged install and removal, C/C++ installed pkg-config consumers,
symlink protection, prefix spaces and minimal/no-JACK installation passed.
Binary archive contents, hashes, relocation and repeat packaging passed.
- Two independent source-export Release builds (including the GUI and CTest)
produced byte-identical `libxtc.a`, `xtc-check`, `xtc` and repacked archives.
The check used an isolated temporary Git index to include the new CMake files
without staging the user's working index; normal `dist` still exports indexed
files as documented.
- Root Steinberg SDK build: host interoperability and official validator CTests
passed. Root JUCE build: all four C-host, file/editor, processor and JUCE-host
CTests passed. The standalone JUCE entry point also configured and built its
CMake core target successfully. The bridge does not invoke Make.
- CMake screenshot capture produced four actual creative-workflow images in the
ignored binary tree. Preview targets wrote the expected WAV files; graph and
project benchmark drivers ran successfully (timings were not used as a gate
while compilation was running). Three minimal-build CPU stress rounds passed.
- Five opt-in live JACK/workflow tests were registered and inspected; they were
not rerun as hardware acceptance. External SDK sources can emit upstream
warnings; the normal project builds were warning-free.
A subsequent user-requested convenience Makefile forwards configure/build,
CTest, GUI/run and clean commands to CMake. It has no compilation rules or source
inventory; CMake remains authoritative. See [quick shortcuts](BUILD.md#quick-make-shortcuts).
Historical validation above remains as recorded. This migration adds no
Windows/macOS, physical-device, native ASIO, or additional plugin-format
qualification.
---
## Recommended Execution Order
Reorder the phases when the audit reveals a blocking dependency. Do not mark a

View file

@ -102,12 +102,12 @@ public C snapshots/commands and never engine internals or callback storage.
## Verification and Limits
`make test-routing` checks branch reachability, external input, levels, capacity
rollback, exact unity-insertion rendering and complete plan handoff. `make test`
also retains concurrent publication/lifecycle tests. `make test-reliability`
retains the callback-allocation guards. `make test-gui-plugins` checks selection
`cmake --build build --target test-routing` checks branch reachability, external input, levels, capacity
rollback, exact unity-insertion rendering and complete plan handoff. `cmake --build build --target check`
also retains concurrent publication/lifecycle tests. `cmake --build build --target test-reliability`
retains the callback-allocation guards. `cmake --build build --target test-gui-plugins` checks selection
diagnostics, unique placement/layout, failed backend publication, atomic
insertion undo/redo and keyboard focus. `make test-gui-jack`
insertion undo/redo and keyboard focus. `cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-gui-jack`
inserts/disconnects/restores real routes during live software playback and
checks engine revision acknowledgements and cycle rejection.

View file

@ -25,6 +25,12 @@ check without adding a C++ runtime or network dependency to libxtc.
- The C render example demonstrates the actual xtc plugin facade and WAV writer,
including no-clobber output, without requiring JACK or a GUI.
Enable the root CMake integration with `-DXTC_BUILD_STEINBERG=ON` and
`-DXTC_VST3_SDK_ROOT=/path/to/vst3sdk`, build, then run
`ctest --test-dir build --output-on-failure -R steinberg`. Normal builds leave
the SDK option off. The example subdirectory also remains a standalone CMake
entry point for native SDK/ASIO diagnostics.
See [the example instructions](../examples/steinberg/README.md) for SDK versions,
build commands, validation and ASIO diagnostics.

View file

@ -86,7 +86,7 @@ host ownership and cleanup.
Reproduce focused verification with:
```sh
make BUILD_DIR=build/audio-editor test-track-fx test-gui-track-fx
cmake --build build/audio-editor --target test-track-fx test-gui-track-fx
XTC_TEST_HOST_VST3=1 ./build/audio-editor/test_track_fx
```

View file

@ -9,20 +9,21 @@ implied.
## Build or Install
Follow BUILD.md and LINUX.md. Core: `make all test`; GUI: `make gui`, then
Configure first with `cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug`; see
BUILD.md and LINUX.md. Core: `cmake --build build --parallel && cmake --build build --target check`; GUI: `cmake --build build --target gui`, then
`./build/xtc`. Use an existing JACK-compatible server and reconnect with F6.
Connect `midi_in` to a controller, `input` to mono capture and `output` /
`output_right` to left/right playback using your JACK routing application. No
server, physical routing or system configuration is changed automatically.
`xtc --version`, `xtc --help` and `xtc --diagnose` need no display/server.
For a source install stage with
`make install-gui DESTDIR="$PWD/build/stage" PREFIX=/usr`, inspect the stage,
and use your normal deployment process. A user prefix is supported (for example
an absolute path to your `.local` folder). `make uninstall` with the same
DESTDIR/PREFIX removes only that version's known files. See LINUX.md for package
extraction, dependencies and removal. Never use a release built for a different
system ABI without rebuilding/testing it.
For a source installation, configure `-DCMAKE_INSTALL_PREFIX=/usr`, build, then
stage with `DESTDIR="$PWD/build/stage" cmake --install build`. Inspect the stage
and use your normal deployment process. A user prefix such as an absolute path
to `.local` is also supported. Use `cmake --build build --target uninstall`
with the same DESTDIR and configured prefix for exact removal. See LINUX.md for
package extraction, dependencies and removal. Rebuild and test for the intended
system ABI before deployment.
---

View file

@ -86,7 +86,7 @@ With installed FLTK/JACK development files, Xvfb and an already running
JACK-compatible server:
```sh
make all test gui test-gui test-workflow test-gui-jack test-jack-midi
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --parallel && cmake --build build --target check gui test-gui test-workflow test-gui-jack test-jack-midi
```
`test-workflow` drives real GUI commands and timeline gestures under Xvfb. It
@ -148,7 +148,7 @@ A successful recorded take adds a reference as one undoable edit. Undo/removing
its region never deletes the WAV; recording failures retain their recovery path.
There is no destructive media-delete operation. New/Open reset history after
unsaved-change handling. The capacity limit and allocation-error reporting in
MIXER.md still apply. Tests: `make test-editing test-gui-plugins test-workflow`.
MIXER.md still apply. Tests: `cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-editing test-gui-plugins test-workflow`.
---

View file

@ -191,7 +191,7 @@ described below. The floating mixer resizes down to 600 × 420 and retains
horizontal track scrolling.
Verified with
`make BUILD_DIR=build/workspace-detach gui test-gui test-gui-instruments test-gui-jack`
`cmake -S . -B build/workspace-detach -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build/workspace-detach --target gui test-gui test-gui-instruments test-gui-jack`
(one line), plus the GUI suite under AddressSanitizer/UBSan. Tests cover
repeated reparenting, close-to-dock, resize, shared BPM/loop state, playback
shortcuts, failed shutdown and cleanup.