Migrated from Make to CMake.
This commit is contained in:
parent
cda05294f5
commit
b6ba093000
52 changed files with 1276 additions and 1210 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,5 +1,7 @@
|
||||||
# Build products
|
# Build products
|
||||||
/build/
|
/build/
|
||||||
|
/cmake-build-*/
|
||||||
|
/CMakeUserPresets.json
|
||||||
/*.o
|
/*.o
|
||||||
*.a
|
*.a
|
||||||
*.so
|
*.so
|
||||||
|
|
|
||||||
2
AGENT.md
2
AGENT.md
|
|
@ -28,7 +28,7 @@ This file is the working contract for AI-assisted development in this repository
|
||||||
|
|
||||||
## First task
|
## First task
|
||||||
|
|
||||||
Run `make clean all test`. Inspect compiler and `pkg-config` availability. Do not install packages or alter system configuration without permission. Report current state and propose the next smallest step.
|
Run `cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug`, `cmake --build build --parallel`, and `ctest --test-dir build --output-on-failure`. Inspect compiler and `pkg-config` availability. Do not install packages or alter system configuration without permission. Report current state and propose the next smallest step.
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
|
|
|
||||||
200
CMakeLists.txt
Normal file
200
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS include/xtc/xtc_version.h)
|
||||||
|
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/xtc/xtc_version.h" version_line REGEX "^#define XTC_VERSION_STRING")
|
||||||
|
string(REGEX MATCH "[0-9]+[.][0-9]+[.][0-9]+" XTC_VERSION "${version_line}")
|
||||||
|
project(xtc VERSION ${XTC_VERSION} LANGUAGES C)
|
||||||
|
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||||
|
message(FATAL_ERROR "Use an out-of-source build: cmake -S . -B build")
|
||||||
|
endif()
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
include(CTest)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
find_package(Python3 3.12 REQUIRED COMPONENTS Interpreter)
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
option(XTC_WITH_JACK "Discover the optional JACK backend" ON)
|
||||||
|
option(XTC_WITH_LADSPA "Enable LADSPA when its system header is available" ON)
|
||||||
|
option(XTC_BUILD_GUI "Build the FLTK application when FLTK is available" ON)
|
||||||
|
option(XTC_ENABLE_LIVE_TESTS "Register tests requiring an existing JACK server" OFF)
|
||||||
|
option(XTC_BUILD_JUCE "Build optional externally supplied JUCE examples" OFF)
|
||||||
|
option(XTC_BUILD_STEINBERG "Build optional externally supplied Steinberg examples" OFF)
|
||||||
|
option(XTC_SANITIZE "Enable address and undefined-behavior sanitizers" OFF)
|
||||||
|
option(XTC_REPRODUCIBLE "Remove source/build paths from optimized release artifacts" OFF)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_C_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
# Keep project warnings/assertions local; external SDKs control their own flags.
|
||||||
|
function(xtc_warnings target)
|
||||||
|
target_compile_options(${target} PRIVATE -Wall -Wextra -Wpedantic -UNDEBUG
|
||||||
|
"$<$<COMPILE_LANGUAGE:C>:-Wconversion;-Wshadow>")
|
||||||
|
endfunction()
|
||||||
|
if(XTC_SANITIZE)
|
||||||
|
add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
|
||||||
|
add_link_options(-fsanitize=address,undefined)
|
||||||
|
endif()
|
||||||
|
if(XTC_REPRODUCIBLE)
|
||||||
|
add_compile_options("-ffile-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=."
|
||||||
|
"-ffile-prefix-map=${CMAKE_CURRENT_BINARY_DIR}=build" -g0)
|
||||||
|
endif()
|
||||||
|
if(XTC_WITH_JACK AND PkgConfig_FOUND)
|
||||||
|
pkg_check_modules(JACK QUIET IMPORTED_TARGET jack)
|
||||||
|
endif()
|
||||||
|
add_library(xtc-core STATIC
|
||||||
|
src/plugin/module_path.c
|
||||||
|
src/midi/file.c
|
||||||
|
src/midi/output.c
|
||||||
|
src/project/crossfade.c
|
||||||
|
src/control/tempo.c
|
||||||
|
src/project/chain_tools.c
|
||||||
|
src/project/chain_preset.c
|
||||||
|
src/mixer/track_fx.c
|
||||||
|
src/audio/sample.c
|
||||||
|
src/persistence/collect.c
|
||||||
|
src/audio/normalize.c
|
||||||
|
src/project/sections.c
|
||||||
|
src/project/editing.c
|
||||||
|
src/audio/export.c
|
||||||
|
src/plugin/builtin.c
|
||||||
|
src/settings/settings.c
|
||||||
|
src/control/model.c
|
||||||
|
src/audio/waveform.c
|
||||||
|
src/plugin/ladspa.c
|
||||||
|
src/plugin/host.c
|
||||||
|
src/plugin/modern.c
|
||||||
|
src/native/processor.c
|
||||||
|
src/audio/recovery.c
|
||||||
|
src/dsp/ramp.c
|
||||||
|
src/native/native.c
|
||||||
|
src/mixer/model.c
|
||||||
|
src/mixer/render.c
|
||||||
|
src/project/history.c
|
||||||
|
src/midi/model.c
|
||||||
|
src/midi/instrument.c
|
||||||
|
src/audio/wave.c
|
||||||
|
src/audio/arrangement.c
|
||||||
|
src/audio/recorder.c
|
||||||
|
src/core/xtc.c
|
||||||
|
src/project/project.c
|
||||||
|
src/persistence/project_file.c
|
||||||
|
src/graph/graph.c
|
||||||
|
src/dsp/gain.c
|
||||||
|
src/engine/offline_engine.c
|
||||||
|
src/engine/realtime.c
|
||||||
|
src/backend/jack_backend.c
|
||||||
|
)
|
||||||
|
set_target_properties(xtc-core PROPERTIES OUTPUT_NAME xtc)
|
||||||
|
xtc_warnings(xtc-core)
|
||||||
|
add_library(xtc::core ALIAS xtc-core)
|
||||||
|
target_include_directories(xtc-core PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||||
|
target_include_directories(xtc-core SYSTEM PRIVATE third_party/clap/include third_party/vst3)
|
||||||
|
target_link_libraries(xtc-core PUBLIC m ${CMAKE_DL_LIBS} Threads::Threads)
|
||||||
|
if(JACK_FOUND AND XTC_WITH_JACK)
|
||||||
|
target_compile_definitions(xtc-core PRIVATE XTC_HAVE_JACK)
|
||||||
|
target_link_libraries(xtc-core PUBLIC PkgConfig::JACK)
|
||||||
|
endif()
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
check_include_file(ladspa.h XTC_HAVE_LADSPA_HEADER)
|
||||||
|
if(XTC_HAVE_LADSPA_HEADER AND XTC_WITH_LADSPA)
|
||||||
|
set(XTC_LADSPA_AVAILABLE TRUE)
|
||||||
|
endif()
|
||||||
|
if(NOT XTC_WITH_LADSPA)
|
||||||
|
target_compile_definitions(xtc-core PRIVATE XTC_DISABLE_LADSPA)
|
||||||
|
endif()
|
||||||
|
function(xtc_executable name source)
|
||||||
|
add_executable(${name} ${source} ${ARGN})
|
||||||
|
target_link_libraries(${name} PRIVATE xtc-core)
|
||||||
|
xtc_warnings(${name})
|
||||||
|
endfunction()
|
||||||
|
xtc_executable(xtc-check src/main.c)
|
||||||
|
xtc_executable(native-gain examples/native_gain.c)
|
||||||
|
xtc_executable(quality-preview-render examples/quality_preview.c)
|
||||||
|
set_target_properties(quality-preview-render PROPERTIES OUTPUT_NAME xtc-quality-preview)
|
||||||
|
xtc_executable(builtin-preview-render examples/builtin_preview.c)
|
||||||
|
set_target_properties(builtin-preview-render PROPERTIES OUTPUT_NAME xtc-builtin-preview)
|
||||||
|
foreach(preview quality builtin)
|
||||||
|
add_custom_target(${preview}-preview
|
||||||
|
COMMAND ${preview}-preview-render "${CMAKE_CURRENT_BINARY_DIR}/${preview}"
|
||||||
|
DEPENDS ${preview}-preview-render VERBATIM)
|
||||||
|
endforeach()
|
||||||
|
include(cmake/Tests.cmake)
|
||||||
|
include(cmake/Gui.cmake)
|
||||||
|
include(cmake/Developer.cmake)
|
||||||
|
include(cmake/Install.cmake)
|
||||||
|
if(XTC_BUILD_STEINBERG)
|
||||||
|
enable_language(CXX)
|
||||||
|
add_subdirectory(examples/steinberg steinberg-sdk)
|
||||||
|
xtc_executable(steinberg-render examples/steinberg/render.c)
|
||||||
|
add_custom_target(steinberg-sdk DEPENDS xtc-sdk-examples validator)
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
xtc_executable(test_steinberg_sdk tests/integration/test_steinberg_sdk.c)
|
||||||
|
set(steinberg_bundle "$<PATH:GET_PARENT_PATH,$<PATH:GET_PARENT_PATH,$<TARGET_FILE_DIR:xtc-sdk-examples>>>")
|
||||||
|
xtc_test(steinberg-sdk test_steinberg_sdk "${steinberg_bundle}")
|
||||||
|
add_test(NAME steinberg-validator COMMAND $<TARGET_FILE:validator> "${steinberg_bundle}")
|
||||||
|
set_tests_properties(steinberg-sdk steinberg-validator PROPERTIES LABELS sdk)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(XTC_BUILD_JUCE)
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
find_program(XTC_XVFB_RUN xvfb-run REQUIRED)
|
||||||
|
endif()
|
||||||
|
enable_language(CXX)
|
||||||
|
add_subdirectory(examples/juce juce)
|
||||||
|
add_custom_target(juce-examples DEPENDS xtc-juce-render XtcJuceSynth_VST3 XtcJuceSynth_Standalone)
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
xtc_executable(test_juce_plugin tests/integration/test_juce_plugin.c)
|
||||||
|
add_test(NAME juce-c-host COMMAND ${XTC_XVFB_RUN} -a $<TARGET_FILE:test_juce_plugin>
|
||||||
|
"$<PATH:GET_PARENT_PATH,$<PATH:GET_PARENT_PATH,$<TARGET_FILE_DIR:XtcJuceSynth_VST3>>>")
|
||||||
|
add_test(NAME juce-files-editor COMMAND ${XTC_XVFB_RUN} -a ${Python3_EXECUTABLE}
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/tests/integration/test_juce_examples.py" $<TARGET_FILE:xtc-juce-render>)
|
||||||
|
set_tests_properties(juce-c-host juce-files-editor PROPERTIES LABELS sdk)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" USES_TERMINAL)
|
||||||
|
get_property(xtc_build_targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
|
||||||
|
foreach(binary IN LISTS xtc_build_targets)
|
||||||
|
get_target_property(kind ${binary} TYPE)
|
||||||
|
if(kind MATCHES "^(EXECUTABLE|MODULE_LIBRARY|STATIC_LIBRARY)$" AND NOT binary STREQUAL capture_screenshots)
|
||||||
|
add_dependencies(check ${binary})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(XTC_BUILD_JUCE)
|
||||||
|
add_dependencies(check xtc-juce-render XtcJuceSynth_VST3 XtcJuceSynth_Standalone)
|
||||||
|
endif()
|
||||||
|
if(XTC_BUILD_STEINBERG)
|
||||||
|
add_dependencies(check xtc-sdk-examples validator)
|
||||||
|
endif()
|
||||||
|
get_property(xtc_tests DIRECTORY PROPERTY TESTS)
|
||||||
|
foreach(name IN LISTS xtc_tests)
|
||||||
|
if(NOT TARGET test-${name} AND NOT name STREQUAL steinberg-sdk)
|
||||||
|
add_custom_target(test-${name} COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R "^${name}$"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" USES_TERMINAL)
|
||||||
|
foreach(binary IN LISTS xtc_build_targets)
|
||||||
|
get_target_property(kind ${binary} TYPE)
|
||||||
|
if(kind MATCHES "^(EXECUTABLE|MODULE_LIBRARY|STATIC_LIBRARY)$" AND NOT binary STREQUAL capture_screenshots)
|
||||||
|
add_dependencies(test-${name} ${binary})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
include(cmake/Variants.cmake)
|
||||||
|
# Historical workflow names retained as CMake target aliases.
|
||||||
|
add_custom_target(test-builtins DEPENDS test-builtin)
|
||||||
|
if(XTC_BUILD_JUCE)
|
||||||
|
add_custom_target(test-juce COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R "juce"
|
||||||
|
DEPENDS xtc-juce-render XtcJuceSynth_VST3 XtcJuceSynth_Standalone test_juce_plugin USES_TERMINAL)
|
||||||
|
endif()
|
||||||
|
if(XTC_BUILD_STEINBERG)
|
||||||
|
add_custom_target(test-steinberg-sdk COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R steinberg
|
||||||
|
DEPENDS xtc-sdk-examples validator test_steinberg_sdk steinberg-render USES_TERMINAL)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
22
CMakePresets.json
Normal file
22
CMakePresets.json
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"version": 6,
|
||||||
|
"cmakeMinimumRequired": { "major": 3, "minor": 25, "patch": 0 },
|
||||||
|
"configurePresets": [
|
||||||
|
{ "name": "debug", "binaryDir": "${sourceDir}/build/debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } },
|
||||||
|
{ "name": "release", "binaryDir": "${sourceDir}/build/release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "XTC_REPRODUCIBLE": "ON" } },
|
||||||
|
{ "name": "minimal", "binaryDir": "${sourceDir}/build/minimal", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "XTC_BUILD_GUI": "OFF", "XTC_WITH_JACK": "OFF", "XTC_WITH_LADSPA": "OFF" } },
|
||||||
|
{ "name": "sanitize", "binaryDir": "${sourceDir}/build/sanitize", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "CMAKE_C_COMPILER": "clang", "XTC_BUILD_GUI": "OFF", "XTC_SANITIZE": "ON" } }
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{ "name": "debug", "configurePreset": "debug" },
|
||||||
|
{ "name": "release", "configurePreset": "release" },
|
||||||
|
{ "name": "minimal", "configurePreset": "minimal" },
|
||||||
|
{ "name": "sanitize", "configurePreset": "sanitize" }
|
||||||
|
],
|
||||||
|
"testPresets": [
|
||||||
|
{ "name": "debug", "configurePreset": "debug", "output": { "outputOnFailure": true } },
|
||||||
|
{ "name": "release", "configurePreset": "release", "output": { "outputOnFailure": true } },
|
||||||
|
{ "name": "minimal", "configurePreset": "minimal", "output": { "outputOnFailure": true } },
|
||||||
|
{ "name": "sanitize", "configurePreset": "sanitize", "output": { "outputOnFailure": true } }
|
||||||
|
]
|
||||||
|
}
|
||||||
689
Makefile
689
Makefile
|
|
@ -1,667 +1,46 @@
|
||||||
|
# Convenience shortcuts only; CMakeLists.txt owns the build.
|
||||||
.DEFAULT_GOAL := all
|
.DEFAULT_GOAL := all
|
||||||
|
# CMake handles parallel compilation; serialize separate wrapper goals.
|
||||||
|
.NOTPARALLEL:
|
||||||
|
|
||||||
CC ?= cc
|
CMAKE ?= cmake
|
||||||
CXX ?= c++
|
CTEST ?= ctest
|
||||||
PKG_CONFIG ?= pkg-config
|
|
||||||
FLTK_CONFIG ?= fltk-config
|
|
||||||
BUILD_DIR ?= build
|
BUILD_DIR ?= build
|
||||||
PREFIX ?= /usr/local
|
BUILD_TYPE ?= Debug
|
||||||
exec_prefix ?= $(PREFIX)
|
JOBS ?= 4
|
||||||
bindir ?= $(exec_prefix)/bin
|
CMAKE_ARGS ?=
|
||||||
libdir ?= $(exec_prefix)/lib
|
CTEST_ARGS ?=
|
||||||
includedir ?= $(PREFIX)/include
|
|
||||||
datarootdir ?= $(PREFIX)/share
|
|
||||||
datadir ?= $(datarootdir)
|
|
||||||
docdir ?= $(datarootdir)/doc/xtc
|
|
||||||
licensedir ?= $(datarootdir)/licenses/xtc
|
|
||||||
examplesdir ?= $(datadir)/xtc/examples
|
|
||||||
desktopdir ?= $(datadir)/applications
|
|
||||||
pkgconfigdir ?= $(libdir)/pkgconfig
|
|
||||||
INSTALL_LAYOUT = --prefix "$(PREFIX)" --destdir "$(DESTDIR)" --bindir "$(bindir)" --libdir "$(libdir)" --includedir "$(includedir)" --docdir "$(docdir)" --licensedir "$(licensedir)" --examplesdir "$(examplesdir)" --desktopdir "$(desktopdir)" --pkgconfigdir "$(pkgconfigdir)"
|
|
||||||
PYTHON ?= python3
|
|
||||||
VERSION := $(shell sed -n 's/^\#define XTC_VERSION_STRING "\([^"]*\)"/\1/p' include/xtc/xtc_version.h)
|
|
||||||
|
|
||||||
CFLAGS ?= -O2 -g
|
.PHONY: all build configure test check gui run clean help
|
||||||
CFLAGS += -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude
|
all: build
|
||||||
CXXFLAGS ?= -O2 -g
|
|
||||||
CXXFLAGS += -std=c++17 -Wall -Wextra -Wpedantic -Iinclude
|
|
||||||
LDFLAGS ?=
|
|
||||||
|
|
||||||
CORE_SOURCES := src/plugin/module_path.c src/midi/file.c src/midi/output.c src/project/crossfade.c src/control/tempo.c src/project/chain_tools.c src/project/chain_preset.c src/mixer/track_fx.c src/audio/sample.c src/persistence/collect.c src/audio/normalize.c src/project/sections.c src/project/editing.c src/audio/export.c src/plugin/builtin.c src/settings/settings.c src/control/model.c src/audio/waveform.c src/plugin/ladspa.c src/plugin/host.c src/plugin/modern.c src/native/processor.c src/audio/recovery.c src/dsp/ramp.c src/native/native.c src/mixer/model.c src/mixer/render.c src/project/history.c src/midi/model.c src/midi/instrument.c src/audio/wave.c src/audio/arrangement.c src/audio/recorder.c src/core/xtc.c src/project/project.c src/persistence/project_file.c src/graph/graph.c src/dsp/gain.c src/engine/offline_engine.c src/engine/realtime.c src/backend/jack_backend.c
|
configure:
|
||||||
JACK_AVAILABLE := $(shell $(PKG_CONFIG) --exists jack 2>/dev/null && echo yes)
|
$(CMAKE) -S . -B "$(BUILD_DIR)" -DCMAKE_BUILD_TYPE="$(BUILD_TYPE)" $(CMAKE_ARGS)
|
||||||
ifeq ($(JACK_AVAILABLE),yes)
|
|
||||||
JACK_CFLAGS := $(shell $(PKG_CONFIG) --cflags jack)
|
|
||||||
JACK_LIBS := $(shell $(PKG_CONFIG) --libs jack)
|
|
||||||
BACKEND_TEST := $(BUILD_DIR)/test_backend
|
|
||||||
$(BUILD_DIR)/tests/unit/test_backend.o: CPPFLAGS += $(JACK_CFLAGS)
|
|
||||||
$(BUILD_DIR)/src/core/xtc.o: CPPFLAGS += -DXTC_HAVE_JACK
|
|
||||||
$(BUILD_DIR)/src/backend/jack_backend.o: CPPFLAGS += -DXTC_HAVE_JACK $(JACK_CFLAGS)
|
|
||||||
endif
|
|
||||||
CORE_OBJECTS := $(CORE_SOURCES:%.c=$(BUILD_DIR)/%.o)
|
|
||||||
TEST_OBJECT := $(BUILD_DIR)/tests/unit/test_core.o
|
|
||||||
ifeq ($(shell $(PKG_CONFIG) --exists fltk 2>/dev/null && echo yes),yes)
|
|
||||||
FLTK_CXXFLAGS := $(shell $(PKG_CONFIG) --cflags fltk)
|
|
||||||
FLTK_LIBS := $(shell $(PKG_CONFIG) --libs fltk)
|
|
||||||
GUI_AVAILABLE := yes
|
|
||||||
else ifeq ($(shell $(FLTK_CONFIG) --version >/dev/null 2>&1 && echo yes),yes)
|
|
||||||
FLTK_CXXFLAGS := $(shell $(FLTK_CONFIG) --cxxflags)
|
|
||||||
FLTK_LIBS := $(shell $(FLTK_CONFIG) --ldflags)
|
|
||||||
GUI_AVAILABLE := yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: all clean test test-jack-midi test-jack-audio test-jack test-gui test-gui-jack debug gui install
|
build: configure
|
||||||
all: $(BUILD_DIR)/libxtc.a $(BUILD_DIR)/xtc-check
|
$(CMAKE) --build "$(BUILD_DIR)" --config "$(BUILD_TYPE)" --parallel "$(JOBS)"
|
||||||
|
|
||||||
$(BUILD_DIR)/xtc-check: $(BUILD_DIR)/src/main.o $(BUILD_DIR)/libxtc.a
|
test: build
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
$(CTEST) --test-dir "$(BUILD_DIR)" --build-config "$(BUILD_TYPE)" --output-on-failure $(CTEST_ARGS)
|
||||||
|
|
||||||
$(BUILD_DIR)/libxtc.a: $(CORE_OBJECTS)
|
check: test
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(AR) rcsD $@ $^
|
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.c
|
gui: configure
|
||||||
@mkdir -p $(@D)
|
$(CMAKE) --build "$(BUILD_DIR)" --config "$(BUILD_TYPE)" --target xtc --parallel "$(JOBS)"
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.cpp
|
run: gui
|
||||||
@mkdir -p $(@D)
|
"$(abspath $(BUILD_DIR))/xtc"
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(FLTK_CXXFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
$(TEST_OBJECT): tests/unit/test_core.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_core: $(TEST_OBJECT) $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $(TEST_OBJECT) $(BUILD_DIR)/libxtc.a -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_offline: $(BUILD_DIR)/tests/unit/test_offline.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_realtime: $(BUILD_DIR)/tests/unit/test_realtime.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl -pthread
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_backend: $(BUILD_DIR)/tests/unit/test_backend.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_graph_edits: $(BUILD_DIR)/tests/unit/test_graph_edits.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_project: $(BUILD_DIR)/tests/unit/test_project.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_audio: $(BUILD_DIR)/tests/unit/test_audio.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl -pthread
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_midi: $(BUILD_DIR)/tests/unit/test_midi.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_mixer: $(BUILD_DIR)/tests/unit/test_mixer.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_native: $(BUILD_DIR)/tests/unit/test_native.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/native-gain: $(BUILD_DIR)/examples/native_gain.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
test: test-modern-editing $(BUILD_DIR)/test_native $(BUILD_DIR)/native-gain $(BUILD_DIR)/test_mixer $(BUILD_DIR)/test_midi $(BUILD_DIR)/test_audio $(BUILD_DIR)/test_project $(BUILD_DIR)/test_graph_edits $(BACKEND_TEST) $(BUILD_DIR)/test_realtime $(BUILD_DIR)/test_core $(BUILD_DIR)/test_offline $(BUILD_DIR)/xtc-check
|
|
||||||
$(if $(BACKEND_TEST),./$(BACKEND_TEST),@echo "JACK fault tests skipped: JACK development files unavailable")
|
|
||||||
./$(BUILD_DIR)/test_native
|
|
||||||
./$(BUILD_DIR)/native-gain
|
|
||||||
./$(BUILD_DIR)/test_mixer
|
|
||||||
./$(BUILD_DIR)/test_midi
|
|
||||||
./$(BUILD_DIR)/test_audio
|
|
||||||
./$(BUILD_DIR)/test_project
|
|
||||||
./$(BUILD_DIR)/test_graph_edits
|
|
||||||
./$(BUILD_DIR)/test_realtime
|
|
||||||
./$(BUILD_DIR)/test_core
|
|
||||||
./$(BUILD_DIR)/test_offline
|
|
||||||
./$(BUILD_DIR)/xtc-check
|
|
||||||
|
|
||||||
debug:
|
|
||||||
$(MAKE) BUILD_DIR="$(BUILD_DIR)/debug" CFLAGS="$(CFLAGS) -O0 -g3" CXXFLAGS="$(CXXFLAGS) -O0 -g3" all test
|
|
||||||
|
|
||||||
ifeq ($(JACK_AVAILABLE),yes)
|
|
||||||
$(BUILD_DIR)/tests/integration/test_jack_midi.o: CPPFLAGS += $(JACK_CFLAGS)
|
|
||||||
$(BUILD_DIR)/test_jack_midi: $(BUILD_DIR)/tests/integration/test_jack_midi.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(JACK_LIBS) -lm -ldl
|
|
||||||
|
|
||||||
test-jack-midi: $(BUILD_DIR)/test_jack_midi
|
|
||||||
./$(BUILD_DIR)/test_jack_midi
|
|
||||||
|
|
||||||
$(BUILD_DIR)/tests/integration/test_jack_audio.o: CPPFLAGS += $(JACK_CFLAGS)
|
|
||||||
$(BUILD_DIR)/test_jack_audio: $(BUILD_DIR)/tests/integration/test_jack_audio.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(JACK_LIBS) -lm -ldl
|
|
||||||
|
|
||||||
test-jack-audio: $(BUILD_DIR)/test_jack_audio
|
|
||||||
./$(BUILD_DIR)/test_jack_audio
|
|
||||||
|
|
||||||
$(BUILD_DIR)/tests/integration/test_jack.o: CPPFLAGS += $(JACK_CFLAGS)
|
|
||||||
$(BUILD_DIR)/test_jack: $(BUILD_DIR)/tests/integration/test_jack.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(JACK_LIBS) -lm -ldl
|
|
||||||
|
|
||||||
test-jack: $(BUILD_DIR)/test_jack
|
|
||||||
./$(BUILD_DIR)/test_jack
|
|
||||||
else
|
|
||||||
test-jack-midi test-jack-audio test-jack:
|
|
||||||
@echo "JACK development files are required for the live integration test."
|
|
||||||
@exit 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(GUI_AVAILABLE),yes)
|
|
||||||
gui: $(BUILD_DIR)/xtc
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_gui: $(BUILD_DIR)/tests/integration/test_gui.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/src/gui/plugin_dialog.o $(BUILD_DIR)/src/gui/sample_editor.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) -lm -ldl -Wl,--wrap=xtc_history_reserve
|
|
||||||
|
|
||||||
test-gui: $(BUILD_DIR)/test_gui
|
|
||||||
xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
ifeq ($(JACK_AVAILABLE),yes)
|
|
||||||
$(BUILD_DIR)/test_gui_jack: $(BUILD_DIR)/tests/integration/test_gui_jack.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/src/gui/plugin_dialog.o $(BUILD_DIR)/src/gui/sample_editor.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) $(JACK_LIBS) -lm -ldl
|
|
||||||
|
|
||||||
test-gui-jack: $(BUILD_DIR)/test_gui_jack
|
|
||||||
xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui_jack
|
|
||||||
else
|
|
||||||
test-gui-jack:
|
|
||||||
@echo "JACK development files are required for the live GUI test."
|
|
||||||
@exit 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(BUILD_DIR)/xtc: $(BUILD_DIR)/src/gui/main.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/src/gui/plugin_dialog.o $(BUILD_DIR)/src/gui/sample_editor.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) $(JACK_LIBS) -lm -ldl
|
|
||||||
else
|
|
||||||
test-gui-jack test-gui:
|
|
||||||
@echo "FLTK development files are required for GUI tests."
|
|
||||||
@exit 1
|
|
||||||
|
|
||||||
gui:
|
|
||||||
@echo "FLTK was not found by pkg-config or fltk-config. GUI requires FLTK development files."
|
|
||||||
@exit 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
# install retains the core-only behavior; install-gui adds the application.
|
|
||||||
.PHONY: install uninstall install-gui dist release test-install test-release test-performance
|
|
||||||
$(BUILD_DIR)/xtc.pc: packaging/xtc.pc.in tools/pkgconfig.py tools/dist.py include/xtc/xtc_version.h FORCE
|
|
||||||
$(PYTHON) tools/pkgconfig.py --prefix "$(PREFIX)" --exec-prefix "$(exec_prefix)" --libdir "$(libdir)" --includedir "$(includedir)" --jack "$(if $(JACK_AVAILABLE),jack)" --output "$@"
|
|
||||||
.PHONY: FORCE
|
|
||||||
FORCE:
|
|
||||||
|
|
||||||
install: all $(BUILD_DIR)/xtc.pc
|
|
||||||
$(PYTHON) tools/install.py $(INSTALL_LAYOUT) --build-dir "$(BUILD_DIR)"
|
|
||||||
|
|
||||||
install-gui: install gui
|
|
||||||
$(PYTHON) tools/install.py $(INSTALL_LAYOUT) --build-dir "$(BUILD_DIR)" --gui
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
$(PYTHON) tools/uninstall.py $(INSTALL_LAYOUT)
|
|
||||||
|
|
||||||
dist:
|
|
||||||
$(PYTHON) tools/dist.py --output "$(BUILD_DIR)/xtc-$(VERSION).tar.gz"
|
|
||||||
|
|
||||||
release:
|
|
||||||
$(MAKE) BUILD_DIR="$(BUILD_DIR)/release" CFLAGS="-O2 -g0 -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude -ffile-prefix-map=$(CURDIR)=." CXXFLAGS="-O2 -g0 -std=c++17 -Wall -Wextra -Wpedantic -Iinclude -ffile-prefix-map=$(CURDIR)=." FLTK_CXXFLAGS="$(filter -I% -D% -pthread,$(FLTK_CXXFLAGS))" all test $(if $(GUI_AVAILABLE),gui)
|
|
||||||
|
|
||||||
test-install: all $(if $(GUI_AVAILABLE),gui)
|
|
||||||
$(PYTHON) tests/integration/test_install.py --build-dir "$(abspath $(BUILD_DIR))" $(if $(GUI_AVAILABLE),--gui)
|
|
||||||
|
|
||||||
test-release: dist
|
|
||||||
$(PYTHON) tests/integration/test_release.py "$(BUILD_DIR)/xtc-$(VERSION).tar.gz" $(if $(GUI_AVAILABLE),--gui)
|
|
||||||
|
|
||||||
|
# Keep the CMake cache; never recursively delete a caller-supplied path.
|
||||||
clean:
|
clean:
|
||||||
rm -rf "$(BUILD_DIR)"
|
@if [ -f "$(BUILD_DIR)/CMakeCache.txt" ]; then \
|
||||||
|
$(CMAKE) --build "$(BUILD_DIR)" --config "$(BUILD_TYPE)" --target clean; \
|
||||||
-include $(CORE_OBJECTS:.o=.d) $(TEST_OBJECT:.o=.d) $(BUILD_DIR)/src/main.d $(BUILD_DIR)/tests/unit/test_offline.d $(BUILD_DIR)/tests/unit/test_realtime.d $(BUILD_DIR)/tests/unit/test_backend.d $(BUILD_DIR)/tests/unit/test_graph_edits.d \
|
fi
|
||||||
$(BUILD_DIR)/src/gui/main.d $(BUILD_DIR)/src/gui/main_window.d $(BUILD_DIR)/src/gui/graph_widget.d $(BUILD_DIR)/src/gui/sequencer_widget.d $(BUILD_DIR)/src/gui/piano_roll.d $(BUILD_DIR)/tests/integration/test_jack.d $(BUILD_DIR)/tests/integration/test_gui.d $(BUILD_DIR)/tests/integration/test_gui_jack.d
|
|
||||||
|
help:
|
||||||
-include $(BUILD_DIR)/tests/unit/test_project.d
|
@echo 'make [build] Configure and compile (default)'
|
||||||
|
@echo 'make configure Configure only'
|
||||||
-include $(BUILD_DIR)/tests/unit/test_audio.d
|
@echo 'make test Build, then run CTest (check is an alias)'
|
||||||
|
@echo 'make gui/run Build the FLTK app / build and launch it'
|
||||||
-include $(BUILD_DIR)/tests/integration/test_jack_audio.d
|
@echo 'make clean Clean products, retaining the CMake cache'
|
||||||
|
@echo 'Overrides: BUILD_DIR=build BUILD_TYPE=Debug JOBS=4 CMAKE_ARGS=... CTEST_ARGS=...'
|
||||||
-include $(BUILD_DIR)/tests/unit/test_midi.d
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_jack_midi.d
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/src/gui/mixer_widget.d
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_mixer.d
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_native.d $(BUILD_DIR)/examples/native_gain.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_performance: $(BUILD_DIR)/tests/integration/test_performance.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_recovery: $(BUILD_DIR)/tests/integration/test_recovery.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
.PHONY: test-recovery
|
|
||||||
test-performance: $(BUILD_DIR)/test_performance
|
|
||||||
./$(BUILD_DIR)/test_performance
|
|
||||||
|
|
||||||
test-recovery: $(BUILD_DIR)/test_recovery
|
|
||||||
./$(BUILD_DIR)/test_recovery
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_performance.d $(BUILD_DIR)/tests/integration/test_recovery.d
|
|
||||||
|
|
||||||
# Linux/GNU-compatible linker test; no instrumentation in production objects.
|
|
||||||
$(BUILD_DIR)/test_reliability: $(BUILD_DIR)/tests/integration/test_reliability.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl -Wl,--wrap=malloc,--wrap=calloc,--wrap=realloc,--wrap=free,--wrap=fopen,--wrap=fread,--wrap=fwrite,--wrap=read,--wrap=write,--wrap=pthread_mutex_lock,--wrap=pthread_cond_wait -pthread
|
|
||||||
|
|
||||||
.PHONY: test-reliability test-sanitize analyze
|
|
||||||
test-reliability: test $(BUILD_DIR)/test_reliability
|
|
||||||
./$(BUILD_DIR)/test_reliability
|
|
||||||
|
|
||||||
test-sanitize:
|
|
||||||
ASAN_OPTIONS=detect_leaks=1:halt_on_error=1 UBSAN_OPTIONS=halt_on_error=1 $(MAKE) BUILD_DIR="$(BUILD_DIR)/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" test-reliability test-recovery test-scale test-soak
|
|
||||||
|
|
||||||
analyze:
|
|
||||||
$(PYTHON) tools/analyze.py $(CORE_SOURCES)
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_reliability.d
|
|
||||||
|
|
||||||
.PHONY: test-workflow
|
|
||||||
ifeq ($(GUI_AVAILABLE)$(JACK_AVAILABLE),yesyes)
|
|
||||||
$(BUILD_DIR)/test_workflow: $(BUILD_DIR)/tests/integration/test_workflow.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/src/gui/plugin_dialog.o $(BUILD_DIR)/src/gui/sample_editor.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) $(JACK_LIBS) -lm -ldl
|
|
||||||
|
|
||||||
test-workflow: $(BUILD_DIR)/test_workflow
|
|
||||||
xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_workflow
|
|
||||||
else
|
|
||||||
test-workflow:
|
|
||||||
@echo "FLTK and JACK development files are required for the workflow test."
|
|
||||||
@exit 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_workflow.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_quality: $(BUILD_DIR)/tests/unit/test_quality.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-quality
|
|
||||||
test-quality: $(BUILD_DIR)/test_quality
|
|
||||||
./$(BUILD_DIR)/test_quality
|
|
||||||
test: test-quality
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_quality.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/quality-preview: $(BUILD_DIR)/examples/quality_preview.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: quality-preview
|
|
||||||
quality-preview: $(BUILD_DIR)/quality-preview
|
|
||||||
./$(BUILD_DIR)/quality-preview "$(abspath $(BUILD_DIR))/quality"
|
|
||||||
-include $(BUILD_DIR)/examples/quality_preview.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_recording: $(BUILD_DIR)/tests/integration/test_recording.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-recording
|
|
||||||
test-recording: $(BUILD_DIR)/test_recording
|
|
||||||
./$(BUILD_DIR)/test_recording
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_recording.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_processor: $(BUILD_DIR)/tests/unit/test_processor.o $(BUILD_DIR)/examples/processors.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-processor
|
|
||||||
test-processor: $(BUILD_DIR)/test_processor
|
|
||||||
./$(BUILD_DIR)/test_processor
|
|
||||||
test: test-processor
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_processor.d $(BUILD_DIR)/examples/processors.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/plugin-fixture.so: tests/plugins/fixture.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -shared -o $@ $<
|
|
||||||
$(BUILD_DIR)/test_plugins: $(BUILD_DIR)/tests/integration/test_plugins.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl -Wl,--wrap=malloc,--wrap=calloc,--wrap=realloc,--wrap=free,--wrap=dlopen,--wrap=dlclose
|
|
||||||
.PHONY: test-plugins test-plugins-real
|
|
||||||
test-plugins: $(BUILD_DIR)/test_plugins $(BUILD_DIR)/plugin-fixture.so
|
|
||||||
./$(BUILD_DIR)/test_plugins "$(abspath $(BUILD_DIR))/plugin-fixture.so" fixture
|
|
||||||
test-plugins-real: $(BUILD_DIR)/test_plugins
|
|
||||||
./$(BUILD_DIR)/test_plugins /usr/lib/ladspa/amp.so
|
|
||||||
./$(BUILD_DIR)/test_plugins /usr/lib/ladspa/inv_1429.so
|
|
||||||
./$(BUILD_DIR)/test_plugins /usr/lib/ladspa/sine.so 3
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_plugins.d
|
|
||||||
|
|
||||||
.PHONY: test-gui-plugins
|
|
||||||
test-gui-plugins: $(BUILD_DIR)/test_gui $(BUILD_DIR)/plugin-fixture.so
|
|
||||||
XTC_TEST_PLUGIN="$(abspath $(BUILD_DIR))/plugin-fixture.so" xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_control: $(BUILD_DIR)/tests/unit/test_control.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-control
|
|
||||||
test-control: $(BUILD_DIR)/test_control
|
|
||||||
./$(BUILD_DIR)/test_control
|
|
||||||
test: test-control
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_control.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_editing: $(BUILD_DIR)/tests/unit/test_editing.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-editing
|
|
||||||
test-editing: $(BUILD_DIR)/test_editing
|
|
||||||
./$(BUILD_DIR)/test_editing
|
|
||||||
test: test-editing
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_editing.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_portability: $(BUILD_DIR)/tests/integration/test_portability.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-portability
|
|
||||||
test-portability: $(BUILD_DIR)/test_portability
|
|
||||||
./$(BUILD_DIR)/test_portability
|
|
||||||
test: test-portability
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_portability.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/benchmark_graph: $(BUILD_DIR)/tests/integration/benchmark_graph.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: benchmark
|
|
||||||
benchmark: $(BUILD_DIR)/benchmark_graph
|
|
||||||
$(PYTHON) tools/benchmark.py --binary "$(BUILD_DIR)/benchmark_graph" --output "$(BUILD_DIR)/performance.json" --compiler "$(CC)" --flags "$(CFLAGS)" --blocks "$(BENCHMARK_BLOCKS)"
|
|
||||||
-include $(BUILD_DIR)/tests/integration/benchmark_graph.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_scale: $(BUILD_DIR)/tests/integration/test_scale.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-scale test-stress
|
|
||||||
test-scale: $(BUILD_DIR)/test_scale
|
|
||||||
./$(BUILD_DIR)/test_scale
|
|
||||||
test-stress: $(BUILD_DIR)/test_realtime $(BUILD_DIR)/test_reliability $(BUILD_DIR)/test_scale $(if $(GUI_AVAILABLE),$(BUILD_DIR)/test_gui)
|
|
||||||
$(PYTHON) tools/stress.py --build-dir "$(BUILD_DIR)" --rounds "$(STRESS_ROUNDS)" $(if $(GUI_AVAILABLE),--gui)
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_scale.d
|
|
||||||
|
|
||||||
BENCHMARK_BLOCKS ?= 300
|
|
||||||
BENCHMARK_BASELINE ?= docs/performance-baseline.json
|
|
||||||
BENCHMARK_MAX_REGRESSION ?= 1.5
|
|
||||||
.PHONY: benchmark-compare
|
|
||||||
benchmark-compare: $(BUILD_DIR)/benchmark_graph
|
|
||||||
$(PYTHON) tools/benchmark.py --binary "$(BUILD_DIR)/benchmark_graph" --output "$(BUILD_DIR)/performance.json" --compiler "$(CC)" --flags "$(CFLAGS)" --blocks "$(BENCHMARK_BLOCKS)" --baseline "$(BENCHMARK_BASELINE)" --max-regression "$(BENCHMARK_MAX_REGRESSION)"
|
|
||||||
|
|
||||||
PACKAGE_ARCH := $(shell uname -m)
|
|
||||||
PACKAGE_FILE := $(BUILD_DIR)/xtc-$(VERSION)-linux-$(PACKAGE_ARCH).tar.gz
|
|
||||||
.PHONY: package test-package
|
|
||||||
package: release
|
|
||||||
$(PYTHON) tools/package.py --build-dir "$(BUILD_DIR)/release" --output "$(PACKAGE_FILE)" $(if $(GUI_AVAILABLE),--gui)
|
|
||||||
test-package: package
|
|
||||||
$(PYTHON) tests/integration/test_package.py "$(PACKAGE_FILE)" --build-dir "$(BUILD_DIR)/release"
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_composition: $(BUILD_DIR)/tests/unit/test_composition.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-composition
|
|
||||||
test-composition: $(BUILD_DIR)/test_composition
|
|
||||||
./$(BUILD_DIR)/test_composition
|
|
||||||
test: test-composition
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_composition.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_audio_editing: $(BUILD_DIR)/tests/unit/test_audio_editing.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-audio-editing
|
|
||||||
test-audio-editing: $(BUILD_DIR)/test_audio_editing
|
|
||||||
./$(BUILD_DIR)/test_audio_editing
|
|
||||||
test: test-audio-editing
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_audio_editing.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_routing: $(BUILD_DIR)/tests/unit/test_routing.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-routing
|
|
||||||
test-routing: $(BUILD_DIR)/test_routing
|
|
||||||
./$(BUILD_DIR)/test_routing
|
|
||||||
test: test-routing
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_routing.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_buses: $(BUILD_DIR)/tests/unit/test_buses.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-buses
|
|
||||||
test-buses: $(BUILD_DIR)/test_buses
|
|
||||||
./$(BUILD_DIR)/test_buses
|
|
||||||
test: test-buses
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_buses.d
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/src/gui/plugin_dialog.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_parameters: $(BUILD_DIR)/tests/unit/test_parameters.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-parameters
|
|
||||||
test-parameters: $(BUILD_DIR)/test_parameters
|
|
||||||
./$(BUILD_DIR)/test_parameters
|
|
||||||
test: test-parameters
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_parameters.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_project_diagnostics: $(BUILD_DIR)/tests/unit/test_project_diagnostics.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl -Wl,--wrap=fflush,--wrap=fclose,--wrap=fsync,--wrap=rename
|
|
||||||
.PHONY: test-project-diagnostics
|
|
||||||
test-project-diagnostics: $(BUILD_DIR)/test_project_diagnostics
|
|
||||||
./$(BUILD_DIR)/test_project_diagnostics
|
|
||||||
test: test-project-diagnostics
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_project_diagnostics.d
|
|
||||||
|
|
||||||
.PHONY: test-project-inspection
|
|
||||||
test-project-inspection: $(BUILD_DIR)/xtc-check
|
|
||||||
$(PYTHON) tests/integration/test_project_inspection.py $(BUILD_DIR)/xtc-check
|
|
||||||
test: test-project-inspection
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_soak: $(BUILD_DIR)/tests/integration/test_soak.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-soak benchmark-project benchmark-project-compare check-development
|
|
||||||
test-soak: $(BUILD_DIR)/test_soak
|
|
||||||
./$(BUILD_DIR)/test_soak
|
|
||||||
PROJECT_BENCHMARK_BASELINE ?= docs/project-performance-baseline.json
|
|
||||||
STRESS_ROUNDS ?= 3
|
|
||||||
test-stress: $(BUILD_DIR)/test_portability $(BUILD_DIR)/test_project_diagnostics $(BUILD_DIR)/test_soak $(BACKEND_TEST)
|
|
||||||
benchmark-project: $(BUILD_DIR)/test_performance
|
|
||||||
$(PYTHON) tools/benchmark.py --workload project --binary "$(BUILD_DIR)/test_performance" --output "$(BUILD_DIR)/project-performance.json" --compiler "$(CC)" --flags "$(CFLAGS)" --blocks "$(BENCHMARK_BLOCKS)"
|
|
||||||
benchmark-project-compare: $(BUILD_DIR)/test_performance
|
|
||||||
$(PYTHON) tools/benchmark.py --workload project --binary "$(BUILD_DIR)/test_performance" --output "$(BUILD_DIR)/project-performance.json" --compiler "$(CC)" --flags "$(CFLAGS)" --blocks "$(BENCHMARK_BLOCKS)" --baseline "$(PROJECT_BENCHMARK_BASELINE)" --max-regression "$(BENCHMARK_MAX_REGRESSION)"
|
|
||||||
check-development: all test-reliability test-scale test-soak analyze test-sanitize
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_soak.d
|
|
||||||
.PHONY: test-benchmark-tools
|
|
||||||
test-benchmark-tools:
|
|
||||||
$(PYTHON) tests/tools/test_benchmark.py
|
|
||||||
check-development: test-benchmark-tools
|
|
||||||
|
|
||||||
.PHONY: test-stress-plugins
|
|
||||||
test-stress-plugins: $(BUILD_DIR)/test_realtime $(BUILD_DIR)/test_reliability $(BUILD_DIR)/test_scale $(BUILD_DIR)/test_portability $(BUILD_DIR)/test_project_diagnostics $(BUILD_DIR)/test_soak $(BACKEND_TEST) $(BUILD_DIR)/test_plugins $(BUILD_DIR)/plugin-fixture.so
|
|
||||||
$(PYTHON) tools/stress.py --build-dir "$(BUILD_DIR)" --rounds "$(STRESS_ROUNDS)" --plugin "$(BUILD_DIR)/plugin-fixture.so"
|
|
||||||
|
|
||||||
.PHONY: test-install-layout
|
|
||||||
test-install-layout: all $(if $(GUI_AVAILABLE),gui)
|
|
||||||
$(PYTHON) tests/integration/test_install.py --build-dir "$(abspath $(BUILD_DIR))" --custom-layout $(if $(GUI_AVAILABLE),--gui)
|
|
||||||
|
|
||||||
$(BUILD_DIR)/src/plugin/modern.o: override CPPFLAGS += -isystem third_party/clap/include -isystem third_party/vst3
|
|
||||||
|
|
||||||
$(BUILD_DIR)/clap-fixture.clap: tests/plugins/clap_fixture.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -isystem third_party/clap/include $(LDFLAGS) -fPIC -shared -o $@ $<
|
|
||||||
$(BUILD_DIR)/vst2-fixture.so: tests/plugins/vst2_fixture.c src/plugin/vst2_abi.h
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -fPIC -shared -o $@ $<
|
|
||||||
$(BUILD_DIR)/vst3-fixture.so: tests/plugins/vst3_fixture.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -isystem third_party/vst3 $(LDFLAGS) -fPIC -shared -o $@ $<
|
|
||||||
$(BUILD_DIR)/test_modern_plugins: $(BUILD_DIR)/tests/integration/test_modern_plugins.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl -Wl,--wrap=malloc,--wrap=calloc,--wrap=realloc,--wrap=free,--wrap=dlopen,--wrap=dlclose
|
|
||||||
.PHONY: test-modern-plugins
|
|
||||||
test-modern-plugins: $(BUILD_DIR)/test_modern_plugins $(BUILD_DIR)/clap-fixture.clap $(BUILD_DIR)/vst2-fixture.so $(BUILD_DIR)/vst3-fixture.so
|
|
||||||
./$(BUILD_DIR)/test_modern_plugins "$(abspath $(BUILD_DIR))/clap-fixture.clap" "$(abspath $(BUILD_DIR))/vst2-fixture.so" "$(abspath $(BUILD_DIR))/vst3-fixture.so"
|
|
||||||
test: test-modern-plugins
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_modern_plugins.d
|
|
||||||
|
|
||||||
.PHONY: test-gui-modern-plugins
|
|
||||||
ifeq ($(GUI_AVAILABLE),yes)
|
|
||||||
test-gui-modern-plugins: $(BUILD_DIR)/test_gui $(BUILD_DIR)/clap-fixture.clap $(BUILD_DIR)/vst2-fixture.so $(BUILD_DIR)/vst3-fixture.so
|
|
||||||
XTC_TEST_CLAP="$(abspath $(BUILD_DIR))/clap-fixture.clap" XTC_TEST_VST2="$(abspath $(BUILD_DIR))/vst2-fixture.so" XTC_TEST_VST3="$(abspath $(BUILD_DIR))/vst3-fixture.so" xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
else
|
|
||||||
test-gui-modern-plugins:
|
|
||||||
@echo "FLTK development files are required for modern plugin GUI tests."
|
|
||||||
@exit 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(BUILD_DIR)/clap-synth-fixture.clap: tests/plugins/clap_synth_fixture.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -isystem third_party/clap/include $(LDFLAGS) -fPIC -shared -o $@ $<
|
|
||||||
$(BUILD_DIR)/vst2-synth-fixture.so: tests/plugins/vst2_synth_fixture.c src/plugin/vst2_abi.h
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -fPIC -shared -o $@ $<
|
|
||||||
$(BUILD_DIR)/vst3-synth-fixture.so: tests/plugins/vst3_synth_fixture.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -isystem third_party/vst3 $(LDFLAGS) -fPIC -shared -o $@ $<
|
|
||||||
$(BUILD_DIR)/test_instruments: $(BUILD_DIR)/tests/integration/test_instruments.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl -Wl,--wrap=malloc,--wrap=calloc,--wrap=realloc,--wrap=free,--wrap=dlopen,--wrap=dlclose
|
|
||||||
.PHONY: test-instruments
|
|
||||||
test-instruments: $(BUILD_DIR)/test_instruments $(BUILD_DIR)/clap-synth-fixture.clap $(BUILD_DIR)/vst2-synth-fixture.so $(BUILD_DIR)/vst3-synth-fixture.so
|
|
||||||
./$(BUILD_DIR)/test_instruments "$(abspath $(BUILD_DIR))/clap-synth-fixture.clap" "$(abspath $(BUILD_DIR))/vst2-synth-fixture.so" "$(abspath $(BUILD_DIR))/vst3-synth-fixture.so"
|
|
||||||
test: test-instruments
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_instruments.d
|
|
||||||
|
|
||||||
.PHONY: test-gui-instruments
|
|
||||||
test-gui-instruments: $(BUILD_DIR)/test_gui $(BUILD_DIR)/clap-synth-fixture.clap $(BUILD_DIR)/vst2-synth-fixture.so $(BUILD_DIR)/vst3-synth-fixture.so
|
|
||||||
XTC_TEST_SYNTH_CLAP="$(abspath $(BUILD_DIR))/clap-synth-fixture.clap" XTC_TEST_SYNTH_VST2="$(abspath $(BUILD_DIR))/vst2-synth-fixture.so" XTC_TEST_SYNTH_VST3="$(abspath $(BUILD_DIR))/vst3-synth-fixture.so" xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_settings: $(BUILD_DIR)/tests/unit/test_settings.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-settings
|
|
||||||
test-settings: $(BUILD_DIR)/test_settings
|
|
||||||
./$(BUILD_DIR)/test_settings
|
|
||||||
test: test-settings
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_settings.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_builtin: tests/unit/test_builtin.c $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(BUILD_DIR)/libxtc.a -lm -ldl
|
|
||||||
.PHONY: test-builtins
|
|
||||||
test: test-builtins
|
|
||||||
test-builtins: $(BUILD_DIR)/test_builtin
|
|
||||||
./$(BUILD_DIR)/test_builtin
|
|
||||||
|
|
||||||
$(BUILD_DIR)/builtin-preview: $(BUILD_DIR)/examples/builtin_preview.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: builtin-preview
|
|
||||||
builtin-preview: $(BUILD_DIR)/builtin-preview
|
|
||||||
./$(BUILD_DIR)/builtin-preview "$(abspath $(BUILD_DIR))/builtin"
|
|
||||||
-include $(BUILD_DIR)/examples/builtin_preview.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_modern_editing: tests/unit/test_modern_editing.c $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(BUILD_DIR)/libxtc.a -lm -ldl
|
|
||||||
|
|
||||||
.PHONY: test-modern-editing
|
|
||||||
test-modern-editing: $(BUILD_DIR)/test_modern_editing
|
|
||||||
./$(BUILD_DIR)/test_modern_editing
|
|
||||||
|
|
||||||
.PHONY: test-gui-modern-editing
|
|
||||||
test-gui-modern-editing: $(BUILD_DIR)/test_gui
|
|
||||||
XTC_TEST_MODERN_EDITING_ONLY=1 xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_next_daw: tests/unit/test_next_daw.c $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(BUILD_DIR)/libxtc.a -lm -ldl
|
|
||||||
.PHONY: test-next-daw test-gui-next-daw
|
|
||||||
test-next-daw: $(BUILD_DIR)/test_next_daw
|
|
||||||
./$(BUILD_DIR)/test_next_daw
|
|
||||||
test: test-next-daw
|
|
||||||
test-gui-next-daw: $(BUILD_DIR)/test_gui
|
|
||||||
XTC_TEST_MODERN_EDITING_ONLY=1 XTC_TEST_NEXT_DAW_ONLY=1 xvfb-run -a -s "-screen 0 1280x800x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
# Optional documentation capture; requires Xvfb, ImageMagick import and xdotool.
|
|
||||||
$(BUILD_DIR)/capture_screenshots: $(BUILD_DIR)/tools/capture_screenshots.o $(BUILD_DIR)/src/gui/main_window.o $(BUILD_DIR)/src/gui/graph_widget.o $(BUILD_DIR)/src/gui/sequencer_widget.o $(BUILD_DIR)/src/gui/piano_roll.o $(BUILD_DIR)/src/gui/mixer_widget.o $(BUILD_DIR)/src/gui/plugin_dialog.o $(BUILD_DIR)/src/gui/sample_editor.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CXX) $(LDFLAGS) -o $@ $^ $(FLTK_LIBS) $(JACK_LIBS) -lm -ldl
|
|
||||||
|
|
||||||
.PHONY: screenshots
|
|
||||||
screenshots: $(BUILD_DIR)/capture_screenshots $(BUILD_DIR)/plugin-fixture.so $(BUILD_DIR)/clap-synth-fixture.clap $(BUILD_DIR)/vst2-synth-fixture.so $(BUILD_DIR)/vst3-synth-fixture.so
|
|
||||||
xvfb-run -a -s "-screen 0 1440x960x24" ./$(BUILD_DIR)/capture_screenshots "$(CURDIR)/screenshots"
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tools/capture_screenshots.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_sample: $(BUILD_DIR)/tests/unit/test_sample.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-sample test-gui-sample
|
|
||||||
test-sample: $(BUILD_DIR)/test_sample
|
|
||||||
./$(BUILD_DIR)/test_sample
|
|
||||||
test: test-sample
|
|
||||||
test-gui-sample: $(BUILD_DIR)/test_gui
|
|
||||||
XTC_TEST_SAMPLE_EDITOR_ONLY=1 xvfb-run -a -s "-screen 0 1280x900x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
-include $(BUILD_DIR)/src/gui/sample_editor.d $(BUILD_DIR)/tests/unit/test_sample.d
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_track_fx: $(BUILD_DIR)/tests/unit/test_track_fx.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-track-fx
|
|
||||||
test-track-fx: $(BUILD_DIR)/test_track_fx
|
|
||||||
./$(BUILD_DIR)/test_track_fx
|
|
||||||
test: test-track-fx
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_track_fx.d
|
|
||||||
|
|
||||||
.PHONY: test-gui-track-fx
|
|
||||||
test-gui-track-fx: $(BUILD_DIR)/test_gui $(BUILD_DIR)/plugin-fixture.so $(BUILD_DIR)/clap-fixture.clap $(BUILD_DIR)/vst2-fixture.so $(BUILD_DIR)/vst3-fixture.so
|
|
||||||
XTC_TEST_TRACK_FX_ONLY=1 XTC_TEST_PLUGIN="$(abspath $(BUILD_DIR))/plugin-fixture.so" XTC_TEST_CLAP="$(abspath $(BUILD_DIR))/clap-fixture.clap" XTC_TEST_VST2="$(abspath $(BUILD_DIR))/vst2-fixture.so" XTC_TEST_VST3="$(abspath $(BUILD_DIR))/vst3-fixture.so" xvfb-run -a -s "-screen 0 1280x900x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_creative: $(BUILD_DIR)/tests/unit/test_creative.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-creative test-gui-creative
|
|
||||||
test-creative: $(BUILD_DIR)/test_creative
|
|
||||||
./$(BUILD_DIR)/test_creative
|
|
||||||
test: test-creative
|
|
||||||
test-gui-creative: $(BUILD_DIR)/test_gui
|
|
||||||
XTC_TEST_CREATIVE_ONLY=1 xvfb-run -a -s "-screen 0 1280x900x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_creative.d
|
|
||||||
|
|
||||||
.PHONY: test-gui-midi-workflows
|
|
||||||
test-gui-midi-workflows: $(BUILD_DIR)/test_gui
|
|
||||||
XTC_TEST_MIDI_WORKFLOWS_ONLY=1 xvfb-run -a -s "-screen 0 1440x960x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_midi_file: $(BUILD_DIR)/tests/unit/test_midi_file.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
.PHONY: test-midi-file
|
|
||||||
test-midi-file: $(BUILD_DIR)/test_midi_file
|
|
||||||
./$(BUILD_DIR)/test_midi_file
|
|
||||||
test: test-midi-file
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_midi_file.d
|
|
||||||
|
|
||||||
.PHONY: test-configuration-startup
|
|
||||||
test-configuration-startup: gui
|
|
||||||
xvfb-run -a -s "-screen 0 1440x960x24" $(PYTHON) tests/integration/test_configuration_startup.py ./$(BUILD_DIR)/xtc
|
|
||||||
|
|
||||||
.PHONY: test-gui-midi-labels
|
|
||||||
test-gui-midi-labels: $(BUILD_DIR)/test_gui
|
|
||||||
XTC_TEST_MIDI_LABELS_ONLY=1 xvfb-run -a -s "-screen 0 1440x960x24" ./$(BUILD_DIR)/test_gui
|
|
||||||
|
|
||||||
# Optional external Steinberg SDK qualification. Normal builds never fetch SDKs.
|
|
||||||
VST3_SDK_ROOT ?=
|
|
||||||
STEINBERG_BUILD_DIR ?= $(BUILD_DIR)/steinberg-sdk
|
|
||||||
.PHONY: steinberg-sdk test-steinberg-sdk test-plugin-module-path
|
|
||||||
steinberg-sdk:
|
|
||||||
@test -n "$(VST3_SDK_ROOT)" || { echo "Set VST3_SDK_ROOT to an official recursive SDK checkout."; exit 1; }
|
|
||||||
cmake -S examples/steinberg -B "$(STEINBERG_BUILD_DIR)" -DXTC_VST3_SDK_ROOT="$(abspath $(VST3_SDK_ROOT))" -DCMAKE_BUILD_TYPE=Release
|
|
||||||
cmake --build "$(STEINBERG_BUILD_DIR)" --target xtc-sdk-examples validator --parallel 4
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_plugin_module_path: $(BUILD_DIR)/tests/unit/test_plugin_module_path.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
test-plugin-module-path: $(BUILD_DIR)/test_plugin_module_path
|
|
||||||
./$(BUILD_DIR)/test_plugin_module_path
|
|
||||||
|
|
||||||
test: test-plugin-module-path
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_steinberg_sdk: $(BUILD_DIR)/tests/integration/test_steinberg_sdk.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
$(BUILD_DIR)/steinberg-render: $(BUILD_DIR)/examples/steinberg/render.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
# Linux bundle convention; native Windows SDK examples use CMake directly.
|
|
||||||
test-steinberg-sdk: steinberg-sdk $(BUILD_DIR)/test_steinberg_sdk $(BUILD_DIR)/steinberg-render
|
|
||||||
"$(STEINBERG_BUILD_DIR)/bin/Release/validator" "$(abspath $(STEINBERG_BUILD_DIR))/VST3/Release/xtc-sdk-examples.vst3"
|
|
||||||
./$(BUILD_DIR)/test_steinberg_sdk "$(abspath $(STEINBERG_BUILD_DIR))/VST3/Release/xtc-sdk-examples.vst3"
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/unit/test_plugin_module_path.d $(BUILD_DIR)/tests/integration/test_steinberg_sdk.d $(BUILD_DIR)/examples/steinberg/render.d
|
|
||||||
|
|
||||||
# Optional JUCE bridge/examples; externally supplied SDK, no downloads or installs.
|
|
||||||
JUCE_ROOT ?=
|
|
||||||
JUCE_BUILD_DIR ?= $(BUILD_DIR)/juce
|
|
||||||
.PHONY: juce-examples test-juce
|
|
||||||
juce-examples:
|
|
||||||
@test -n "$(JUCE_ROOT)" || { echo "Set JUCE_ROOT to an external JUCE 9 checkout (AGPLv3/commercial)."; exit 1; }
|
|
||||||
cmake -S examples/juce -B "$(JUCE_BUILD_DIR)" -DXTC_JUCE_ROOT="$(abspath $(JUCE_ROOT))" -DCMAKE_BUILD_TYPE=Release
|
|
||||||
cmake --build "$(JUCE_BUILD_DIR)" --target xtc-juce-render XtcJuceSynth_VST3 XtcJuceSynth_Standalone --parallel 3
|
|
||||||
|
|
||||||
$(BUILD_DIR)/test_juce_plugin: $(BUILD_DIR)/tests/integration/test_juce_plugin.o $(BUILD_DIR)/libxtc.a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lm -ldl
|
|
||||||
|
|
||||||
test-juce: juce-examples $(BUILD_DIR)/test_juce_plugin
|
|
||||||
xvfb-run -a $(PYTHON) tests/integration/test_juce_examples.py "$(JUCE_BUILD_DIR)/xtc-juce-render_artefacts/Release/xtc-juce-render"
|
|
||||||
xvfb-run -a ctest --test-dir "$(JUCE_BUILD_DIR)" --output-on-failure
|
|
||||||
xvfb-run -a ./$(BUILD_DIR)/test_juce_plugin "$(abspath $(JUCE_BUILD_DIR))/XtcJuceSynth_artefacts/Release/VST3/xtc JUCE Synth.vst3"
|
|
||||||
|
|
||||||
-include $(BUILD_DIR)/tests/integration/test_juce_plugin.d
|
|
||||||
|
|
|
||||||
62
README.md
62
README.md
|
|
@ -40,23 +40,37 @@ hosting supports the compatible mono processors documented in
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
Requirements: a C compiler, a C++ compiler, GNU Make, and `pkg-config`. FLTK is optional for the core and tests.
|
Requirements: CMake 3.25+, a C99 compiler, Python 3.12+ and a build backend
|
||||||
|
such as Ninja or Unix Makefiles. The optional GUI needs C++17 and FLTK; JACK and
|
||||||
|
LADSPA development files enable their optional integrations.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make
|
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
|
||||||
make test
|
cmake --build build --parallel
|
||||||
|
ctest --test-dir build --output-on-failure
|
||||||
```
|
```
|
||||||
|
|
||||||
`make` also builds `build/xtc-check`, a headless core startup/shutdown
|
For quick development, the optional Make wrapper provides the same workflow:
|
||||||
check. Use `make debug` for a separate debug build and test run. See
|
|
||||||
[docs/BUILD.md](docs/BUILD.md) for the inspected toolchain and baseline limits.
|
|
||||||
|
|
||||||
Build the optional FLTK GUI if FLTK is installed:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make gui
|
make # configure and build
|
||||||
|
make test # build and run CTest
|
||||||
|
make gui # build just the FLTK application
|
||||||
|
make run # build and launch it
|
||||||
|
make clean # clean products; keep the CMake cache
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Override `BUILD_DIR`, `BUILD_TYPE` or `JOBS` as needed, for example
|
||||||
|
`make BUILD_DIR=build/release BUILD_TYPE=Release JOBS=8`. Pass additional options
|
||||||
|
with `CMAKE_ARGS` and `CTEST_ARGS`. CMake remains the authoritative build system.
|
||||||
|
|
||||||
|
This builds `libxtc.a`, the headless `xtc-check`, tests, examples and the FLTK
|
||||||
|
application when available. Live JACK tests are opt-in. Use `-DXTC_BUILD_GUI=OFF`
|
||||||
|
for the C-only build, or the `debug`, `release`, `minimal` and `sanitize` presets
|
||||||
|
for separate configurations. See [docs/BUILD.md](docs/BUILD.md) for options,
|
||||||
|
focused tests, installation and IDE setup. [Phase 108](docs/ROADMAP.md#phase-108--complete-cmake-build-migration) records
|
||||||
|
the CMake migration.
|
||||||
|
|
||||||
Run the GUI:
|
Run the GUI:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
@ -93,24 +107,24 @@ active graph intact; queued changes are labeled until the engine adopts them.
|
||||||
See [GUI documentation](docs/GUI.md).
|
See [GUI documentation](docs/GUI.md).
|
||||||
For Linux installation, routing and CLI options see [LINUX.md](docs/LINUX.md);
|
For Linux installation, routing and CLI options see [LINUX.md](docs/LINUX.md);
|
||||||
for native effects/instruments see [NATIVE_API.md](docs/NATIVE_API.md).
|
for native effects/instruments see [NATIVE_API.md](docs/NATIVE_API.md).
|
||||||
`make release`, `make dist`, `make test-install` and `make test-release` provide
|
The release preset and CMake’s `dist`, `test-install`, `test-release` and
|
||||||
release preparation; see [RELEASING.md](docs/RELEASING.md) for exact guarantees.
|
`test-package` targets provide release preparation; see
|
||||||
With JACK development files and an existing JACK-compatible server, run the
|
[RELEASING.md](docs/RELEASING.md) for exact guarantees.
|
||||||
isolated software-loopback test with `make test-jack` and the record/reopen/play
|
With JACK development files and an existing JACK-compatible server, configure
|
||||||
acceptance test with `make test-jack-audio` and MIDI acceptance with
|
with `-DXTC_ENABLE_LIVE_TESTS=ON`, build, and run
|
||||||
`make test-jack-midi`. It connects only test
|
`ctest --test-dir build --output-on-failure -L live`. These software-loopback
|
||||||
clients. See [engine documentation](docs/AUDIO_ENGINE.md) for configuration,
|
checks connect only test clients. See [engine documentation](docs/AUDIO_ENGINE.md)
|
||||||
routing, ownership and recovery.
|
for configuration, routing, ownership and recovery.
|
||||||
|
|
||||||
Clean generated files:
|
Clean generated files:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make clean
|
cmake --build build --target clean
|
||||||
```
|
```
|
||||||
|
|
||||||
## Suggested first agent task
|
## Suggested first agent task
|
||||||
|
|
||||||
Read `AGENT.md` and `docs/ARCHITECTURE.md`. Inspect the existing implementation, run `make test`, and report gaps before adding the next feature. Do not jump directly to plugin hosting or a full sequencer.
|
Read `AGENT.md` and `docs/ARCHITECTURE.md`. Inspect the existing implementation, run `cmake --build build --target check`, and report gaps before adding the next feature. Do not jump directly to plugin hosting or a full sequencer.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
@ -128,19 +142,19 @@ See [RECOVERY.md](docs/RECOVERY.md), [NATIVE_API.md](docs/NATIVE_API.md) and
|
||||||
For everyday use see [USER_MANUAL.md](docs/USER_MANUAL.md),
|
For everyday use see [USER_MANUAL.md](docs/USER_MANUAL.md),
|
||||||
[KNOWN_LIMITATIONS.md](docs/KNOWN_LIMITATIONS.md) and
|
[KNOWN_LIMITATIONS.md](docs/KNOWN_LIMITATIONS.md) and
|
||||||
[MAINTENANCE.md](docs/MAINTENANCE.md). `xtc-check --diagnose` reports build features;
|
[MAINTENANCE.md](docs/MAINTENANCE.md). `xtc-check --diagnose` reports build features;
|
||||||
`make test-package` checks a local system-linked Linux binary archive.
|
`cmake --build build --target test-package` checks a local system-linked Linux binary archive.
|
||||||
Effect automation/controllers, editing commands, v7 project-folder media paths,
|
Effect automation/controllers, editing commands, v7 project-folder media paths,
|
||||||
performance baselines and release/installation checks are also supported.
|
performance baselines and release/installation checks are also supported.
|
||||||
|
|
||||||
Non-destructive audio splitting, clip gain/fades and cached timeline waveforms
|
Non-destructive audio splitting, clip gain/fades and cached timeline waveforms
|
||||||
are supported, with undo and v8 persistence (reading v1–v7). See
|
are supported, with undo and v8 persistence (reading v1–v7). See
|
||||||
[AUDIO_FILES.md](docs/AUDIO_FILES.md#non-destructive-clip-editing).
|
[AUDIO_FILES.md](docs/AUDIO_FILES.md#non-destructive-clip-editing).
|
||||||
`make test-audio-editing` checks source preservation and exact boundary output.
|
`cmake --build build --target test-audio-editing` checks source preservation and exact boundary output.
|
||||||
Time stretching and independent pitch shifting remain deferred.
|
Time stretching and independent pitch shifting remain deferred.
|
||||||
|
|
||||||
Signal-flow graph layout, routing diagnostics, direction/role indicators and
|
Signal-flow graph layout, routing diagnostics, direction/role indicators and
|
||||||
atomic unity-gain insertion into a wire are supported. See
|
atomic unity-gain insertion into a wire are supported. See
|
||||||
[ROUTING.md](docs/ROUTING.md); `make test-routing` verifies the C routing contract.
|
[ROUTING.md](docs/ROUTING.md); `cmake --build build --target test-routing` verifies the C routing contract.
|
||||||
|
|
||||||
One-level mix buses, routing, coherent track/bus peaks and master clipping
|
One-level mix buses, routing, coherent track/bus peaks and master clipping
|
||||||
indicators are supported, persisted in v9 (reading v1–v8). See [MIXER.md](docs/MIXER.md).
|
indicators are supported, persisted in v9 (reading v1–v8). See [MIXER.md](docs/MIXER.md).
|
||||||
|
|
@ -198,12 +212,12 @@ for file support, routing and persistence details.
|
||||||
|
|
||||||
[Steinberg SDK integration (Phase 106)](docs/STEINBERG.md) adds conventional Linux
|
[Steinberg SDK integration (Phase 106)](docs/STEINBERG.md) adds conventional Linux
|
||||||
VST3 bundle loading, transport context, official-SDK gain/synth examples and
|
VST3 bundle loading, transport context, official-SDK gain/synth examples and
|
||||||
validator checks. Run `make VST3_SDK_ROOT=/path/to/vst3sdk test-steinberg-sdk`
|
validator checks. Run `cmake -S . -B build -DXTC_VST3_SDK_ROOT=/path/to/vst3sdk -DXTC_BUILD_STEINBERG=ON && cmake --build build --target test-steinberg-sdk`
|
||||||
for optional SDK qualification. A Windows ASIO device diagnostic is provided;
|
for optional SDK qualification. A Windows ASIO device diagnostic is provided;
|
||||||
a native ASIO playback/capture backend remains planned.
|
a native ASIO playback/capture backend remains planned.
|
||||||
|
|
||||||
[JUCE integration (Phase 107)](docs/JUCE.md) provides an optional VST3/standalone
|
[JUCE integration (Phase 107)](docs/JUCE.md) provides an optional VST3/standalone
|
||||||
Soft Keys instrument with a native editor, DSP effects, presets, MIDI-to-WAV
|
Soft Keys instrument with a native editor, DSP effects, presets, MIDI-to-WAV
|
||||||
rendering and VST3 hosting examples. Build and qualify it with
|
rendering and VST3 hosting examples. Build and qualify it with
|
||||||
`make JUCE_ROOT=/path/to/JUCE test-juce`; review JUCE’s AGPLv3/commercial licence
|
`cmake -S . -B build -DXTC_JUCE_ROOT=/path/to/JUCE -DXTC_BUILD_JUCE=ON && cmake --build build --target test-juce`; review JUCE’s AGPLv3/commercial licence
|
||||||
before distributing linked binaries. See [the examples](examples/juce/README.md).
|
before distributing linked binaries. See [the examples](examples/juce/README.md).
|
||||||
|
|
|
||||||
57
cmake/Developer.cmake
Normal file
57
cmake/Developer.cmake
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
get_target_property(xtc_sources xtc-core SOURCES)
|
||||||
|
add_custom_target(analyze COMMAND ${Python3_EXECUTABLE} tools/analyze.py ${xtc_sources}
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
xtc_executable(benchmark_graph tests/integration/benchmark_graph.c)
|
||||||
|
set(XTC_BENCHMARK_BLOCKS 300 CACHE STRING "Benchmark iterations")
|
||||||
|
set(XTC_BENCHMARK_MAX_REGRESSION 1.5 CACHE STRING "Benchmark regression limit")
|
||||||
|
set(XTC_STRESS_ROUNDS 3 CACHE STRING "Stress iterations")
|
||||||
|
set(XTC_BENCHMARK_BASELINE "${PROJECT_SOURCE_DIR}/docs/performance-baseline.json" CACHE FILEPATH "Graph benchmark baseline")
|
||||||
|
set(XTC_PROJECT_BENCHMARK_BASELINE "${PROJECT_SOURCE_DIR}/docs/project-performance-baseline.json" CACHE FILEPATH "Project benchmark baseline")
|
||||||
|
foreach(workload graph project)
|
||||||
|
if(workload STREQUAL graph)
|
||||||
|
set(binary benchmark_graph)
|
||||||
|
set(stem benchmark)
|
||||||
|
set(baseline "${XTC_BENCHMARK_BASELINE}")
|
||||||
|
set(report performance.json)
|
||||||
|
else()
|
||||||
|
set(binary test_performance)
|
||||||
|
set(stem benchmark-project)
|
||||||
|
set(baseline "${XTC_PROJECT_BENCHMARK_BASELINE}")
|
||||||
|
set(report project-performance.json)
|
||||||
|
endif()
|
||||||
|
foreach(compare "" "-compare")
|
||||||
|
set(extra)
|
||||||
|
if(compare)
|
||||||
|
set(extra --baseline "${baseline}" --max-regression ${XTC_BENCHMARK_MAX_REGRESSION})
|
||||||
|
endif()
|
||||||
|
add_custom_target(${stem}${compare}
|
||||||
|
COMMAND ${Python3_EXECUTABLE} tools/benchmark.py --workload ${workload}
|
||||||
|
--binary $<TARGET_FILE:${binary}> --output "${CMAKE_CURRENT_BINARY_DIR}/${report}"
|
||||||
|
--compiler "${CMAKE_C_COMPILER}" --flags "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}"
|
||||||
|
--blocks ${XTC_BENCHMARK_BLOCKS} ${extra}
|
||||||
|
DEPENDS ${binary} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
set(stress_deps test_realtime test_reliability test_scale test_portability test_project_diagnostics test_soak)
|
||||||
|
if(TARGET test_backend)
|
||||||
|
list(APPEND stress_deps test_backend)
|
||||||
|
endif()
|
||||||
|
set(gui_arg)
|
||||||
|
if(TARGET test_gui)
|
||||||
|
set(gui_arg --gui)
|
||||||
|
list(APPEND stress_deps test_gui)
|
||||||
|
endif()
|
||||||
|
add_custom_target(test-stress COMMAND ${Python3_EXECUTABLE} tools/stress.py
|
||||||
|
--build-dir "${CMAKE_CURRENT_BINARY_DIR}" --rounds ${XTC_STRESS_ROUNDS} ${gui_arg}
|
||||||
|
DEPENDS ${stress_deps} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
if(XTC_LADSPA_AVAILABLE)
|
||||||
|
add_custom_target(test-stress-plugins COMMAND ${Python3_EXECUTABLE} tools/stress.py
|
||||||
|
--build-dir "${CMAKE_CURRENT_BINARY_DIR}" --rounds ${XTC_STRESS_ROUNDS} --plugin $<TARGET_FILE:plugin-fixture>
|
||||||
|
DEPENDS ${stress_deps} test_plugins plugin-fixture WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
endif()
|
||||||
|
add_custom_target(test-plugins-real
|
||||||
|
COMMAND test_plugins /usr/lib/ladspa/amp.so
|
||||||
|
COMMAND test_plugins /usr/lib/ladspa/inv_1429.so
|
||||||
|
COMMAND test_plugins /usr/lib/ladspa/sine.so 3 DEPENDS test_plugins VERBATIM)
|
||||||
|
endif()
|
||||||
87
cmake/Gui.cmake
Normal file
87
cmake/Gui.cmake
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
if(NOT XTC_BUILD_GUI)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
if(PkgConfig_FOUND)
|
||||||
|
pkg_check_modules(FLTK QUIET IMPORTED_TARGET fltk)
|
||||||
|
endif()
|
||||||
|
if(FLTK_FOUND)
|
||||||
|
set(xtc_fltk PkgConfig::FLTK)
|
||||||
|
else()
|
||||||
|
find_program(XTC_FLTK_CONFIG fltk-config)
|
||||||
|
if(NOT XTC_FLTK_CONFIG)
|
||||||
|
message(STATUS "FLTK unavailable: building core and offline tests only")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
execute_process(COMMAND ${XTC_FLTK_CONFIG} --cxxflags OUTPUT_VARIABLE fltk_flags OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)
|
||||||
|
execute_process(COMMAND ${XTC_FLTK_CONFIG} --ldflags OUTPUT_VARIABLE fltk_libs OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)
|
||||||
|
separate_arguments(fltk_flags UNIX_COMMAND "${fltk_flags}")
|
||||||
|
separate_arguments(fltk_libs UNIX_COMMAND "${fltk_libs}")
|
||||||
|
# Distribution flags must not override this project's debug/release settings.
|
||||||
|
list(FILTER fltk_flags INCLUDE REGEX "^(-I|-D|-pthread)")
|
||||||
|
add_library(xtc-fltk INTERFACE)
|
||||||
|
target_compile_options(xtc-fltk INTERFACE ${fltk_flags})
|
||||||
|
target_link_libraries(xtc-fltk INTERFACE ${fltk_libs})
|
||||||
|
set(xtc_fltk xtc-fltk)
|
||||||
|
endif()
|
||||||
|
enable_language(CXX)
|
||||||
|
set(XTC_GUI_AVAILABLE TRUE)
|
||||||
|
add_library(xtc-gui STATIC src/gui/main_window.cpp src/gui/graph_widget.cpp
|
||||||
|
src/gui/sequencer_widget.cpp src/gui/piano_roll.cpp src/gui/mixer_widget.cpp
|
||||||
|
src/gui/plugin_dialog.cpp src/gui/sample_editor.cpp)
|
||||||
|
xtc_warnings(xtc-gui)
|
||||||
|
target_link_libraries(xtc-gui PUBLIC xtc-core ${xtc_fltk})
|
||||||
|
add_executable(xtc src/gui/main.cpp)
|
||||||
|
xtc_warnings(xtc)
|
||||||
|
target_link_libraries(xtc PRIVATE xtc-gui)
|
||||||
|
add_custom_target(gui DEPENDS xtc)
|
||||||
|
find_program(XTC_XVFB_RUN xvfb-run)
|
||||||
|
add_executable(capture_screenshots EXCLUDE_FROM_ALL tools/capture_screenshots.cpp)
|
||||||
|
xtc_warnings(capture_screenshots)
|
||||||
|
target_link_libraries(capture_screenshots PRIVATE xtc-gui)
|
||||||
|
if(XTC_XVFB_RUN AND BUILD_TESTING)
|
||||||
|
if(XTC_LADSPA_AVAILABLE)
|
||||||
|
add_custom_target(screenshots COMMAND ${XTC_XVFB_RUN} -a -s "-screen 0 1440x960x24"
|
||||||
|
$<TARGET_FILE:capture_screenshots> "${PROJECT_SOURCE_DIR}/screenshots"
|
||||||
|
DEPENDS capture_screenshots plugin-fixture clap-synth-fixture vst2-synth-fixture vst3-synth-fixture
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
endif()
|
||||||
|
add_executable(test_gui tests/integration/test_gui.cpp)
|
||||||
|
xtc_warnings(test_gui)
|
||||||
|
target_link_libraries(test_gui PRIVATE xtc-gui)
|
||||||
|
xtc_wrap(test_gui xtc_history_reserve)
|
||||||
|
function(xtc_gui_test name)
|
||||||
|
add_test(NAME ${name} COMMAND ${XTC_XVFB_RUN} -a -s "-screen 0 1440x960x24" $<TARGET_FILE:test_gui>)
|
||||||
|
set_tests_properties(${name} PROPERTIES WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" LABELS gui ENVIRONMENT "${ARGN}")
|
||||||
|
endfunction()
|
||||||
|
xtc_gui_test(gui)
|
||||||
|
if(XTC_LADSPA_AVAILABLE)
|
||||||
|
xtc_gui_test(gui-plugins "XTC_TEST_PLUGIN=$<TARGET_FILE:plugin-fixture>")
|
||||||
|
endif()
|
||||||
|
xtc_gui_test(gui-modern-plugins "XTC_TEST_CLAP=$<TARGET_FILE:clap-fixture>" "XTC_TEST_VST2=$<TARGET_FILE:vst2-fixture>" "XTC_TEST_VST3=$<TARGET_FILE:vst3-fixture>")
|
||||||
|
xtc_gui_test(gui-instruments "XTC_TEST_SYNTH_CLAP=$<TARGET_FILE:clap-synth-fixture>" "XTC_TEST_SYNTH_VST2=$<TARGET_FILE:vst2-synth-fixture>" "XTC_TEST_SYNTH_VST3=$<TARGET_FILE:vst3-synth-fixture>")
|
||||||
|
foreach(pair "modern-editing|MODERN_EDITING" "next-daw|NEXT_DAW" "sample|SAMPLE_EDITOR" "creative|CREATIVE" "midi-workflows|MIDI_WORKFLOWS" "midi-labels|MIDI_LABELS")
|
||||||
|
string(REPLACE "|" ";" pair "${pair}")
|
||||||
|
list(GET pair 0 name)
|
||||||
|
list(GET pair 1 env)
|
||||||
|
xtc_gui_test(gui-${name} "XTC_TEST_${env}_ONLY=1")
|
||||||
|
endforeach()
|
||||||
|
set_property(TEST gui-next-daw APPEND PROPERTY ENVIRONMENT XTC_TEST_MODERN_EDITING_ONLY=1)
|
||||||
|
if(XTC_LADSPA_AVAILABLE)
|
||||||
|
xtc_gui_test(gui-track-fx "XTC_TEST_TRACK_FX_ONLY=1" "XTC_TEST_PLUGIN=$<TARGET_FILE:plugin-fixture>" "XTC_TEST_CLAP=$<TARGET_FILE:clap-fixture>" "XTC_TEST_VST2=$<TARGET_FILE:vst2-fixture>" "XTC_TEST_VST3=$<TARGET_FILE:vst3-fixture>")
|
||||||
|
endif()
|
||||||
|
add_test(NAME configuration-startup COMMAND ${XTC_XVFB_RUN} -a -s "-screen 0 1440x960x24" ${Python3_EXECUTABLE}
|
||||||
|
"${PROJECT_SOURCE_DIR}/tests/integration/test_configuration_startup.py" $<TARGET_FILE:xtc>)
|
||||||
|
set_tests_properties(configuration-startup PROPERTIES LABELS gui)
|
||||||
|
if(JACK_FOUND AND XTC_WITH_JACK)
|
||||||
|
foreach(kind gui_jack workflow)
|
||||||
|
add_executable(test_${kind} tests/integration/test_${kind}.cpp)
|
||||||
|
xtc_warnings(test_${kind})
|
||||||
|
target_link_libraries(test_${kind} PRIVATE xtc-gui)
|
||||||
|
if(XTC_ENABLE_LIVE_TESTS)
|
||||||
|
string(REPLACE "_" "-" name "${kind}")
|
||||||
|
add_test(NAME ${name} COMMAND ${XTC_XVFB_RUN} -a $<TARGET_FILE:test_${kind}>)
|
||||||
|
set_tests_properties(${name} PROPERTIES WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" LABELS live RUN_SERIAL TRUE)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
46
cmake/Install.cmake
Normal file
46
cmake/Install.cmake
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Retain the audited owned-file inventory and symlink-safe staging implementation.
|
||||||
|
set(XTC_INSTALL_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE PATH "Directory containing built install inputs")
|
||||||
|
option(XTC_INSTALL_GUI "Include the GUI in installation" ${XTC_GUI_AVAILABLE})
|
||||||
|
set(XTC_INSTALL_LICENSEDIR "${CMAKE_INSTALL_DATAROOTDIR}/licenses/xtc" CACHE STRING "License install directory")
|
||||||
|
set(XTC_INSTALL_EXAMPLESDIR "${CMAKE_INSTALL_DATAROOTDIR}/xtc/examples" CACHE STRING "Example install directory")
|
||||||
|
set(XTC_INSTALL_DESKTOPDIR "${CMAKE_INSTALL_DATAROOTDIR}/applications" CACHE STRING "Desktop entry directory")
|
||||||
|
set(XTC_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE STRING "pkg-config directory")
|
||||||
|
configure_file(cmake/InstallDriver.cmake.in xtc-install.cmake @ONLY)
|
||||||
|
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/xtc-install.cmake")
|
||||||
|
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -DXTC_UNINSTALL=ON -P "${CMAKE_CURRENT_BINARY_DIR}/xtc-install.cmake" VERBATIM)
|
||||||
|
add_custom_target(dist COMMAND ${Python3_EXECUTABLE} tools/dist.py --output "${CMAKE_CURRENT_BINARY_DIR}/xtc-${PROJECT_VERSION}.tar.gz"
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
set(gui_arg)
|
||||||
|
if(XTC_GUI_AVAILABLE)
|
||||||
|
set(gui_arg --gui)
|
||||||
|
endif()
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
foreach(layout "" "-layout")
|
||||||
|
set(extra)
|
||||||
|
if(layout)
|
||||||
|
set(extra --custom-layout)
|
||||||
|
endif()
|
||||||
|
add_custom_target(test-install${layout} COMMAND ${Python3_EXECUTABLE} tests/integration/test_install.py
|
||||||
|
--build-dir "${CMAKE_CURRENT_BINARY_DIR}" ${gui_arg} ${extra}
|
||||||
|
DEPENDS xtc-core xtc-check
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
if(XTC_GUI_AVAILABLE)
|
||||||
|
add_dependencies(test-install${layout} xtc)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
add_custom_target(test-release COMMAND ${Python3_EXECUTABLE} tests/integration/test_release.py
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/xtc-${PROJECT_VERSION}.tar.gz" --generator "${CMAKE_GENERATOR}" ${gui_arg}
|
||||||
|
DEPENDS dist WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
endif()
|
||||||
|
set(package_file "${CMAKE_CURRENT_BINARY_DIR}/xtc-${PROJECT_VERSION}-linux-${CMAKE_SYSTEM_PROCESSOR}.tar.gz")
|
||||||
|
add_custom_target(package-binary COMMAND ${Python3_EXECUTABLE} tools/package.py
|
||||||
|
--build-dir "${CMAKE_CURRENT_BINARY_DIR}" --output "${package_file}" ${gui_arg}
|
||||||
|
DEPENDS xtc-core xtc-check WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
if(XTC_GUI_AVAILABLE)
|
||||||
|
add_dependencies(package-binary xtc)
|
||||||
|
endif()
|
||||||
|
add_custom_target(test-package COMMAND ${Python3_EXECUTABLE} tests/integration/test_package.py
|
||||||
|
"${package_file}" --build-dir "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
DEPENDS package-binary WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" VERBATIM)
|
||||||
|
|
||||||
|
add_custom_target(package DEPENDS package-binary)
|
||||||
41
cmake/InstallDriver.cmake.in
Normal file
41
cmake/InstallDriver.cmake.in
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
|
||||||
|
endif()
|
||||||
|
set(layout --prefix "${CMAKE_INSTALL_PREFIX}" --destdir "$ENV{DESTDIR}")
|
||||||
|
set(keys bindir libdir includedir docdir licensedir examplesdir desktopdir pkgconfigdir)
|
||||||
|
set(dirs "@CMAKE_INSTALL_BINDIR@" "@CMAKE_INSTALL_LIBDIR@" "@CMAKE_INSTALL_INCLUDEDIR@" "@CMAKE_INSTALL_DOCDIR@"
|
||||||
|
"@XTC_INSTALL_LICENSEDIR@" "@XTC_INSTALL_EXAMPLESDIR@" "@XTC_INSTALL_DESKTOPDIR@" "@XTC_INSTALL_PKGCONFIGDIR@")
|
||||||
|
foreach(index RANGE 0 7)
|
||||||
|
list(GET keys ${index} key)
|
||||||
|
list(GET dirs ${index} dir)
|
||||||
|
if(NOT IS_ABSOLUTE "${dir}")
|
||||||
|
set(dir "${CMAKE_INSTALL_PREFIX}/${dir}")
|
||||||
|
endif()
|
||||||
|
list(APPEND layout --${key} "${dir}")
|
||||||
|
endforeach()
|
||||||
|
if(XTC_UNINSTALL)
|
||||||
|
set(operation uninstall)
|
||||||
|
set(extra)
|
||||||
|
else()
|
||||||
|
set(operation install)
|
||||||
|
set(extra --build-dir "@XTC_INSTALL_BUILD_DIR@")
|
||||||
|
if("@XTC_INSTALL_GUI@")
|
||||||
|
list(APPEND extra --gui)
|
||||||
|
endif()
|
||||||
|
set(jack)
|
||||||
|
if("@JACK_FOUND@" AND "@XTC_WITH_JACK@")
|
||||||
|
set(jack jack)
|
||||||
|
endif()
|
||||||
|
list(GET dirs 1 libdir)
|
||||||
|
list(GET dirs 2 includedir)
|
||||||
|
foreach(key libdir includedir)
|
||||||
|
if(NOT IS_ABSOLUTE "${${key}}")
|
||||||
|
set(${key} "${CMAKE_INSTALL_PREFIX}/${${key}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
execute_process(COMMAND "@Python3_EXECUTABLE@" tools/pkgconfig.py --prefix "${CMAKE_INSTALL_PREFIX}"
|
||||||
|
--libdir "${libdir}" --includedir "${includedir}" --jack "${jack}" --output "@XTC_INSTALL_BUILD_DIR@/xtc.pc"
|
||||||
|
WORKING_DIRECTORY "@PROJECT_SOURCE_DIR@" COMMAND_ERROR_IS_FATAL ANY)
|
||||||
|
endif()
|
||||||
|
execute_process(COMMAND "@Python3_EXECUTABLE@" "tools/${operation}.py" ${layout} ${extra}
|
||||||
|
WORKING_DIRECTORY "@PROJECT_SOURCE_DIR@" COMMAND_ERROR_IS_FATAL ANY)
|
||||||
144
cmake/Tests.cmake
Normal file
144
cmake/Tests.cmake
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
# Every test runs from the source root: fixtures/project paths are source-relative.
|
||||||
|
function(xtc_test name binary)
|
||||||
|
add_test(NAME ${name} COMMAND ${binary} ${ARGN})
|
||||||
|
set_tests_properties(${name} PROPERTIES WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
|
||||||
|
endfunction()
|
||||||
|
function(xtc_wrap target)
|
||||||
|
foreach(symbol IN LISTS ARGN)
|
||||||
|
target_link_options(${target} PRIVATE "LINKER:--wrap=${symbol}")
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
if(NOT BUILD_TESTING)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
xtc_executable(test_offline tests/unit/test_offline.c)
|
||||||
|
xtc_test(offline test_offline)
|
||||||
|
xtc_executable(test_realtime tests/unit/test_realtime.c)
|
||||||
|
xtc_test(realtime test_realtime)
|
||||||
|
xtc_executable(test_graph_edits tests/unit/test_graph_edits.c)
|
||||||
|
xtc_test(graph-edits test_graph_edits)
|
||||||
|
xtc_executable(test_project tests/unit/test_project.c)
|
||||||
|
xtc_test(project test_project)
|
||||||
|
xtc_executable(test_audio tests/unit/test_audio.c)
|
||||||
|
xtc_test(audio test_audio)
|
||||||
|
xtc_executable(test_midi tests/unit/test_midi.c)
|
||||||
|
xtc_test(midi test_midi)
|
||||||
|
xtc_executable(test_mixer tests/unit/test_mixer.c)
|
||||||
|
xtc_test(mixer test_mixer)
|
||||||
|
xtc_executable(test_native tests/unit/test_native.c)
|
||||||
|
xtc_test(native test_native)
|
||||||
|
xtc_executable(test_performance tests/integration/test_performance.c)
|
||||||
|
xtc_test(performance test_performance)
|
||||||
|
xtc_executable(test_recovery tests/integration/test_recovery.c)
|
||||||
|
xtc_test(recovery test_recovery)
|
||||||
|
xtc_executable(test_reliability tests/integration/test_reliability.c)
|
||||||
|
xtc_wrap(test_reliability malloc calloc realloc free fopen fread fwrite read write pthread_mutex_lock pthread_cond_wait)
|
||||||
|
xtc_test(reliability test_reliability)
|
||||||
|
xtc_executable(test_quality tests/unit/test_quality.c)
|
||||||
|
xtc_test(quality test_quality)
|
||||||
|
xtc_executable(test_recording tests/integration/test_recording.c)
|
||||||
|
xtc_test(recording test_recording)
|
||||||
|
xtc_executable(test_processor tests/unit/test_processor.c examples/processors.c)
|
||||||
|
xtc_test(processor test_processor)
|
||||||
|
xtc_executable(test_plugins tests/integration/test_plugins.c)
|
||||||
|
xtc_wrap(test_plugins malloc calloc realloc free dlopen dlclose)
|
||||||
|
xtc_executable(test_control tests/unit/test_control.c)
|
||||||
|
xtc_test(control test_control)
|
||||||
|
xtc_executable(test_editing tests/unit/test_editing.c)
|
||||||
|
xtc_test(editing test_editing)
|
||||||
|
xtc_executable(test_portability tests/integration/test_portability.c)
|
||||||
|
xtc_test(portability test_portability)
|
||||||
|
xtc_executable(test_scale tests/integration/test_scale.c)
|
||||||
|
xtc_test(scale test_scale)
|
||||||
|
xtc_executable(test_composition tests/unit/test_composition.c)
|
||||||
|
xtc_test(composition test_composition)
|
||||||
|
xtc_executable(test_audio_editing tests/unit/test_audio_editing.c)
|
||||||
|
xtc_test(audio-editing test_audio_editing)
|
||||||
|
xtc_executable(test_routing tests/unit/test_routing.c)
|
||||||
|
xtc_test(routing test_routing)
|
||||||
|
xtc_executable(test_buses tests/unit/test_buses.c)
|
||||||
|
xtc_test(buses test_buses)
|
||||||
|
xtc_executable(test_parameters tests/unit/test_parameters.c)
|
||||||
|
xtc_test(parameters test_parameters)
|
||||||
|
xtc_executable(test_project_diagnostics tests/unit/test_project_diagnostics.c)
|
||||||
|
xtc_wrap(test_project_diagnostics fflush fclose fsync rename)
|
||||||
|
xtc_test(project-diagnostics test_project_diagnostics)
|
||||||
|
xtc_executable(test_soak tests/integration/test_soak.c)
|
||||||
|
xtc_test(soak test_soak)
|
||||||
|
xtc_executable(test_modern_plugins tests/integration/test_modern_plugins.c)
|
||||||
|
xtc_wrap(test_modern_plugins malloc calloc realloc free dlopen dlclose)
|
||||||
|
xtc_executable(test_instruments tests/integration/test_instruments.c)
|
||||||
|
xtc_wrap(test_instruments malloc calloc realloc free dlopen dlclose)
|
||||||
|
xtc_executable(test_settings tests/unit/test_settings.c)
|
||||||
|
xtc_test(settings test_settings)
|
||||||
|
xtc_executable(test_builtin tests/unit/test_builtin.c)
|
||||||
|
xtc_test(builtin test_builtin)
|
||||||
|
xtc_executable(test_modern_editing tests/unit/test_modern_editing.c)
|
||||||
|
xtc_test(modern-editing test_modern_editing)
|
||||||
|
xtc_executable(test_next_daw tests/unit/test_next_daw.c)
|
||||||
|
xtc_test(next-daw test_next_daw)
|
||||||
|
xtc_executable(test_sample tests/unit/test_sample.c)
|
||||||
|
xtc_test(sample test_sample)
|
||||||
|
xtc_executable(test_track_fx tests/unit/test_track_fx.c)
|
||||||
|
xtc_test(track-fx test_track_fx)
|
||||||
|
xtc_executable(test_creative tests/unit/test_creative.c)
|
||||||
|
xtc_test(creative test_creative)
|
||||||
|
xtc_executable(test_midi_file tests/unit/test_midi_file.c)
|
||||||
|
xtc_test(midi-file test_midi_file)
|
||||||
|
xtc_executable(test_plugin_module_path tests/unit/test_plugin_module_path.c)
|
||||||
|
xtc_test(plugin-module-path test_plugin_module_path)
|
||||||
|
xtc_executable(test_core tests/unit/test_core.c)
|
||||||
|
xtc_test(core test_core)
|
||||||
|
if(XTC_LADSPA_AVAILABLE)
|
||||||
|
add_library(plugin-fixture MODULE tests/plugins/fixture.c)
|
||||||
|
xtc_warnings(plugin-fixture)
|
||||||
|
set_target_properties(plugin-fixture PROPERTIES PREFIX "" SUFFIX ".so")
|
||||||
|
target_include_directories(plugin-fixture SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/third_party/clap/include" "${PROJECT_SOURCE_DIR}/third_party/vst3")
|
||||||
|
endif()
|
||||||
|
add_library(clap-fixture MODULE tests/plugins/clap_fixture.c)
|
||||||
|
xtc_warnings(clap-fixture)
|
||||||
|
set_target_properties(clap-fixture PROPERTIES PREFIX "" SUFFIX ".clap")
|
||||||
|
target_include_directories(clap-fixture SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/third_party/clap/include" "${PROJECT_SOURCE_DIR}/third_party/vst3")
|
||||||
|
add_library(vst2-fixture MODULE tests/plugins/vst2_fixture.c)
|
||||||
|
xtc_warnings(vst2-fixture)
|
||||||
|
set_target_properties(vst2-fixture PROPERTIES PREFIX "" SUFFIX ".so")
|
||||||
|
target_include_directories(vst2-fixture SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/third_party/clap/include" "${PROJECT_SOURCE_DIR}/third_party/vst3")
|
||||||
|
add_library(vst3-fixture MODULE tests/plugins/vst3_fixture.c)
|
||||||
|
xtc_warnings(vst3-fixture)
|
||||||
|
set_target_properties(vst3-fixture PROPERTIES PREFIX "" SUFFIX ".so")
|
||||||
|
target_include_directories(vst3-fixture SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/third_party/clap/include" "${PROJECT_SOURCE_DIR}/third_party/vst3")
|
||||||
|
add_library(clap-synth-fixture MODULE tests/plugins/clap_synth_fixture.c)
|
||||||
|
xtc_warnings(clap-synth-fixture)
|
||||||
|
set_target_properties(clap-synth-fixture PROPERTIES PREFIX "" SUFFIX ".clap")
|
||||||
|
target_include_directories(clap-synth-fixture SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/third_party/clap/include" "${PROJECT_SOURCE_DIR}/third_party/vst3")
|
||||||
|
add_library(vst2-synth-fixture MODULE tests/plugins/vst2_synth_fixture.c)
|
||||||
|
xtc_warnings(vst2-synth-fixture)
|
||||||
|
set_target_properties(vst2-synth-fixture PROPERTIES PREFIX "" SUFFIX ".so")
|
||||||
|
target_include_directories(vst2-synth-fixture SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/third_party/clap/include" "${PROJECT_SOURCE_DIR}/third_party/vst3")
|
||||||
|
add_library(vst3-synth-fixture MODULE tests/plugins/vst3_synth_fixture.c)
|
||||||
|
xtc_warnings(vst3-synth-fixture)
|
||||||
|
set_target_properties(vst3-synth-fixture PROPERTIES PREFIX "" SUFFIX ".so")
|
||||||
|
target_include_directories(vst3-synth-fixture SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/third_party/clap/include" "${PROJECT_SOURCE_DIR}/third_party/vst3")
|
||||||
|
if(XTC_LADSPA_AVAILABLE)
|
||||||
|
xtc_test(plugins test_plugins $<TARGET_FILE:plugin-fixture> fixture)
|
||||||
|
endif()
|
||||||
|
xtc_test(modern-plugins test_modern_plugins $<TARGET_FILE:clap-fixture> $<TARGET_FILE:vst2-fixture> $<TARGET_FILE:vst3-fixture>)
|
||||||
|
xtc_test(instruments test_instruments $<TARGET_FILE:clap-synth-fixture> $<TARGET_FILE:vst2-synth-fixture> $<TARGET_FILE:vst3-synth-fixture>)
|
||||||
|
xtc_test(startup xtc-check)
|
||||||
|
xtc_test(native-example native-gain)
|
||||||
|
add_test(NAME project-inspection COMMAND ${Python3_EXECUTABLE} "${PROJECT_SOURCE_DIR}/tests/integration/test_project_inspection.py" $<TARGET_FILE:xtc-check>)
|
||||||
|
set_tests_properties(project-inspection PROPERTIES WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
|
||||||
|
add_test(NAME benchmark-tools COMMAND ${Python3_EXECUTABLE} "${PROJECT_SOURCE_DIR}/tests/tools/test_benchmark.py")
|
||||||
|
set_tests_properties(benchmark-tools PROPERTIES WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
|
||||||
|
if(JACK_FOUND AND XTC_WITH_JACK)
|
||||||
|
xtc_executable(test_backend tests/unit/test_backend.c)
|
||||||
|
xtc_test(backend test_backend)
|
||||||
|
foreach(kind jack jack_audio jack_midi)
|
||||||
|
xtc_executable(test_${kind} tests/integration/test_${kind}.c)
|
||||||
|
if(XTC_ENABLE_LIVE_TESTS)
|
||||||
|
string(REPLACE "_" "-" name "${kind}")
|
||||||
|
xtc_test(${name} test_${kind})
|
||||||
|
set_tests_properties(${name} PROPERTIES LABELS live RUN_SERIAL TRUE)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
29
cmake/Variants.cmake
Normal file
29
cmake/Variants.cmake
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Each compiler/flag variant has its own cache and products.
|
||||||
|
foreach(variant debug release sanitize)
|
||||||
|
set(extra)
|
||||||
|
if(CMAKE_CXX_COMPILER)
|
||||||
|
list(APPEND extra "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
|
||||||
|
endif()
|
||||||
|
if(variant STREQUAL debug)
|
||||||
|
set(kind Debug)
|
||||||
|
else()
|
||||||
|
set(kind Release)
|
||||||
|
list(APPEND extra -DXTC_REPRODUCIBLE=ON)
|
||||||
|
endif()
|
||||||
|
if(variant STREQUAL sanitize)
|
||||||
|
set(kind Debug)
|
||||||
|
list(APPEND extra -DXTC_SANITIZE=ON -DXTC_BUILD_GUI=OFF -DCMAKE_C_COMPILER=clang)
|
||||||
|
set(target test-sanitize)
|
||||||
|
else()
|
||||||
|
set(target ${variant})
|
||||||
|
endif()
|
||||||
|
add_custom_target(${target}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -S "${PROJECT_SOURCE_DIR}" -B "${CMAKE_CURRENT_BINARY_DIR}/${variant}"
|
||||||
|
-DCMAKE_BUILD_TYPE=${kind} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||||
|
-DXTC_WITH_JACK=${XTC_WITH_JACK} -DXTC_WITH_LADSPA=${XTC_WITH_LADSPA}
|
||||||
|
-DXTC_BUILD_GUI=${XTC_BUILD_GUI} ${extra}
|
||||||
|
COMMAND ${CMAKE_COMMAND} --build "${CMAKE_CURRENT_BINARY_DIR}/${variant}" --parallel 3
|
||||||
|
COMMAND ${CMAKE_CTEST_COMMAND} --test-dir "${CMAKE_CURRENT_BINARY_DIR}/${variant}" --output-on-failure
|
||||||
|
USES_TERMINAL VERBATIM)
|
||||||
|
endforeach()
|
||||||
|
add_custom_target(check-development DEPENDS check analyze test-sanitize)
|
||||||
|
|
@ -109,12 +109,9 @@ implemented.
|
||||||
|
|
||||||
## Verification
|
## 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,
|
malformed inputs, missing/relinked assets, SPSC concurrency/overflow/cleanup,
|
||||||
and record -> save/reopen -> exact playback through the backend callback. make
|
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
|
||||||
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
|
|
||||||
-> saved/reopened project -> graph playback -> capture assertion. Physical
|
-> saved/reopened project -> graph playback -> capture assertion. Physical
|
||||||
input/output, device latency, slow-disk endurance and server loss during a real
|
input/output, device latency, slow-disk endurance and server loss during a real
|
||||||
recording remain unverified.
|
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
|
canonical 44-byte mono float32 header only, not arbitrary damaged WAVs. Recovery
|
||||||
is explicit and control-thread only; no orphan scan runs during playback.
|
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
|
and draining, destination races/symlinks, a child-local disk-size limit, prefix
|
||||||
recovery and incomplete/missing asset reopening. `test-recovery` retains process
|
recovery and incomplete/missing asset reopening. `test-recovery` retains process
|
||||||
kill coverage; `test_audio` covers saturation and concurrent drain. This is
|
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
|
external replacement. Cache allocation failure omits previews without changing
|
||||||
music metadata.
|
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
|
seeks, shortened media tails, one-frame files, source/project limits, capacity
|
||||||
rollback, duplication/fade inheritance, persistence/invalid metadata, undo, peak
|
rollback, duplication/fade inheritance, persistence/invalid metadata, undo, peak
|
||||||
bins after source removal and byte-identical source preservation. GUI tests
|
bins after source removal and byte-identical source preservation. GUI tests
|
||||||
|
|
|
||||||
|
|
@ -150,13 +150,13 @@ maps and physical recording-offset calibration remain unsupported.
|
||||||
## Verification and Listening
|
## Verification and Listening
|
||||||
|
|
||||||
```
|
```
|
||||||
make all test gui test-reliability test-workflow test-gui test-gui-jack
|
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
|
||||||
make test-jack test-jack-audio test-jack-midi test-performance
|
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-jack test-jack-audio test-jack-midi test-performance
|
||||||
make test-sanitize analyze
|
cmake --build build --target test-sanitize analyze
|
||||||
make quality-preview
|
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
|
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
|
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,
|
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
|
Physical-device listening and human listening acceptance are **not yet
|
||||||
verified**.
|
verified**.
|
||||||
|
|
||||||
`make quality-preview` writes ignored build artifacts `quality-raw.wav` and
|
`cmake --build build --target quality-preview` writes ignored build artifacts `quality-raw.wav` and
|
||||||
`quality-smooth.wav` in BUILD_DIR using `examples/quality_preview.c`. Compare at
|
`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
|
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.
|
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
|
Check that fades reduce edge clicks, do not add noise and do not unexpectedly
|
||||||
|
|
|
||||||
439
docs/BUILD.md
439
docs/BUILD.md
|
|
@ -1,325 +1,188 @@
|
||||||
# Build Baseline
|
# Building xtc with CMake
|
||||||
|
|
||||||
The existing layout is retained: public C headers in `include/xtc`, C
|
The root `CMakeLists.txt` is the authoritative build. C99 engine/model/DSP and
|
||||||
implementation modules under `src`, optional C++ GUI under `src/gui`, and tests
|
public C APIs remain in `include/xtc` and `src`; C++17 is used for the optional
|
||||||
under `tests`. `src/main.c` is a minimal headless startup/shutdown check; it
|
FLTK interface and SDK examples. The small root Makefile only forwards common
|
||||||
does not initialize audio devices or open a GUI.
|
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
|
```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
|
./build/xtc-check
|
||||||
make debug
|
./build/xtc # when FLTK was found
|
||||||
make gui
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`all` builds the static C library and startup check. `test` runs the existing
|
All binaries and the static `libxtc.a` are in the chosen binary directory.
|
||||||
core/offline tests, concurrent plan-handoff stress, JACK fault injection (when
|
The default build includes offline test binaries and plugin fixtures. CTest
|
||||||
JACK headers are available), and the startup check. `debug` builds and tests
|
runs offline, fault-injection, plugin, recovery, capacity/endurance, and available
|
||||||
separately in `build/debug`. `gui` builds the FLTK shell with backend controls
|
GUI tests; live JACK tests require explicit opt-in. GUI tests use Xvfb and
|
||||||
and status. The shell starts with a silent graph and never connects physical
|
startup checks also require xdotool. No physical ports are connected by tests.
|
||||||
ports. Generated files remain under `build` and header changes trigger rebuilds.
|
CTest runs source-relative fixtures with an explicit working directory.
|
||||||
Compiler, flags, `BUILD_DIR`, `PKG_CONFIG`, `FLTK_CONFIG`, and installation
|
Assertions stay enabled in optimized test builds.
|
||||||
`PREFIX` can be overridden through Make variables. C uses C99; GUI uses C++17.
|
|
||||||
|
|
||||||
---
|
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 |
|
| `BUILD_TESTING` | `ON` | Build/register the test suite |
|
||||||
| GNU Make | 4.4.1 | Build and test driver |
|
| `XTC_BUILD_GUI` | `ON` | Discover FLTK and build the application when available |
|
||||||
| pkg-config | 3.0.10 | Development package discovery |
|
| `XTC_WITH_JACK` | `ON` | Discover/build the JACK/PipeWire backend |
|
||||||
| FLTK | 1.4.5 | Optional GUI; discovered through `fltk-config` |
|
| `XTC_WITH_LADSPA` | `ON` | Enable LADSPA when the system header exists |
|
||||||
| JACK | 3.1609.0 (pkg-config) | Optional JACK backend (PipeWire compatibility library) |
|
| `XTC_ENABLE_LIVE_TESTS` | `OFF` | Register software JACK loopback and GUI/JACK workflows |
|
||||||
| ALSA | 1.2.16.1 (pkg-config) | Future MIDI candidate; not linked yet |
|
| `XTC_SANITIZE` | `OFF` | Address/undefined sanitizers, frame pointers |
|
||||||
| Clang | 23.1.3 | Alternative compiler / diagnostics |
|
| `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
|
Use `-DNAME=VALUE` during configuration, not Make variables. Standard CMake
|
||||||
and require no external test framework. FLTK has no `fltk.pc` on this host; the
|
settings include `CMAKE_C_COMPILER`, `CMAKE_CXX_COMPILER`, `CMAKE_BUILD_TYPE`,
|
||||||
Makefile tries pkg-config first, then `fltk-config`.
|
`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:
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make all test gui debug
|
cmake -S . -B build/minimal -G Ninja -DCMAKE_BUILD_TYPE=Release \
|
||||||
make test-jack
|
-DXTC_BUILD_GUI=OFF -DXTC_WITH_JACK=OFF -DXTC_WITH_LADSPA=OFF
|
||||||
# Extended live run after building the integration binary:
|
cmake --build build/minimal --parallel
|
||||||
./build/test_jack 30
|
ctest --test-dir build/minimal --output-on-failure
|
||||||
# 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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Normal, sanitizer and no-JACK tests pass. ThreadSanitizer reports no race in
|
This path needs no C++ compiler, FLTK, JACK or LADSPA development files. CLAP and
|
||||||
2,000 concurrent submissions. The 30-second live loopback test passed at 48 kHz
|
VST3 C headers stay pinned in `third_party`; VST2 uses original declarations.
|
||||||
with zero xruns and ten restart cycles; see tests/integration/README.md. Live
|
No external plugin or SDK is included in normal packages. See [LICENSES.md](LICENSES.md).
|
||||||
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.
|
|
||||||
|
|
||||||
---
|
## Focused tests and tools
|
||||||
|
|
||||||
## GUI Shell Verification
|
Build before invoking CTest, or use `check`, which builds the test dependencies:
|
||||||
|
|
||||||
```sh
|
```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
|
Each registered root test also has a `test-NAME` build target (for example
|
||||||
server. `test-gui-jack` needs a running server; it creates no physical routes.
|
`test-core`, `test-gui`, `test-track-fx`). `test-builtins` aliases `test-builtin`.
|
||||||
Both passed, including repeated active-client close and reconnect. The GUI also
|
`gui` builds the optional main application. Preview targets write WAVs below the
|
||||||
builds without JACK metadata and reports unsupported backend support at startup.
|
binary directory without playback. Screenshot commands are in
|
||||||
A live keyboard/visual smoke run passed under Xvfb. Clang ASan/UBSan GUI tests
|
[the gallery](../screenshots/README.md). These commands assume configuration
|
||||||
passed with a suppression limited to the installed fontconfig library's
|
has already completed; feature-specific docs use the same convention.
|
||||||
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.
|
|
||||||
|
|
||||||
---
|
To qualify live software routing against an **existing** JACK-compatible server:
|
||||||
|
|
||||||
## Graph Editor Verification
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make clean all test gui debug test-gui test-gui-jack
|
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON
|
||||||
make BUILD_DIR=build/nojack PKG_CONFIG=false all test gui test-gui
|
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,
|
Live tests are serialized. They neither start/reconfigure the server nor
|
||||||
transactional rejection/deletion/disconnect and known rendered samples before
|
establish physical-device acceptance. See [AUDIO_ENGINE.md](AUDIO_ENGINE.md).
|
||||||
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.
|
|
||||||
|
|
||||||
---
|
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
|
```sh
|
||||||
make clean all test gui debug test-gui test-gui-jack
|
cmake -S . -B build/release -DCMAKE_BUILD_TYPE=Release -DXTC_REPRODUCIBLE=ON \
|
||||||
make BUILD_DIR=build/nojack PKG_CONFIG=false all test gui test-gui
|
-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
|
For uninstall, configure with `-DCMAKE_INSTALL_PREFIX=/usr` first when that is
|
||||||
transport conversion, exact file roundtrip with graph rendering, exhaustive
|
the desired permanent prefix, or invoke the generated `xtc-install.cmake` with
|
||||||
fixture truncations, byte mutations, failed saves and temporary cleanup. GUI
|
`-DCMAKE_INSTALL_PREFIX=/usr -DXTC_UNINSTALL=ON -P` explicitly. The `--prefix`
|
||||||
tests cover region gestures, zoom, save/load and backend rollback. Live JACK
|
install override does not persist in CMake's cache. Prefer setting the prefix at
|
||||||
tests verify playhead advance, pause and resume without creating routes. The
|
configure time for a matching install/uninstall pair. Standard `DESTDIR` staging
|
||||||
updated core and GUI tests pass Clang ASan/UBSan (the GUI uses the existing
|
never enters installed metadata. The audited Python installer retains exact
|
||||||
fontconfig-only LSan suppression). An Xvfb/xdotool visual check created a track
|
owned-file inventory, atomic file replacement and symlink protection.
|
||||||
and region, moved it one bar and zoomed the canvas. No dependencies were added.
|
|
||||||
|
|
||||||
Audio assets and recording are supported. Silent arrangement regions, fixed
|
`test-install` and `test-install-layout` stage into temporary directories and
|
||||||
tempo/4/4, no undo, no persisted GUI layout, and unverified physical-device
|
compile installed C/C++ consumers. `dist` exports indexed files; `test-release`
|
||||||
playback/endurance remain explicit limits.
|
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.
|
||||||
|
|
||||||
---
|
Clean products with `cmake --build build --target clean`; to discard the cache,
|
||||||
|
remove only the selected build directory. Never configure in the source tree.
|
||||||
## Audio Verification
|
Historical validation entries in ROADMAP describe the build used at that time;
|
||||||
|
Phase 108 records the CMake migration and its verified results.
|
||||||
```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.
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
allocation, file access, library loading, locking or GUI calls.
|
||||||
|
|
||||||
Validation:
|
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
|
(join onto one line). `test-builtins` checks impulse tails, dry mix, feedback
|
||||||
bounds, block partition consistency, note release/panic and instrument/effect
|
bounds, block partition consistency, note release/panic and instrument/effect
|
||||||
project round trips.
|
project round trips.
|
||||||
|
|
@ -47,7 +47,7 @@ project round trips.
|
||||||
|
|
||||||
## Acceptance Checks
|
## 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
|
checks all four device identities and GUI paths without external plugin
|
||||||
binaries. The reliability runner fails each internal preparation allocation in
|
binaries. The reliability runner fails each internal preparation allocation in
|
||||||
turn and forbids allocation/free, direct file I/O and blocking locks during
|
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
|
reset/seek/panic. The existing portability suite verifies older project
|
||||||
migrations.
|
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
|
`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
|
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
|
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
|
energy, bounded extreme feedback/diffusion and graph/direct stereo output
|
||||||
(including the engine's subnormal-to-zero policy). GUI tests save/reopen both
|
(including the engine's subnormal-to-zero policy). GUI tests save/reopen both
|
||||||
identities; callback guards and ASan/UBSan cover processing.
|
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.
|
listening remains pending.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -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:
|
endpoints, seek/plan replacement, sustain/retrigger and controller ramp tests:
|
||||||
|
|
||||||
```sh
|
```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,
|
Physical controller devices and listening remain unqualified; no tempo map,
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ edits do not request extra approval. No operation here deletes source media.
|
||||||
|
|
||||||
## Evidence and Manual Procedure
|
## 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
|
covers core commands, grouped gestures/batches, backend rollback, selection
|
||||||
retention, take undo/redo and real software JACK state restoration. The GUI
|
retention, take undo/redo and real software JACK state restoration. The GUI
|
||||||
fixture injects history-reservation failure before graph/map/import publication
|
fixture injects history-reservation failure before graph/map/import publication
|
||||||
|
|
|
||||||
|
|
@ -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
|
only after successful close. The entry point catches C++ exceptions before
|
||||||
process exit. Backend operations return C error codes throughout.
|
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
|
backend under Xvfb, including control errors, startup without JACK, partially
|
||||||
initialized handles, server/format notifications, view switching, retrying
|
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
|
JACK-compatible server, tests repeated start/stop, reconnect and active-client
|
||||||
close, and creates no routes. Physical playback is outside this shell. See
|
close, and creates no routes. Physical playback is outside this shell. See
|
||||||
BUILD.md and the integration test README for sanitizer limitations and keyboard
|
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
|
zero. Failed candidate installation now refreshes the actual backend state even
|
||||||
when the previous document is retained.
|
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
|
stereo render comparisons across destruction/recreation of the GUI and live
|
||||||
playhead/meter/transport checks. `test-gui` covers stop/seek failure and
|
playhead/meter/transport checks. `test-gui` covers stop/seek failure and
|
||||||
recording guards. No project files need manual editing for this workflow.
|
recording guards. No project files need manual editing for this workflow.
|
||||||
|
|
|
||||||
10
docs/IDEA.md
10
docs/IDEA.md
|
|
@ -172,7 +172,7 @@ Adapt this to an existing repository instead of replacing it blindly.
|
||||||
xtc/
|
xtc/
|
||||||
├── README.md
|
├── README.md
|
||||||
├── LICENSE
|
├── LICENSE
|
||||||
├── Makefile
|
├── CMakeLists.txt
|
||||||
├── docs/
|
├── docs/
|
||||||
│ ├── ARCHITECTURE.md
|
│ ├── ARCHITECTURE.md
|
||||||
│ ├── AUDIO_ENGINE.md
|
│ ├── AUDIO_ENGINE.md
|
||||||
|
|
@ -624,8 +624,8 @@ make an edit partially visible if it fails validation.
|
||||||
|
|
||||||
### Build system
|
### Build system
|
||||||
|
|
||||||
Use a straightforward Makefile unless the existing repository has a sound reason
|
Use the root CMake project and CTest. Keep SDK integrations optional and
|
||||||
to use another build system.
|
all generated output in separate build directories.
|
||||||
|
|
||||||
The build must:
|
The build must:
|
||||||
|
|
||||||
|
|
@ -736,7 +736,7 @@ feature is exciting.
|
||||||
### Repository and design baseline
|
### Repository and design baseline
|
||||||
|
|
||||||
- Inspect the repository and available toolchain.
|
- 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
|
- Verify C compiler, C++ compiler, FLTK, audio development headers, and test
|
||||||
tools.
|
tools.
|
||||||
- Record dependency and licensing decisions.
|
- Record dependency and licensing decisions.
|
||||||
|
|
@ -851,7 +851,7 @@ Start with the **repository and design baseline** only.
|
||||||
development packages, `pkg-config`, and test tools.
|
development packages, `pkg-config`, and test tools.
|
||||||
3. Do not install packages or modify system configuration without permission.
|
3. Do not install packages or modify system configuration without permission.
|
||||||
4. Propose the smallest initial source tree compatible with this brief.
|
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
|
6. Create a minimal program that builds and exits cleanly; do not yet implement
|
||||||
a full audio engine or GUI.
|
a full audio engine or GUI.
|
||||||
7. Build it and run its tests.
|
7. Build it and run its tests.
|
||||||
|
|
|
||||||
10
docs/JUCE.md
10
docs/JUCE.md
|
|
@ -17,8 +17,9 @@ normal builds or automatically installed. The integration uses:
|
||||||
|
|
||||||
Synthesis is the real xtc **Soft Keys** implementation, called through
|
Synthesis is the real xtc **Soft Keys** implementation, called through
|
||||||
`xtc_plugin_*`. C++ remains confined to the optional integration. The SDK build
|
`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
|
links the root CMake PIC C archive through target dependencies; standalone SDK
|
||||||
application and existing build directories are not modified.
|
configuration adds the same CMake core with JACK/FLTK disabled. SDK targets do
|
||||||
|
not install plugins or modify other binary directories.
|
||||||
|
|
||||||
## Screenshots
|
## 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.
|
to the normal xtc install/package targets.
|
||||||
|
|
||||||
JUCE requires C++17 and its Linux development dependencies, including ALSA,
|
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`
|
examples. Xvfb runs automated checks without a desktop. The SDK's `juceaide`
|
||||||
tool is compiled at configure time. Builds are substantially heavier than the
|
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
|
SDKs or install system packages. Only the inspected SDK revision has been
|
||||||
qualified; use the documented revision for reproducibility.
|
qualified; use the documented revision for reproducibility.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,11 @@ redistributing dependencies. The default install uses system shared libraries.
|
||||||
| HarfBuzz, Wayland, libdecor, xkbcommon | MIT-family licenses; check each shipped package. |
|
| HarfBuzz, Wayland, libdecor, xkbcommon | MIT-family licenses; check each shipped package. |
|
||||||
| X11 libraries | MIT/X11-family notices. |
|
| X11 libraries | MIT/X11-family notices. |
|
||||||
| D-Bus | AFL-2.1 OR GPL-2.0-or-later. |
|
| 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
|
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
|
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.
|
packages were installed and no application dependency was added.
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
# Linux Setup and Installation
|
# 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
|
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
|
enable the GUI; JACK-compatible development files enable the optional audio/MIDI
|
||||||
backend. Packaging/install tests additionally use Python 3.12+ (standard library
|
backend. Build/test/install tooling uses Python 3.12+ (standard library only). No command starts a server, installs dependencies or changes system
|
||||||
only). No command starts a server, installs dependencies or changes system
|
|
||||||
settings.
|
settings.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make all test
|
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
|
||||||
make gui
|
cmake --build build --parallel
|
||||||
|
ctest --test-dir build --output-on-failure
|
||||||
./build/xtc
|
./build/xtc
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -31,17 +31,20 @@ files.
|
||||||
|
|
||||||
## Staged Installation
|
## Staged Installation
|
||||||
|
|
||||||
Core-only installation retains the original `make install` behavior and now adds
|
CMake installation includes the core, xtc-check, pkg-config metadata, licenses
|
||||||
xtc-check, pkg-config metadata, license and documentation. install-gui adds the
|
and documentation. `XTC_INSTALL_GUI` defaults on when FLTK was found, adding the
|
||||||
GUI executable and desktop launcher. Defaults to PREFIX=/usr/local:
|
application and desktop launcher. Use `-DXTC_INSTALL_GUI=OFF` for core-only
|
||||||
|
installation. The prefix defaults to `/usr/local`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make install-gui DESTDIR="$PWD/build/stage" PREFIX=/usr
|
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
make uninstall DESTDIR="$PWD/build/stage" 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
|
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
|
`$HOME/.local` and ensure its bin is in PATH. Prefixes containing spaces are
|
||||||
tested; shell metacharacters/newlines, quotes, dollar signs and backslashes are
|
tested; shell metacharacters/newlines, quotes, dollar signs and backslashes are
|
||||||
not supported. No root installation is performed by tests. Uninstall from the
|
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.
|
compiler; expose PREFIX/lib/pkgconfig through PKG_CONFIG_PATH when needed.
|
||||||
Static backend consumers need JACK if that optional backend was built; the pc
|
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.
|
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.
|
Python is not needed to run the installed executables or library.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Binary/Development Archive
|
## Binary/Development Archive
|
||||||
|
|
||||||
`make package` creates a system-linked Linux archive plus SHA-256 sidecar below
|
`cmake --build build --target package-binary` creates a system-linked Linux archive plus SHA-256 sidecar below
|
||||||
BUILD_DIR; `make test-package` verifies its contents. It includes usr/bin,
|
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),
|
headers/static library/pkg-config metadata, desktop file (when FLTK is present),
|
||||||
manuals, baseline and MIT license. No shared library, third-party plugin, media,
|
manuals, baseline and MIT license. No shared library, third-party plugin, media,
|
||||||
service or dependency installer is bundled. `BINARY_MANIFEST.json` lists file
|
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
|
(`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
|
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
|
archive's pkg-config prefix is relative to its installed location; normal
|
||||||
`make install` retains explicit PREFIX. Use the matching source's uninstall with
|
`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
|
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
|
files are retained by source uninstall. This local tar package is not a
|
||||||
pacman/RPM/deb registration or public distribution.
|
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
|
headlessly as well. Missing runtime GUI libraries are loader errors: install the
|
||||||
distribution's compatible dependencies or rebuild the core-only configuration.
|
distribution's compatible dependencies or rebuild the core-only configuration.
|
||||||
Build without optional libraries using a fresh directory,
|
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.
|
setting or package is changed by tests.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
## Supported Development Target
|
## 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
|
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.
|
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
|
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
|
bump, Git tag, public upload or external release is performed by local
|
||||||
targets.
|
targets.
|
||||||
2. Run warning-enabled
|
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.
|
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
|
dependency builds. GUI leak checks use only the documented fontconfig
|
||||||
suppression; core tests use none. Run publication/recording race tests as
|
suppression; core tests use none. Run publication/recording race tests as
|
||||||
described in RELIABILITY.md. Sanitizers are not latency qualification.
|
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
|
host/compiler/flags against a reviewed baseline. Investigate regressions; do
|
||||||
not weaken thresholds or replace evidence without explanation.
|
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
|
hashes, dynamic dependency names and licenses. Source exports rebuild twice
|
||||||
with identical artifacts on this host. Repeat binary packaging compares
|
with identical artifacts on this host. Repeat binary packaging compares
|
||||||
bytes.
|
bytes.
|
||||||
|
|
|
||||||
10
docs/MIDI.md
10
docs/MIDI.md
|
|
@ -74,11 +74,11 @@ zoom yet. Note edits participate in project snapshot undo/redo.
|
||||||
|
|
||||||
## Verification
|
## 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
|
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.
|
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
|
panic, disconnection and saved/reopened scheduled playback. JACK port discovery
|
||||||
may lag activation under PipeWire; the test waits before connecting. Physical
|
may lag activation under PipeWire; the test waits before connecting. Physical
|
||||||
MIDI devices, bridge/device loss behind an unchanged port, latency and
|
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
|
reordering. The renderer rejects malformed/unsorted/out-of-range events before
|
||||||
touching output or runtime; raw velocity-zero note-ons decode to note-off.
|
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,
|
repeats/fresh IDs, rejected batch rollback, capacity, undo snapshots,
|
||||||
equal-offset live order, adjacent/overlapping notes, exact block partitions and
|
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
|
undo/redo and engine reinstallation. Listening and physical MIDI-device
|
||||||
validation remain pending.
|
validation remain pending.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,8 @@ The code is built with warnings enabled and tested. Reproduce the core,
|
||||||
transaction and allocation-failure checks with:
|
transaction and allocation-failure checks with:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make BUILD_DIR=build/roadmap-audit all gui test-reliability
|
cmake --build build/roadmap-audit --parallel && cmake --build build/roadmap-audit --target gui test-reliability
|
||||||
make BUILD_DIR=build/roadmap-audit test-gui-modern-editing
|
cmake --build build/roadmap-audit --target test-gui-modern-editing
|
||||||
```
|
```
|
||||||
|
|
||||||
The full GUI, instrument/effect plugin fixtures, software JACK lifecycle, Clang
|
The full GUI, instrument/effect plugin fixtures, software JACK lifecycle, Clang
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Native C Processor API, Version 1
|
# Native C Processor API, Version 1
|
||||||
|
|
||||||
`xtc_native.h` defines a small compile-time extension boundary for trusted C99
|
`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
|
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
|
API for this release, not a promise of binary compatibility across
|
||||||
builds/platforms. There is no module scanner, dynamic loader, SDK dependency or
|
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,
|
Tests cover ABI/size/field rejection, descriptor copying, aliased buffers,
|
||||||
prepare/process failures, stereo compile cleanup, retirement/destruction outside
|
prepare/process failures, stereo compile cleanup, retirement/destruction outside
|
||||||
processing, event offsets, seek note reset, source ports, instrument-buffer
|
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).
|
`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.
|
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
|
`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.
|
both. The instrument has immediate note-off and no voice stealing/release tail.
|
||||||
|
|
||||||
Descriptors have an exact ABI version and structure size, a persistent
|
Descriptors have an exact ABI version and structure size, a persistent
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ termination remain unqualified.
|
||||||
|
|
||||||
## Matrix, Capacity and Contention Checks
|
## 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
|
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
|
separately from 300 process calls, mean/p99/max, block deadline, mean load, and
|
||||||
paired graph buffer bytes. Timing, sorting, allocation and logging happen
|
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.
|
reviewing changes and conditions.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make benchmark test-performance test-scale test-stress
|
cmake --build build --target benchmark test-performance test-scale test-stress
|
||||||
make benchmark-compare BENCHMARK_MAX_REGRESSION=1.5
|
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:
|
# 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.
|
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
|
baseline to make a regression disappear. Scheduling, clocks, thermal state and
|
||||||
shared-machine contention still affect results. No real-time scheduling/pinning
|
shared-machine contention still affect results. No real-time scheduling/pinning
|
||||||
or external profiler is required. CPU-pressure runs are correctness checks, not
|
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
|
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
|
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.
|
synthetic cases do not qualify every possible dense graph or plugin chain.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make benchmark benchmark-project
|
cmake --build build --target benchmark benchmark-project
|
||||||
make benchmark-compare
|
cmake --build build --target benchmark-compare
|
||||||
make benchmark-project-compare
|
cmake --build build --target benchmark-project-compare
|
||||||
# Baselines must match the current CPU/compiler/flags and workload.
|
# 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
|
./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
|
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
|
## Endurance, Faults and Callback Audit
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make test-soak test-stress test-stress-plugins
|
cmake --build build --target test-soak test-stress test-stress-plugins
|
||||||
make test-stress STRESS_ROUNDS=10
|
cmake -S . -B build -DXTC_STRESS_ROUNDS=10 && cmake --build build --target test-stress
|
||||||
./build/test_soak 10000000
|
./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
|
`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):
|
Reproduce in an isolated build (GNU gprof must already be installed):
|
||||||
|
|
||||||
```sh
|
```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
|
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
|
gprof build/profile/test_performance build/profile/gmon.* > build/profile/profile.txt
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,8 @@ binary/version identities.
|
||||||
## Repeatable Acceptance
|
## Repeatable Acceptance
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make all test gui test-plugins test-gui-plugins analyze
|
cmake --build build --parallel && cmake --build build --target check gui test-plugins test-gui-plugins analyze
|
||||||
make test-plugins-real
|
cmake --build build --target test-plugins-real
|
||||||
```
|
```
|
||||||
|
|
||||||
The first plugin target builds an original MIT shared-library fixture with gain,
|
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.
|
block. VST2 has no process error return.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make all test gui test-modern-plugins test-gui-modern-plugins
|
cmake --build build --parallel && cmake --build build --target check gui test-modern-plugins test-gui-modern-plugins
|
||||||
make test-sanitize analyze
|
cmake --build build --target test-sanitize analyze
|
||||||
```
|
```
|
||||||
|
|
||||||
Original CLAP/VST2/VST3 shared-library fixtures exercise exact in-place and
|
Original CLAP/VST2/VST3 shared-library fixtures exercise exact in-place and
|
||||||
|
|
|
||||||
|
|
@ -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
|
the existing destination are preserved on load failure. No automatic
|
||||||
unknown-field stripping or media deletion occurs.
|
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
|
checked-in v1–v10 fixtures (including missing v5/v6 plugins), current exact
|
||||||
roundtrips, moved-folder playback from a different cwd, missing media retention,
|
roundtrips, moved-folder playback from a different cwd, missing media retention,
|
||||||
unknown records, every truncation and deterministic byte mutations, malformed
|
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
|
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
|
waveform cache or source audio is serialized. Checked-in v1–v7 migrations, v8
|
||||||
exact roundtrips, malformed new metadata and byte-mutation tests cover the
|
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
|
sample rate, block limits and device routing are runtime dependencies; loading
|
||||||
metadata does not restore device connections.
|
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
|
input, retained-state diagnostics, CLI dependency inspection, and deterministic
|
||||||
save faults at flush, file sync, close, rename and directory sync. Pre-rename
|
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
|
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
|
failure reports I/O while leaving a complete new document; inspect it before
|
||||||
retrying. Fault wrappers are linked into tests only. These tests complement
|
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.
|
behavior.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -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
|
history. Existing finalized files are protected against the tested process-level
|
||||||
failures; unsaved edits/in-flight takes can still be lost.
|
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
|
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
|
eight project writers while temporaries are visible, and kills a recorder after
|
||||||
draining but before finalization. Complete old/new destinations and explicit
|
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
|
float32 WAV from complete on-disk frames, ignoring a trailing partial frame. It
|
||||||
never changes the source or overwrites an existing destination. This supersedes
|
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
|
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
|
## 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
|
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
|
bytes and clean temporary files. Post-rename sync errors leave a complete new
|
||||||
file and return failure; there is no rollback after replacement. Load
|
file and return failure; there is no rollback after replacement. Load
|
||||||
|
|
|
||||||
|
|
@ -3,29 +3,32 @@
|
||||||
Source packaging, staged install/uninstall and repeatable builds are testable.
|
Source packaging, staged install/uninstall and repeatable builds are testable.
|
||||||
It does not turn the prototype into a production-qualified DAW. The version
|
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
|
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
|
## Build and Package
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make release
|
cmake --preset release
|
||||||
make test-install
|
cmake --build --preset release --parallel
|
||||||
make test-recovery test-performance
|
ctest --preset release
|
||||||
make dist
|
cmake --build build/release --target test-install test-install-layout
|
||||||
make test-release
|
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
|
The release preset builds optimized, warning-enabled C/C++ code, test binaries
|
||||||
in BUILD_DIR/release with no debug paths, a source-prefix map, deterministic ar
|
and the available GUI in `build/release`, with source/binary prefix maps,
|
||||||
metadata and FLTK include/define flags rather than distribution-specific LTO
|
no debug information, deterministic archive metadata and assertions retained.
|
||||||
flags. It retains assertions so the test harness actually runs. dist creates
|
FLTK discovery takes include/define flags without overriding the project's
|
||||||
BUILD_DIR/xtc-0.1.0.tar.gz using Python's standard library. It includes only Git
|
optimization settings. `dist` creates `xtc-0.1.0.tar.gz` below the binary
|
||||||
indexed regular files (working-tree contents, including staged new files), plus
|
directory using Python's standard library. It includes only Git-indexed regular
|
||||||
a source manifest; stage intended files first and check `git diff --cached`.
|
files (working-tree contents, including staged new files), plus a source
|
||||||
Untracked files, ignored build output and .git are excluded. Exported archives
|
manifest; stage intended files first and check `git diff --cached`. Untracked
|
||||||
can reproduce themselves without Git using SOURCE_MANIFEST.json.
|
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
|
Archive order, permissions, ownership, gzip filename and timestamps are
|
||||||
normalized. SOURCE_DATE_EPOCH defaults to 0; set an unsigned 32-bit epoch
|
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
|
dirty-tree archive as an attested release. No artifact is uploaded by these
|
||||||
targets.
|
targets.
|
||||||
|
|
||||||
test-release unpacks the source into two different temporary paths, runs release
|
test-release unpacks the source into two different temporary paths, configures
|
||||||
in each, compares libxtc.a/xtc-check/optional xtc SHA-256 values, and repacks
|
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
|
each export to compare archive bytes. This verifies reproducibility for the same
|
||||||
host, compiler, flags and dependency versions. It does not promise bit-identical
|
host, compiler, flags and dependency versions. It does not promise bit-identical
|
||||||
output across distributions, compilers or library updates.
|
output across distributions, compilers or library updates.
|
||||||
|
|
@ -66,11 +69,11 @@ shared-library extension ABI in this release.
|
||||||
|
|
||||||
## Local Binary Packaging and Installed Workflow
|
## 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
|
DESTDIR, writes a normalized Linux binary/development archive, checks its
|
||||||
SHA-256 sidecar and per-file manifest, relocatable pkg-config paths and headless
|
SHA-256 sidecar and per-file manifest, relocatable pkg-config paths and headless
|
||||||
commands. Same-host repeated packaging is byte-identical; dependency versions
|
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
|
repeats installation to verify repair/upgrade of owned files while preserving an
|
||||||
unrelated sentinel, then compiles both C99 and C++17 installed consumers that
|
unrelated sentinel, then compiles both C99 and C++17 installed consumers that
|
||||||
create MIDI, save/reopen and compare nonzero exact rendering. Removal remains
|
create MIDI, save/reopen and compare nonzero exact rendering. Removal remains
|
||||||
|
|
@ -88,21 +91,28 @@ pending.
|
||||||
|
|
||||||
## Release Workflow
|
## Release Workflow
|
||||||
|
|
||||||
Installation now shares one explicit file inventory with uninstallation.
|
Installation shares the existing explicit owned-file inventory with removal.
|
||||||
GNU-style `exec_prefix`, `bindir`, `libdir`, `includedir`, `datarootdir`,
|
Use CMake's `CMAKE_INSTALL_PREFIX`, `CMAKE_INSTALL_BINDIR`,
|
||||||
`datadir`, `docdir`, `pkgconfigdir` and the xtc-specific `licensedir`,
|
`CMAKE_INSTALL_LIBDIR`, `CMAKE_INSTALL_INCLUDEDIR`, `CMAKE_INSTALL_DATAROOTDIR`
|
||||||
`examplesdir`, `desktopdir` can be overridden alongside `PREFIX`/`DESTDIR`.
|
and `CMAKE_INSTALL_DOCDIR`. xtc-specific cache entries are
|
||||||
Paths must be absolute POSIX paths; spaces are supported. Do not include DESTDIR
|
`XTC_INSTALL_LICENSEDIR`, `XTC_INSTALL_EXAMPLESDIR`, `XTC_INSTALL_DESKTOPDIR`
|
||||||
in a directory variable: staging is applied separately and never embedded in
|
and `XTC_INSTALL_PKGCONFIGDIR`. Relative directories resolve beneath the prefix;
|
||||||
pkg-config metadata. Staging refuses parent symlinks that escape DESTDIR. Use
|
absolute directories are supported. Spaces work; control characters, quotes,
|
||||||
exactly the same variables for removal.
|
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
|
```sh
|
||||||
make BUILD_DIR=build/release-check all test gui
|
cmake -S . -B build/release-check -DCMAKE_BUILD_TYPE=Release \
|
||||||
make BUILD_DIR=build/release-check test-install test-install-layout
|
-DXTC_REPRODUCIBLE=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib64
|
||||||
make PREFIX=/usr DESTDIR=/tmp/xtc-stage libdir=/usr/lib64 install-gui
|
cmake --build build/release-check --parallel
|
||||||
make PREFIX=/usr DESTDIR=/tmp/xtc-stage libdir=/usr/lib64 uninstall
|
ctest --test-dir build/release-check --output-on-failure
|
||||||
make test-release test-package
|
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`,
|
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
|
symlinks are replaced, not followed; installation is atomic per file, not a
|
||||||
transaction over the entire prefix.
|
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
|
archive. Record that hash, the reviewed commit, version and build/dependency
|
||||||
conditions with release logs. `test-release` verifies the hash, builds/tests two
|
conditions with release logs. `test-release` verifies the hash, builds/tests two
|
||||||
fresh source exports and compares artifacts and repacks. It validates exported
|
fresh source exports and compares artifacts and repacks. It validates exported
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,11 @@ formal proof.
|
||||||
From the repository root:
|
From the repository root:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make BUILD_DIR=build/audit all gui test-reliability test-recovery
|
cmake --build build/audit --parallel && cmake --build build/audit --target gui test-reliability test-recovery
|
||||||
make BUILD_DIR=build/audit test-sanitize
|
cmake --build build/audit --target test-sanitize
|
||||||
make analyze
|
cmake --build build --target analyze
|
||||||
make BUILD_DIR=build/audit test-gui test-gui-jack test-jack test-jack-audio test-jack-midi
|
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
|
||||||
make BUILD_DIR=build/nojack PKG_CONFIG=false all test-reliability gui
|
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
|
`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
|
## 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
|
deterministic benchmark-gate tests, static analysis and ASan/UBSan (including
|
||||||
scale and soak). `make test-stress` repeats project/backend/publication faults
|
scale and soak). `cmake --build build --target test-stress` repeats project/backend/publication faults
|
||||||
under CPU contention; `make test-stress-plugins` adds the original LADSPA
|
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
|
failure fixture. The reliability callback guard now also rejects common host
|
||||||
file I/O and blocking mutex/condition calls. It audits directly linked 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
|
code, not arbitrary dynamic-plugin internals. See PERFORMANCE.md for exact
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
# Roadmap
|
# 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
|
## Phase 0 — Baseline
|
||||||
|
|
||||||
### Goal
|
### 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
|
## Recommended Execution Order
|
||||||
|
|
||||||
Reorder the phases when the audit reveals a blocking dependency. Do not mark a
|
Reorder the phases when the audit reveals a blocking dependency. Do not mark a
|
||||||
|
|
|
||||||
|
|
@ -102,12 +102,12 @@ public C snapshots/commands and never engine internals or callback storage.
|
||||||
|
|
||||||
## Verification and Limits
|
## Verification and Limits
|
||||||
|
|
||||||
`make test-routing` checks branch reachability, external input, levels, capacity
|
`cmake --build build --target test-routing` checks branch reachability, external input, levels, capacity
|
||||||
rollback, exact unity-insertion rendering and complete plan handoff. `make test`
|
rollback, exact unity-insertion rendering and complete plan handoff. `cmake --build build --target check`
|
||||||
also retains concurrent publication/lifecycle tests. `make test-reliability`
|
also retains concurrent publication/lifecycle tests. `cmake --build build --target test-reliability`
|
||||||
retains the callback-allocation guards. `make test-gui-plugins` checks selection
|
retains the callback-allocation guards. `cmake --build build --target test-gui-plugins` checks selection
|
||||||
diagnostics, unique placement/layout, failed backend publication, atomic
|
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
|
inserts/disconnects/restores real routes during live software playback and
|
||||||
checks engine revision acknowledgements and cycle rejection.
|
checks engine revision acknowledgements and cycle rejection.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
- The C render example demonstrates the actual xtc plugin facade and WAV writer,
|
||||||
including no-clobber output, without requiring JACK or a GUI.
|
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,
|
See [the example instructions](../examples/steinberg/README.md) for SDK versions,
|
||||||
build commands, validation and ASIO diagnostics.
|
build commands, validation and ASIO diagnostics.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ host ownership and cleanup.
|
||||||
Reproduce focused verification with:
|
Reproduce focused verification with:
|
||||||
|
|
||||||
```sh
|
```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
|
XTC_TEST_HOST_VST3=1 ./build/audio-editor/test_track_fx
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,20 +9,21 @@ implied.
|
||||||
|
|
||||||
## Build or Install
|
## 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.
|
`./build/xtc`. Use an existing JACK-compatible server and reconnect with F6.
|
||||||
Connect `midi_in` to a controller, `input` to mono capture and `output` /
|
Connect `midi_in` to a controller, `input` to mono capture and `output` /
|
||||||
`output_right` to left/right playback using your JACK routing application. No
|
`output_right` to left/right playback using your JACK routing application. No
|
||||||
server, physical routing or system configuration is changed automatically.
|
server, physical routing or system configuration is changed automatically.
|
||||||
`xtc --version`, `xtc --help` and `xtc --diagnose` need no display/server.
|
`xtc --version`, `xtc --help` and `xtc --diagnose` need no display/server.
|
||||||
|
|
||||||
For a source install stage with
|
For a source installation, configure `-DCMAKE_INSTALL_PREFIX=/usr`, build, then
|
||||||
`make install-gui DESTDIR="$PWD/build/stage" PREFIX=/usr`, inspect the stage,
|
stage with `DESTDIR="$PWD/build/stage" cmake --install build`. Inspect the stage
|
||||||
and use your normal deployment process. A user prefix is supported (for example
|
and use your normal deployment process. A user prefix such as an absolute path
|
||||||
an absolute path to your `.local` folder). `make uninstall` with the same
|
to `.local` is also supported. Use `cmake --build build --target uninstall`
|
||||||
DESTDIR/PREFIX removes only that version's known files. See LINUX.md for package
|
with the same DESTDIR and configured prefix for exact removal. See LINUX.md for
|
||||||
extraction, dependencies and removal. Never use a release built for a different
|
package extraction, dependencies and removal. Rebuild and test for the intended
|
||||||
system ABI without rebuilding/testing it.
|
system ABI before deployment.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ With installed FLTK/JACK development files, Xvfb and an already running
|
||||||
JACK-compatible server:
|
JACK-compatible server:
|
||||||
|
|
||||||
```sh
|
```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
|
`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.
|
its region never deletes the WAV; recording failures retain their recovery path.
|
||||||
There is no destructive media-delete operation. New/Open reset history after
|
There is no destructive media-delete operation. New/Open reset history after
|
||||||
unsaved-change handling. The capacity limit and allocation-error reporting in
|
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`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ described below. The floating mixer resizes down to 600 × 420 and retains
|
||||||
horizontal track scrolling.
|
horizontal track scrolling.
|
||||||
|
|
||||||
Verified with
|
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
|
(one line), plus the GUI suite under AddressSanitizer/UBSan. Tests cover
|
||||||
repeated reparenting, close-to-dock, resize, shared BPM/loop state, playback
|
repeated reparenting, close-to-dock, resize, shared BPM/loop state, playback
|
||||||
shortcuts, failed shutdown and cleanup.
|
shortcuts, failed shutdown and cleanup.
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
`native_gain.c` is a complete trusted native C effect compiled into an offline
|
`native_gain.c` is a complete trusted native C effect compiled into an offline
|
||||||
graph. Build/run with `make build/native-gain && ./build/native-gain`; it needs
|
graph. Build/run with `cmake --build build --target native-gain && ./build/native-gain`; it needs
|
||||||
no GUI/server/plugin SDK. See ../docs/NATIVE_API.md for lifecycle/event contracts.
|
no GUI/server/plugin SDK. See ../docs/NATIVE_API.md for lifecycle/event contracts.
|
||||||
|
|
||||||
`quality_preview.c` uses public C MIDI, recorder and gain-ramp APIs to generate
|
`quality_preview.c` uses public C MIDI, recorder and gain-ramp APIs to generate
|
||||||
matched raw/smoothed listening fixtures. Run `make quality-preview`; generated
|
matched raw/smoothed listening fixtures. Run `cmake --build build --target quality-preview`; generated
|
||||||
WAVs remain in the ignored build directory. See docs/AUDIO_QUALITY.md for the
|
WAVs remain in the ignored build directory. See docs/AUDIO_QUALITY.md for the
|
||||||
listening sequence and the distinction between automated checks and human
|
listening sequence and the distinction between automated checks and human
|
||||||
listening acceptance. It never starts a backend or plays audio.
|
listening acceptance. It never starts a backend or plays audio.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(xtc_juce_examples VERSION 0.1.0 LANGUAGES C CXX)
|
project(xtc_juce_examples VERSION 0.1.0 LANGUAGES C CXX)
|
||||||
|
include(CTest)
|
||||||
set(XTC_JUCE_ROOT "" CACHE PATH "External JUCE source checkout")
|
set(XTC_JUCE_ROOT "" CACHE PATH "External JUCE source checkout")
|
||||||
if(NOT EXISTS "${XTC_JUCE_ROOT}/modules/juce_audio_utils/juce_audio_utils.h")
|
if(NOT EXISTS "${XTC_JUCE_ROOT}/modules/juce_audio_utils/juce_audio_utils.h")
|
||||||
message(FATAL_ERROR "Set XTC_JUCE_ROOT to an external JUCE checkout; normal xtc builds do not download JUCE")
|
message(FATAL_ERROR "Set XTC_JUCE_ROOT to an external JUCE checkout; normal xtc builds do not download JUCE")
|
||||||
|
|
@ -11,21 +12,17 @@ message(STATUS "JUCE is AGPLv3/commercial: review the external SDK LICENSE.md be
|
||||||
set(JUCE_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
set(JUCE_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
set(JUCE_BUILD_EXTRAS OFF CACHE BOOL "" FORCE)
|
set(JUCE_BUILD_EXTRAS OFF CACHE BOOL "" FORCE)
|
||||||
add_subdirectory("${XTC_JUCE_ROOT}" juce-sdk EXCLUDE_FROM_ALL)
|
add_subdirectory("${XTC_JUCE_ROOT}" juce-sdk EXCLUDE_FROM_ALL)
|
||||||
find_program(XTC_MAKE_EXECUTABLE NAMES gmake make REQUIRED)
|
|
||||||
get_filename_component(XTC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
|
get_filename_component(XTC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
|
||||||
set(XTC_CORE_BUILD "${CMAKE_CURRENT_BINARY_DIR}/c-core")
|
if(NOT TARGET xtc-core)
|
||||||
add_custom_target(xtc-juce-core
|
set(XTC_BUILD_GUI OFF CACHE BOOL "" FORCE)
|
||||||
COMMAND "${XTC_MAKE_EXECUTABLE}" -C "${XTC_ROOT}"
|
set(XTC_WITH_JACK OFF CACHE BOOL "" FORCE)
|
||||||
"BUILD_DIR=${XTC_CORE_BUILD}" "CC=${CMAKE_C_COMPILER}"
|
set(XTC_BUILD_JUCE OFF CACHE BOOL "" FORCE)
|
||||||
"CFLAGS=-O2 -g -fPIC -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Iinclude"
|
set(XTC_BUILD_STEINBERG OFF CACHE BOOL "" FORCE)
|
||||||
PKG_CONFIG=false FLTK_CONFIG=false "${XTC_CORE_BUILD}/libxtc.a"
|
set(xtc_saved_testing ${BUILD_TESTING})
|
||||||
BYPRODUCTS "${XTC_CORE_BUILD}/libxtc.a"
|
set(BUILD_TESTING OFF)
|
||||||
VERBATIM USES_TERMINAL)
|
add_subdirectory("${XTC_ROOT}" c-core EXCLUDE_FROM_ALL)
|
||||||
add_library(xtc-juce-c-core STATIC IMPORTED)
|
set(BUILD_TESTING ${xtc_saved_testing})
|
||||||
set_target_properties(xtc-juce-c-core PROPERTIES
|
endif()
|
||||||
IMPORTED_LOCATION "${XTC_CORE_BUILD}/libxtc.a"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${XTC_ROOT}/include")
|
|
||||||
add_dependencies(xtc-juce-c-core xtc-juce-core)
|
|
||||||
|
|
||||||
juce_add_plugin(XtcJuceSynth
|
juce_add_plugin(XtcJuceSynth
|
||||||
COMPANY_NAME xtc
|
COMPANY_NAME xtc
|
||||||
|
|
@ -42,12 +39,15 @@ juce_add_plugin(XtcJuceSynth
|
||||||
NEEDS_WEB_BROWSER FALSE
|
NEEDS_WEB_BROWSER FALSE
|
||||||
NEEDS_CURL FALSE)
|
NEEDS_CURL FALSE)
|
||||||
target_sources(XtcJuceSynth PRIVATE Processor.cpp Editor.cpp PluginEntry.cpp)
|
target_sources(XtcJuceSynth PRIVATE Processor.cpp Editor.cpp PluginEntry.cpp)
|
||||||
|
# JUCE’s bundled FLAC uses POSIX fileno; its C module sources need GNU extensions.
|
||||||
|
# The xtc-core target remains strict C99.
|
||||||
|
set_target_properties(XtcJuceSynth PROPERTIES C_STANDARD 11 C_EXTENSIONS ON)
|
||||||
target_compile_features(XtcJuceSynth PUBLIC cxx_std_17)
|
target_compile_features(XtcJuceSynth PUBLIC cxx_std_17)
|
||||||
target_compile_definitions(XtcJuceSynth PUBLIC
|
target_compile_definitions(XtcJuceSynth PUBLIC
|
||||||
JUCE_WEB_BROWSER=0 JUCE_USE_CURL=0 JUCE_VST3_CAN_REPLACE_VST2=0 JUCE_PLUGINHOST_VST3=1
|
JUCE_WEB_BROWSER=0 JUCE_USE_CURL=0 JUCE_VST3_CAN_REPLACE_VST2=0 JUCE_PLUGINHOST_VST3=1
|
||||||
)
|
)
|
||||||
target_include_directories(XtcJuceSynth PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" "${XTC_ROOT}/include")
|
target_include_directories(XtcJuceSynth PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" "${XTC_ROOT}/include")
|
||||||
target_link_libraries(XtcJuceSynth PRIVATE xtc-juce-c-core juce::juce_audio_utils juce::juce_dsp
|
target_link_libraries(XtcJuceSynth PRIVATE xtc-core juce::juce_audio_utils juce::juce_dsp
|
||||||
PUBLIC juce::juce_recommended_config_flags juce::juce_recommended_warning_flags)
|
PUBLIC juce::juce_recommended_config_flags juce::juce_recommended_warning_flags)
|
||||||
|
|
||||||
add_executable(xtc-juce-render Render.cpp)
|
add_executable(xtc-juce-render Render.cpp)
|
||||||
|
|
@ -57,8 +57,11 @@ target_include_directories(xtc-juce-render PRIVATE "${XTC_JUCE_ROOT}/modules")
|
||||||
# Exact float comparisons intentionally check bit-identical C bridge output.
|
# Exact float comparisons intentionally check bit-identical C bridge output.
|
||||||
set_source_files_properties(Render.cpp PROPERTIES COMPILE_OPTIONS "-Wno-float-equal")
|
set_source_files_properties(Render.cpp PROPERTIES COMPILE_OPTIONS "-Wno-float-equal")
|
||||||
target_compile_definitions(xtc-juce-render PRIVATE JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1)
|
target_compile_definitions(xtc-juce-render PRIVATE JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1)
|
||||||
target_link_libraries(xtc-juce-render PRIVATE XtcJuceSynth xtc-juce-c-core)
|
target_link_libraries(xtc-juce-render PRIVATE XtcJuceSynth xtc-core)
|
||||||
enable_testing()
|
if(BUILD_TESTING)
|
||||||
add_test(NAME xtc-juce-processor COMMAND xtc-juce-render --self-test)
|
find_program(XTC_XVFB_RUN xvfb-run REQUIRED)
|
||||||
|
add_test(NAME xtc-juce-processor COMMAND ${XTC_XVFB_RUN} -a $<TARGET_FILE:xtc-juce-render> --self-test)
|
||||||
add_test(NAME xtc-juce-vst3 COMMAND xtc-juce-render --host-check "$<TARGET_FILE_DIR:XtcJuceSynth_VST3>/../..")
|
add_test(NAME xtc-juce-vst3 COMMAND ${XTC_XVFB_RUN} -a $<TARGET_FILE:xtc-juce-render>
|
||||||
|
--host-check "$<PATH:GET_PARENT_PATH,$<PATH:GET_PARENT_PATH,$<TARGET_FILE_DIR:XtcJuceSynth_VST3>>>")
|
||||||
|
set_tests_properties(xtc-juce-processor xtc-juce-vst3 PROPERTIES LABELS sdk)
|
||||||
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -10,27 +10,34 @@ No SDK or linked binary is copied into normal xtc packages.
|
||||||
## Build and test (Linux)
|
## Build and test (Linux)
|
||||||
|
|
||||||
Supply JUCE explicitly, for example in `/your/path/JUCE`. With CMake >= 3.25,
|
Supply JUCE explicitly, for example in `/your/path/JUCE`. With CMake >= 3.25,
|
||||||
GNU Make, a C/C++17 toolchain and JUCE's Linux development prerequisites:
|
Ninja or another CMake backend, a C/C++17 toolchain and JUCE's Linux development
|
||||||
|
prerequisites, configure from the repository root:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make JUCE_ROOT=/your/path/JUCE juce-examples
|
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
|
||||||
make JUCE_ROOT=/your/path/JUCE test-juce
|
-DXTC_BUILD_JUCE=ON -DXTC_JUCE_ROOT=/your/path/JUCE
|
||||||
|
cmake --build build --target juce-examples --parallel 3
|
||||||
|
cmake --build build --target test-juce
|
||||||
```
|
```
|
||||||
|
|
||||||
The build never downloads JUCE, installs dependencies or copies plugins into
|
The build never downloads JUCE, installs dependencies or copies plugins into
|
||||||
user plugin directories. It builds its own C99 PIC archive with JACK/FLTK disabled
|
user plugin directories. The bridge links the root `xtc-core` PIC C99 target;
|
||||||
under `build/juce/c-core`. `test-juce` also requires Xvfb and runs the processor
|
there is no recursive Make build or duplicate core archive. `test-juce` requires
|
||||||
and JUCE-host checks, then loads the built instrument through xtc's C VST3 host.
|
Xvfb and runs the processor, JUCE-host, file/editor and xtc C-host checks.
|
||||||
Normal `make`, `make gui` and `make test` remain JUCE-independent.
|
Normal builds leave `XTC_BUILD_JUCE=OFF` and remain JUCE-independent.
|
||||||
|
|
||||||
Build products:
|
Build products (Release):
|
||||||
|
|
||||||
- `build/juce/XtcJuceSynth_artefacts/Release/VST3/xtc JUCE Synth.vst3`
|
- `build/juce/XtcJuceSynth_artefacts/Release/VST3/xtc JUCE Synth.vst3`
|
||||||
- `build/juce/XtcJuceSynth_artefacts/Release/Standalone/xtc JUCE Synth`
|
- `build/juce/XtcJuceSynth_artefacts/Release/Standalone/xtc JUCE Synth`
|
||||||
- `build/juce/xtc-juce-render_artefacts/Release/xtc-juce-render`
|
- `build/juce/xtc-juce-render_artefacts/Release/xtc-juce-render`
|
||||||
|
|
||||||
Set `BUILD_DIR=...` to move the main build root, or `JUCE_BUILD_DIR=...` to select
|
Use CMake's `-B` argument to select another binary directory. Debug builds use
|
||||||
only the SDK example build directory.
|
`Debug` in place of `Release`. The examples can also be configured directly with
|
||||||
|
`cmake -S examples/juce -B build/juce-only -DXTC_JUCE_ROOT=/your/path/JUCE
|
||||||
|
-DCMAKE_BUILD_TYPE=Release`; that standalone path adds the same root CMake core
|
||||||
|
with GUI/JACK/tests disabled rather than invoking Make. Its artefacts are directly
|
||||||
|
under `build/juce-only`, without the additional `juce` directory.
|
||||||
|
|
||||||
## Play and shape Soft Keys
|
## Play and shape Soft Keys
|
||||||
|
|
||||||
|
|
@ -84,7 +91,7 @@ VST3 host. These operations do not start an audio device.
|
||||||
## Regression checks and an actual editor image
|
## Regression checks and an actual editor image
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
xvfb-run -a ctest --test-dir build/juce --output-on-failure
|
ctest --test-dir build --output-on-failure -R juce
|
||||||
xvfb-run -a ./build/juce/xtc-juce-render_artefacts/Release/xtc-juce-render --snapshot /absolute/new-editor.png
|
xvfb-run -a ./build/juce/xtc-juce-render_artefacts/Release/xtc-juce-render --snapshot /absolute/new-editor.png
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ if(XTC_VST3_SDK_ROOT)
|
||||||
set(SMTG_ENABLE_VST3_HOSTING_EXAMPLES ON CACHE BOOL "" FORCE)
|
set(SMTG_ENABLE_VST3_HOSTING_EXAMPLES ON CACHE BOOL "" FORCE)
|
||||||
add_subdirectory("${XTC_VST3_SDK_ROOT}" sdk)
|
add_subdirectory("${XTC_VST3_SDK_ROOT}" sdk)
|
||||||
set(public_sdk_SOURCE_DIR "${XTC_VST3_SDK_ROOT}/public.sdk")
|
set(public_sdk_SOURCE_DIR "${XTC_VST3_SDK_ROOT}/public.sdk")
|
||||||
|
set(SMTG_CUSTOM_BINARY_LOCATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
smtg_add_vst3plugin(xtc-sdk-examples sdk_plugins.cpp)
|
smtg_add_vst3plugin(xtc-sdk-examples sdk_plugins.cpp)
|
||||||
target_link_libraries(xtc-sdk-examples PRIVATE sdk)
|
target_link_libraries(xtc-sdk-examples PRIVATE sdk)
|
||||||
target_compile_features(xtc-sdk-examples PRIVATE cxx_std_17)
|
target_compile_features(xtc-sdk-examples PRIVATE cxx_std_17)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Official Steinberg SDK examples
|
# Official Steinberg SDK examples
|
||||||
|
|
||||||
These are optional integration examples. Normal `make` / `make test` uses the
|
These are optional integration examples. Normal CMake builds and CTest use the
|
||||||
existing pinned C ABI headers and never downloads SDKs. Original example source
|
existing pinned C ABI headers and never downloads SDKs. Original example source
|
||||||
is MIT-licensed like xtc. SDK code is compiled from an external checkout, not
|
is MIT-licensed like xtc. SDK code is compiled from an external checkout, not
|
||||||
vendored or installed by these targets. C++ is confined to the SDK examples;
|
vendored or installed by these targets. C++ is confined to the SDK examples;
|
||||||
|
|
@ -26,13 +26,17 @@ trademark distribution rights.
|
||||||
From the xtc repository root:
|
From the xtc repository root:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make VST3_SDK_ROOT=/your/path/vst3sdk test-steinberg-sdk
|
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DXTC_BUILD_STEINBERG=ON -DXTC_VST3_SDK_ROOT=/your/path/vst3sdk
|
||||||
|
cmake --build build --parallel 3
|
||||||
|
ctest --test-dir build --output-on-failure -R steinberg
|
||||||
```
|
```
|
||||||
|
|
||||||
This builds the original `xtc-sdk-examples.vst3` bundle using Steinberg's factory,
|
This builds the original `xtc-sdk-examples.vst3` bundle using Steinberg's factory,
|
||||||
AudioEffect, controller and platform-entry implementations; runs the official
|
AudioEffect, controller and platform-entry implementations; runs the official
|
||||||
validator; and runs xtc's gain/MIDI interoperability checks. Build output stays
|
validator; and runs xtc's gain/MIDI interoperability checks. The plugin bundle stays
|
||||||
under `build/steinberg-sdk`; automatic plugin-directory links and installation
|
under `build/steinberg-sdk`; SDK helper executables use `build/bin`. Automatic
|
||||||
|
plugin-directory links and installation
|
||||||
are disabled. SDK source may emit its own compiler warnings.
|
are disabled. SDK source may emit its own compiler warnings.
|
||||||
|
|
||||||
The bundle contains:
|
The bundle contains:
|
||||||
|
|
@ -56,9 +60,9 @@ xtc synth -> effect host path:
|
||||||
/absolute/path/to/new-sdk-demo.wav
|
/absolute/path/to/new-sdk-demo.wav
|
||||||
```
|
```
|
||||||
|
|
||||||
The destination must not exist. This executable is built by `test-steinberg-sdk`.
|
The destination must not exist. This executable is built when the SDK option is enabled.
|
||||||
To use a different xtc build directory, pass `BUILD_DIR=...`; the SDK build then
|
Use CMake’s `-B` argument to select another binary directory; the SDK build then
|
||||||
lives under that directory unless `STEINBERG_BUILD_DIR=...` is explicitly set.
|
lives under its `steinberg-sdk` subdirectory.
|
||||||
|
|
||||||
The main app's existing plugin loader can use the bundle path through its C API;
|
The main app's existing plugin loader can use the bundle path through its C API;
|
||||||
its file chooser may require selecting the inner `.so`. The effect loads as a
|
its file chooser may require selecting the inner `.so`. The effect loads as a
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,11 @@ The host is stopped and meters are idle. No ASIO interface is shown or implied.
|
||||||
See [Steinberg integration](../docs/STEINBERG.md) and
|
See [Steinberg integration](../docs/STEINBERG.md) and
|
||||||
[JUCE integration](../docs/JUCE.md).
|
[JUCE integration](../docs/JUCE.md).
|
||||||
|
|
||||||
After building both SDK examples, reproduce only these host captures with:
|
After configuring the root CMake project and building both SDK examples,
|
||||||
|
reproduce only these host captures with:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make build/capture_screenshots
|
cmake --build build --target capture_screenshots
|
||||||
XTC_CAPTURE_STEINBERG_BUNDLE="$PWD/build/steinberg-sdk/VST3/Release/xtc-sdk-examples.vst3" \
|
XTC_CAPTURE_STEINBERG_BUNDLE="$PWD/build/steinberg-sdk/VST3/Release/xtc-sdk-examples.vst3" \
|
||||||
XTC_CAPTURE_JUCE_BUNDLE="$PWD/build/juce/XtcJuceSynth_artefacts/Release/VST3/xtc JUCE Synth.vst3" \
|
XTC_CAPTURE_JUCE_BUNDLE="$PWD/build/juce/XtcJuceSynth_artefacts/Release/VST3/xtc JUCE Synth.vst3" \
|
||||||
xvfb-run -a -s '-screen 0 1440x960x24' \
|
xvfb-run -a -s '-screen 0 1440x960x24' \
|
||||||
|
|
@ -91,14 +92,15 @@ mean no automatic connection. Actual device choices depend on host JACK/PipeWire
|
||||||
exposure. Configuration paths are disabled in captures to preserve user settings.
|
exposure. Configuration paths are disabled in captures to preserve user settings.
|
||||||
See [MIDI workflows and limits](../docs/MIDI_WORKFLOWS.md).
|
See [MIDI workflows and limits](../docs/MIDI_WORKFLOWS.md).
|
||||||
|
|
||||||
Reproduce these five captures with
|
After configuring `build/audio-editor` with the root CMake project,
|
||||||
`XTC_CAPTURE_MIDI_ONLY=1 make BUILD_DIR=build/audio-editor screenshots`.
|
reproduce these five captures with
|
||||||
|
`XTC_CAPTURE_MIDI_ONLY=1 cmake --build build/audio-editor --target screenshots`.
|
||||||
|
|
||||||
The open input dropdown was captured after the device-label lifetime fix. It
|
The open input dropdown was captured after the device-label lifetime fix. It
|
||||||
shows actual host sources, including UMC204HD, USB MIDI, Oxygen Pro 25 and BLE
|
shows actual host sources, including UMC204HD, USB MIDI, Oxygen Pro 25 and BLE
|
||||||
MIDI ports. No route is selected and user preferences are preserved. Reproduce
|
MIDI ports. No route is selected and user preferences are preserved. Reproduce
|
||||||
just this image with real MIDI sources exposed by JACK/PipeWire:
|
just this image with real MIDI sources exposed by JACK/PipeWire:
|
||||||
`XTC_CAPTURE_MIDI_INPUT_ONLY=1 make BUILD_DIR=build/audio-editor screenshots`.
|
`XTC_CAPTURE_MIDI_INPUT_ONLY=1 cmake --build build/audio-editor --target screenshots`.
|
||||||
The capture fails explicitly if the host exposes no input sources.
|
The capture fails explicitly if the host exposes no input sources.
|
||||||
|
|
||||||
## Creative workflows (Phases 90–99)
|
## Creative workflows (Phases 90–99)
|
||||||
|
|
@ -112,7 +114,7 @@ creative controls; the rest of the gallery also reflects the current UI.
|
||||||
- [Strummed chord notes in the piano roll](creative-strum-result.png)
|
- [Strummed chord notes in the piano roll](creative-strum-result.png)
|
||||||
|
|
||||||
Reproduce only these captures with
|
Reproduce only these captures with
|
||||||
`XTC_CAPTURE_CREATIVE_ONLY=1 make BUILD_DIR=build/audio-editor screenshots`.
|
`XTC_CAPTURE_CREATIVE_ONLY=1 cmake --build build/audio-editor --target screenshots`.
|
||||||
The rack shows the actual template and idle meter; no live peak readings are
|
The rack shows the actual template and idle meter; no live peak readings are
|
||||||
fabricated. See [creative workflow limits](../docs/CREATIVE_WORKFLOWS.md).
|
fabricated. See [creative workflow limits](../docs/CREATIVE_WORKFLOWS.md).
|
||||||
|
|
||||||
|
|
@ -219,7 +221,8 @@ to return it to the main window.
|
||||||
From the repository root, run:
|
From the repository root, run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make BUILD_DIR=build/next-daw screenshots
|
cmake -S . -B build/next-daw -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
cmake --build build/next-daw --target screenshots
|
||||||
```
|
```
|
||||||
|
|
||||||
This optional documentation target requires the existing FLTK/JACK build
|
This optional documentation target requires the existing FLTK/JACK build
|
||||||
|
|
@ -230,7 +233,7 @@ PNGs. All demonstration edits and collection outputs use an automatically remove
|
||||||
temporary directory; no preferences are saved. It neither installs dependencies
|
temporary directory; no preferences are saved. It neither installs dependencies
|
||||||
nor starts/reconfigures the audio server.
|
nor starts/reconfigures the audio server.
|
||||||
|
|
||||||
Set `XTC_CAPTURE_SAMPLE_ONLY=1` for the capture tool (or the make target) to write
|
Set `XTC_CAPTURE_SAMPLE_ONLY=1` for the capture tool (or the CMake target) to write
|
||||||
only the two sample-editor images while retaining the existing gallery.
|
only the two sample-editor images while retaining the existing gallery.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -241,6 +244,6 @@ XTC_CAPTURE_HOST_VST3=1 xvfb-run -a -s '-screen 0 1440x960x24' \
|
||||||
./build/audio-editor/capture_screenshots "$PWD/screenshots"
|
./build/audio-editor/capture_screenshots "$PWD/screenshots"
|
||||||
```
|
```
|
||||||
|
|
||||||
Run `make BUILD_DIR=build/audio-editor screenshots` first to build the tool and
|
Run `cmake --build build/audio-editor --target screenshots` first to build the tool and
|
||||||
refresh the full fixture/demo gallery. All captures use temporary projects and
|
refresh the full fixture/demo gallery. All captures use temporary projects and
|
||||||
preserve user settings and original media.
|
preserve user settings and original media.
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,20 @@
|
||||||
# Integration tests
|
# Integration tests
|
||||||
|
|
||||||
`make test` is hardware/server independent: offline render tests, concurrent
|
Configure the root project first with `cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug`,
|
||||||
|
then `cmake --build build --parallel`. Run `ctest --test-dir build
|
||||||
|
--output-on-failure` for registered tests. Live tests require a separate configure
|
||||||
|
with `-DXTC_ENABLE_LIVE_TESTS=ON` and an existing JACK server; CTest serializes them.
|
||||||
|
See [BUILD.md](../../docs/BUILD.md) for presets and feature options. Older validation
|
||||||
|
records below describe tests performed at that time; commands use the CMake
|
||||||
|
workflow and assume the relevant configuration has already completed.
|
||||||
|
|
||||||
|
`cmake --build build --target check` is hardware/server independent: offline render tests, concurrent
|
||||||
plan-replacement stress, and (when JACK headers are present) JACK ABI fault
|
plan-replacement stress, and (when JACK headers are present) JACK ABI fault
|
||||||
injection. The fake links against installed declarations without linking
|
injection. The fake exports JACK entry points against the installed declarations;
|
||||||
libjack. It does not claim to reproduce JACK scheduling; the separate
|
the CMake core target carries the optional JACK link dependency. It does not claim to reproduce JACK scheduling; the separate
|
||||||
threaded stress test exercises publication/reclamation.
|
threaded stress test exercises publication/reclamation.
|
||||||
|
|
||||||
`make test-jack` explicitly runs a five-second live JACK loopback test. Requires
|
`cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-jack` explicitly runs a five-second live JACK loopback test. Requires
|
||||||
an existing JACK or PipeWire JACK-compatible server; does not start a server,
|
an existing JACK or PipeWire JACK-compatible server; does not start a server,
|
||||||
change its sample rate/block size, or connect physical outputs. Source output
|
change its sample rate/block size, or connect physical outputs. Source output
|
||||||
is connected only to the test's capture client, then disconnected and removed.
|
is connected only to the test's capture client, then disconnected and removed.
|
||||||
|
|
@ -14,7 +22,7 @@ It checks finite/bounded captured samples at two gains, active plan replacement,
|
||||||
status and ten restart cycles. For a longer run:
|
status and ten restart cycles. For a longer run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make build/test_jack
|
cmake --build build --target test_jack
|
||||||
./build/test_jack 30
|
./build/test_jack 30
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -30,9 +38,9 @@ JACK callbacks/results in `tests/unit/test_backend.c`.
|
||||||
## FLTK shell tests
|
## FLTK shell tests
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make gui test-gui
|
cmake --build build --target gui test-gui
|
||||||
# Optional, requires a running JACK-compatible server:
|
# Optional, requires a running JACK-compatible server:
|
||||||
make test-gui-jack
|
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-gui-jack
|
||||||
```
|
```
|
||||||
|
|
||||||
These targets require FLTK development files, `xvfb-run` and Xvfb. No additional
|
These targets require FLTK development files, `xvfb-run` and Xvfb. No additional
|
||||||
|
|
@ -58,15 +66,15 @@ the third-party font stack is leak-free. Apply only to GUI sanitizer tests:
|
||||||
LSAN_OPTIONS=suppressions=tests/integration/lsan.supp xvfb-run -a -s '-screen 0 1280x800x24' ./build/gui-sanitize/test_gui
|
LSAN_OPTIONS=suppressions=tests/integration/lsan.supp xvfb-run -a -s '-screen 0 1280x800x24' ./build/gui-sanitize/test_gui
|
||||||
```
|
```
|
||||||
|
|
||||||
Build that binary with Clang/Clang++, `-fsanitize=address,undefined` in both
|
Build that binary in a separate CMake directory with
|
||||||
CFLAGS/CXXFLAGS and LDFLAGS, using the baseline warning/include/standard flags
|
`-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DXTC_SANITIZE=ON`.
|
||||||
from BUILD.md. Keep FLTK's `-I` and `-D` flags from `fltk-config --cxxflags`,
|
CMake propagates sanitizer compile/link options and filters FLTK discovery flags
|
||||||
but exclude the distribution's GCC-specific LTO/object-code flags for Clang.
|
so they do not override the chosen compiler or optimization settings.
|
||||||
No suppressions are used for core/backend/realtime sanitizer tests.
|
No suppressions are used for core/backend/realtime sanitizer tests.
|
||||||
|
|
||||||
## Phase 4 graph editing coverage
|
## Phase 4 graph editing coverage
|
||||||
|
|
||||||
The same `make test-gui` target now adds nodes through toolbar callbacks,
|
The same `cmake --build build --target test-gui` target now adds nodes through toolbar callbacks,
|
||||||
connects the exact rendered graph, validates expected oscillator/gain samples
|
connects the exact rendered graph, validates expected oscillator/gain samples
|
||||||
in the submitted backend plan, checks cycle/direction/duplicate rejection,
|
in the submitted backend plan, checks cycle/direction/duplicate rejection,
|
||||||
checks backend I/O/pending-capacity rollback, deletes wires and incident edges,
|
checks backend I/O/pending-capacity rollback, deletes wires and incident edges,
|
||||||
|
|
@ -74,7 +82,7 @@ and verifies stable IDs, preserved positions, prepared/queued/active feedback
|
||||||
and empty-graph silence. The fake backend compiles submitted C snapshots rather
|
and empty-graph silence. The fake backend compiles submitted C snapshots rather
|
||||||
than accepting an unrelated GUI model. Move-only actions do not submit plans.
|
than accepting an unrelated GUI model. Move-only actions do not submit plans.
|
||||||
|
|
||||||
`make test-gui-jack` exercises the same widget against real JACK: it builds a
|
`cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-gui-jack` exercises the same widget against real JACK: it builds a
|
||||||
graph while stopped, starts it, adds/deletes nodes during active processing,
|
graph while stopped, starts it, adds/deletes nodes during active processing,
|
||||||
waits for revision acknowledgement, and rejects cycles without changing the
|
waits for revision acknowledgement, and rejects cycles without changing the
|
||||||
model. Start/stop/reconnect and callback-safe active close remain covered. No
|
model. Start/stop/reconnect and callback-safe active close remain covered. No
|
||||||
|
|
@ -99,14 +107,14 @@ A sample-status update drives the cursor to an exact tick; a graph edit retains
|
||||||
that position. test_gui_jack checks actual playhead advancement and a stable
|
that position. test_gui_jack checks actual playhead advancement and a stable
|
||||||
paused cursor across repeated starts/stops. No routes are created.
|
paused cursor across repeated starts/stops. No routes are created.
|
||||||
test_project additionally covers serialization, exact graph samples/IDs,
|
test_project additionally covers serialization, exact graph samples/IDs,
|
||||||
truncation/mutation input, capacity, save failures and cleanup (part of make test).
|
truncation/mutation input, capacity, save failures and cleanup (part of CTest).
|
||||||
The core/backend tests remain unsuppressed under ASan/UBSan; GUI checks retain
|
The core/backend tests remain unsuppressed under ASan/UBSan; GUI checks retain
|
||||||
the narrowly scoped fontconfig-only suppression described above.
|
the narrowly scoped fontconfig-only suppression described above.
|
||||||
|
|
||||||
|
|
||||||
## Phase 6 audio acceptance
|
## Phase 6 audio acceptance
|
||||||
|
|
||||||
make test-jack-audio requires a running JACK-compatible server. It creates only
|
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-jack-audio requires a running JACK-compatible server. It creates only
|
||||||
software routes between its probe and xtc backend: known 0.25 source, input
|
software routes between its probe and xtc backend: known 0.25 source, input
|
||||||
capture through the recorder ring, WAV finalization, project save/reopen,
|
capture through the recorder ring, WAV finalization, project save/reopen,
|
||||||
then clip source graph playback observed at the probe input. All test ports,
|
then clip source graph playback observed at the probe input. All test ports,
|
||||||
|
|
@ -117,14 +125,14 @@ test_gui covers record/Stop, exact take playback, saving/reopening, failed impor
|
||||||
missing assets, and blocked edits/file actions/close while recording. The live
|
missing assets, and blocked edits/file actions/close while recording. The live
|
||||||
test_gui_jack records a silent take, finalizes and saves/reopens it, then starts
|
test_gui_jack records a silent take, finalizes and saves/reopens it, then starts
|
||||||
playback before callback-safe close. Decoder and producer/consumer concurrency
|
playback before callback-safe close. Decoder and producer/consumer concurrency
|
||||||
checks are part of make test; run test_audio and test_realtime under TSan as in
|
checks are part of CTest; run test_audio and test_realtime under TSan as in
|
||||||
BUILD.md. Physical input/output and latency compensation are not tested.
|
BUILD.md. Physical input/output and latency compensation are not tested.
|
||||||
|
|
||||||
## Phase 7 verification
|
## Phase 7 verification
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make all test gui debug test-gui test-gui-jack test-jack-audio test-jack-midi
|
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --parallel && cmake --build build --target check 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
|
cmake -S . -B build/nojack -DXTC_WITH_JACK=OFF && cmake --build build/nojack --parallel && cmake --build build/nojack --target check gui test-gui
|
||||||
```
|
```
|
||||||
|
|
||||||
`test_midi` adds exact sample scheduling, trim/seek/panic, block independence,
|
`test_midi` adds exact sample scheduling, trim/seek/panic, block independence,
|
||||||
|
|
@ -139,8 +147,8 @@ or system changes are made. MIDI recording/SMF and physical devices are deferred
|
||||||
## Phase 8 verification
|
## Phase 8 verification
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make all test gui debug test-gui test-gui-jack test-jack-audio test-jack-midi
|
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --parallel && cmake --build build --target check 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
|
cmake -S . -B build/nojack -DXTC_WITH_JACK=OFF && cmake --build build/nojack --parallel && cmake --build build/nojack --target check gui test-gui
|
||||||
```
|
```
|
||||||
|
|
||||||
`test_mixer` covers stereo gain/pan, mute/solo, sample automation, block
|
`test_mixer` covers stereo gain/pan, mute/solo, sample automation, block
|
||||||
|
|
@ -160,9 +168,9 @@ long-running stereo performance remain unverified.
|
||||||
## Phase 9 release preparation
|
## Phase 9 release preparation
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make all test gui debug test-gui test-gui-jack test-jack test-jack-audio test-jack-midi
|
cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --parallel && cmake --build build --target check gui debug test-gui test-gui-jack test-jack test-jack-audio test-jack-midi
|
||||||
make test-install test-recovery test-performance
|
cmake --build build --target test-install test-recovery test-performance
|
||||||
make test-release
|
cmake --build build --target test-release
|
||||||
```
|
```
|
||||||
|
|
||||||
Core test now includes native ABI/lifecycle/retirement and the native-gain example.
|
Core test now includes native ABI/lifecycle/retirement and the native-gain example.
|
||||||
|
|
@ -185,9 +193,9 @@ and their repacked source archives were byte-identical on this toolchain.
|
||||||
|
|
||||||
## Phase 10 reliability audit
|
## Phase 10 reliability audit
|
||||||
|
|
||||||
Run `make test-reliability` for the core suites, allocation-failure sweep,
|
Run `cmake --build build --target test-reliability` for the core suites, allocation-failure sweep,
|
||||||
callback allocation/free guard and native reclamation checks. Run
|
callback allocation/free guard and native reclamation checks. Run
|
||||||
`make test-sanitize` for Clang ASan/UBSan/leak checks and `make analyze` for
|
`cmake --build build --target test-sanitize` for Clang ASan/UBSan/leak checks and `cmake --build build --target analyze` for
|
||||||
Clang static analysis of all core sources. These need installed development
|
Clang static analysis of all core sources. These need installed development
|
||||||
tools; the allocation guard uses a GNU-compatible linker. See
|
tools; the allocation guard uses a GNU-compatible linker. See
|
||||||
[RELIABILITY.md](../../docs/RELIABILITY.md) for ownership, audit findings,
|
[RELIABILITY.md](../../docs/RELIABILITY.md) for ownership, audit findings,
|
||||||
|
|
@ -195,7 +203,7 @@ full verification commands and remaining limits.
|
||||||
|
|
||||||
## Phase 11 composition workflow
|
## Phase 11 composition workflow
|
||||||
|
|
||||||
`make test-workflow` builds and runs `test_workflow.cpp` under Xvfb with the real
|
`cmake -S . -B build -DXTC_ENABLE_LIVE_TESTS=ON && cmake --build build --target test-workflow` builds and runs `test_workflow.cpp` under Xvfb with the real
|
||||||
JACK-compatible backend. It requires an already running server. It creates and
|
JACK-compatible backend. It requires an already running server. It creates and
|
||||||
arranges MIDI and imported audio through GUI commands, saves/closes/destroys the
|
arranges MIDI and imported audio through GUI commands, saves/closes/destroys the
|
||||||
window, reopens in another window, compares stereo rendering exactly, verifies
|
window, reopens in another window, compares stereo rendering exactly, verifies
|
||||||
|
|
|
||||||
|
|
@ -27,20 +27,39 @@ def main():
|
||||||
sentinel = root / 'lib/keep-unrelated.txt'
|
sentinel = root / 'lib/keep-unrelated.txt'
|
||||||
sentinel.parent.mkdir(parents=True)
|
sentinel.parent.mkdir(parents=True)
|
||||||
sentinel.write_text('keep\n')
|
sentinel.write_text('keep\n')
|
||||||
make = shlex.split(os.environ.get('MAKE', 'make'))
|
# Generate the real CMake install driver against the already-built inputs.
|
||||||
# MAKEFLAGS jobserver descriptors do not cross Python subprocesses.
|
# The temporary cache keeps the caller's build configuration untouched.
|
||||||
env = dict(os.environ, MAKEFLAGS='', MFLAGS='')
|
installer = stage / 'cmake-driver'
|
||||||
variables = [f'BUILD_DIR={args.build_dir}', f'PREFIX={prefix}', f'DESTDIR={stage}']
|
cache = (args.build_dir / 'CMakeCache.txt').read_text()
|
||||||
|
generator = next(line.partition('=')[2] for line in cache.splitlines()
|
||||||
|
if line.startswith('CMAKE_GENERATOR:INTERNAL='))
|
||||||
|
jack = 'OFF' if 'XTC_WITH_JACK:BOOL=OFF' in cache else 'ON'
|
||||||
|
env = dict(os.environ)
|
||||||
|
variables = ['-DBUILD_TESTING=OFF', f'-DXTC_BUILD_GUI={"ON" if args.gui else "OFF"}',
|
||||||
|
f'-DCMAKE_INSTALL_PREFIX={prefix}',
|
||||||
|
f'-DXTC_INSTALL_BUILD_DIR={args.build_dir.resolve()}',
|
||||||
|
f'-DXTC_WITH_JACK={jack}', '-DXTC_INSTALL_GUI=OFF', '-DCMAKE_INSTALL_DOCDIR=share/doc/xtc']
|
||||||
if args.custom_layout:
|
if args.custom_layout:
|
||||||
variables += [f'exec_prefix={prefix}/runtime', f'libdir={prefix}/lib64',
|
variables += ['-DCMAKE_INSTALL_BINDIR=runtime/bin', '-DCMAKE_INSTALL_LIBDIR=lib64',
|
||||||
f'includedir={prefix}/headers', f'datarootdir={prefix}/resources',
|
'-DCMAKE_INSTALL_INCLUDEDIR=headers', '-DCMAKE_INSTALL_DATAROOTDIR=resources',
|
||||||
f'docdir={prefix}/manual', f'pkgconfigdir={prefix}/metadata']
|
'-DCMAKE_INSTALL_DOCDIR=manual', '-DXTC_INSTALL_PKGCONFIGDIR=metadata']
|
||||||
|
|
||||||
|
def install_command(operation, options, **kwargs):
|
||||||
|
config = subprocess.run(['cmake', '-G', generator, '-S', str(source), '-B', str(installer),
|
||||||
|
*options], env=env, stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT, text=True)
|
||||||
|
if config.returncode:
|
||||||
|
raise RuntimeError(config.stdout)
|
||||||
|
command = (['cmake', '--build', str(installer), '--target', 'uninstall']
|
||||||
|
if operation == 'uninstall' else ['cmake', '--install', str(installer)])
|
||||||
|
return subprocess.run(command, env=dict(env, DESTDIR=str(stage)), **kwargs)
|
||||||
|
|
||||||
binaries = root / ('runtime/bin' if args.custom_layout else 'bin')
|
binaries = root / ('runtime/bin' if args.custom_layout else 'bin')
|
||||||
headers = root / ('headers' if args.custom_layout else 'include')
|
headers = root / ('headers' if args.custom_layout else 'include')
|
||||||
resources = root / ('resources' if args.custom_layout else 'share')
|
resources = root / ('resources' if args.custom_layout else 'share')
|
||||||
docs = root / ('manual' if args.custom_layout else 'share/doc/xtc')
|
docs = root / ('manual' if args.custom_layout else 'share/doc/xtc')
|
||||||
metadata = root / ('metadata' if args.custom_layout else 'lib/pkgconfig')
|
metadata = root / ('metadata' if args.custom_layout else 'lib/pkgconfig')
|
||||||
run(make + ['install'] + variables, env=env)
|
install_command('install', variables, check=True)
|
||||||
assert not (binaries / 'xtc').exists()
|
assert not (binaries / 'xtc').exists()
|
||||||
assert (resources / 'licenses/xtc/LICENSE').read_bytes() == (source / 'LICENSE').read_bytes()
|
assert (resources / 'licenses/xtc/LICENSE').read_bytes() == (source / 'LICENSE').read_bytes()
|
||||||
assert (docs / 'PROJECT_FORMAT.md').is_file()
|
assert (docs / 'PROJECT_FORMAT.md').is_file()
|
||||||
|
|
@ -64,7 +83,7 @@ def main():
|
||||||
(binaries / 'xtc-check').symlink_to(protected)
|
(binaries / 'xtc-check').symlink_to(protected)
|
||||||
# Upgrade/repair repeats the same owned-file install and keeps unrelated data.
|
# Upgrade/repair repeats the same owned-file install and keeps unrelated data.
|
||||||
(headers / 'xtc/xtc.h').write_text('old installation marker\n')
|
(headers / 'xtc/xtc.h').write_text('old installation marker\n')
|
||||||
run(make + ['install'] + variables, env=env)
|
install_command('install', variables, check=True)
|
||||||
assert (headers / 'xtc/xtc.h').read_bytes() == (source / 'include/xtc/xtc.h').read_bytes()
|
assert (headers / 'xtc/xtc.h').read_bytes() == (source / 'include/xtc/xtc.h').read_bytes()
|
||||||
assert sentinel.read_text() == 'keep\n'
|
assert sentinel.read_text() == 'keep\n'
|
||||||
assert protected.read_text() == 'keep unrelated target\n'
|
assert protected.read_text() == 'keep unrelated target\n'
|
||||||
|
|
@ -79,8 +98,7 @@ def main():
|
||||||
pkg_env = dict(env, PKG_CONFIG_PATH=str(metadata) + ':' + env.get('PKG_CONFIG_PATH', ''),
|
pkg_env = dict(env, PKG_CONFIG_PATH=str(metadata) + ':' + env.get('PKG_CONFIG_PATH', ''),
|
||||||
PKG_CONFIG_SYSROOT_DIR=str(stage))
|
PKG_CONFIG_SYSROOT_DIR=str(stage))
|
||||||
pkg = shlex.split(os.environ.get('PKG_CONFIG', 'pkg-config'))
|
pkg = shlex.split(os.environ.get('PKG_CONFIG', 'pkg-config'))
|
||||||
# A no-JACK test can be invoked with PKG_CONFIG=false; package consumer
|
# The build may disable JACK; consumer discovery still uses pkg-config.
|
||||||
# discovery itself still uses the installed pkg-config tool.
|
|
||||||
if pkg == ['false']:
|
if pkg == ['false']:
|
||||||
pkg = ['pkg-config']
|
pkg = ['pkg-config']
|
||||||
flags = shlex.split(subprocess.check_output(pkg + ['--cflags', '--libs', '--static', 'xtc'], env=pkg_env, text=True))
|
flags = shlex.split(subprocess.check_output(pkg + ['--cflags', '--libs', '--static', 'xtc'], env=pkg_env, text=True))
|
||||||
|
|
@ -110,7 +128,7 @@ int main(int argc, char **argv) {
|
||||||
run(command + [f'-std={standard}', '-Wall', '-Wextra', '-Werror', str(consumer)] + flags + ['-o', str(output)])
|
run(command + [f'-std={standard}', '-Wall', '-Wextra', '-Werror', str(consumer)] + flags + ['-o', str(output)])
|
||||||
run([str(output), str(stage / ("installed-" + compiler + ".xtc"))])
|
run([str(output), str(stage / ("installed-" + compiler + ".xtc"))])
|
||||||
if args.gui:
|
if args.gui:
|
||||||
run(make + ['install-gui'] + variables, env=env)
|
install_command('install', variables + ['-DXTC_INSTALL_GUI=ON'], check=True)
|
||||||
gui_env = dict(env, DISPLAY='', WAYLAND_DISPLAY='')
|
gui_env = dict(env, DISPLAY='', WAYLAND_DISPLAY='')
|
||||||
assert subprocess.check_output([str(binaries / 'xtc'), '--version'], env=gui_env, text=True) == version
|
assert subprocess.check_output([str(binaries / 'xtc'), '--version'], env=gui_env, text=True) == version
|
||||||
run([str(binaries / 'xtc'), '--help'], env=gui_env)
|
run([str(binaries / 'xtc'), '--help'], env=gui_env)
|
||||||
|
|
@ -120,9 +138,9 @@ int main(int argc, char **argv) {
|
||||||
with tempfile.TemporaryDirectory(prefix='xtc-install-outside-') as outside:
|
with tempfile.TemporaryDirectory(prefix='xtc-install-outside-') as outside:
|
||||||
escape = root / 'escape'
|
escape = root / 'escape'
|
||||||
escape.symlink_to(outside, target_is_directory=True)
|
escape.symlink_to(outside, target_is_directory=True)
|
||||||
redirected = variables + [f'docdir={prefix}/escape/docs']
|
redirected = variables + [f'-DCMAKE_INSTALL_DOCDIR={prefix}/escape/docs']
|
||||||
for operation in ('install', 'uninstall'):
|
for operation in ('install', 'uninstall'):
|
||||||
refusal = subprocess.run(make + [operation] + redirected, env=env,
|
refusal = install_command(operation, redirected,
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
assert refusal.returncode != 0 and not list(Path(outside).iterdir())
|
assert refusal.returncode != 0 and not list(Path(outside).iterdir())
|
||||||
assert (headers / 'xtc/xtc.h').is_file()
|
assert (headers / 'xtc/xtc.h').is_file()
|
||||||
|
|
@ -131,13 +149,13 @@ int main(int argc, char **argv) {
|
||||||
saved_binary = stage / 'saved-check'
|
saved_binary = stage / 'saved-check'
|
||||||
(binaries / 'xtc-check').rename(saved_binary)
|
(binaries / 'xtc-check').rename(saved_binary)
|
||||||
(binaries / 'xtc-check').mkdir()
|
(binaries / 'xtc-check').mkdir()
|
||||||
refusal = subprocess.run(make + ['uninstall'] + variables, env=env,
|
refusal = install_command('uninstall', variables + ['-DCMAKE_INSTALL_DOCDIR=manual' if args.custom_layout else '-DCMAKE_INSTALL_DOCDIR=share/doc/xtc'],
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
assert refusal.returncode != 0 and (headers / 'xtc/xtc.h').is_file()
|
assert refusal.returncode != 0 and (headers / 'xtc/xtc.h').is_file()
|
||||||
(binaries / 'xtc-check').rmdir()
|
(binaries / 'xtc-check').rmdir()
|
||||||
saved_binary.rename(binaries / 'xtc-check')
|
saved_binary.rename(binaries / 'xtc-check')
|
||||||
run(make + ['uninstall'] + variables, env=env)
|
install_command('uninstall', variables, check=True)
|
||||||
run(make + ['uninstall'] + variables, env=env)
|
install_command('uninstall', variables, check=True)
|
||||||
remaining = sorted(p.relative_to(root).as_posix() for p in root.rglob('*') if p.is_file() or p.is_symlink())
|
remaining = sorted(p.relative_to(root).as_posix() for p in root.rglob('*') if p.is_file() or p.is_symlink())
|
||||||
assert remaining == ['lib/keep-unrelated.txt'], remaining
|
assert remaining == ['lib/keep-unrelated.txt'], remaining
|
||||||
assert sentinel.read_text() == 'keep\n'
|
assert sentinel.read_text() == 'keep\n'
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import argparse
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import shlex
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
@ -18,6 +17,7 @@ def main():
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument('archive', type=Path)
|
parser.add_argument('archive', type=Path)
|
||||||
parser.add_argument('--gui', action='store_true')
|
parser.add_argument('--gui', action='store_true')
|
||||||
|
parser.add_argument('--generator', default=os.environ.get('CMAKE_GENERATOR'))
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
archive = args.archive.resolve()
|
archive = args.archive.resolve()
|
||||||
assert archive.with_name(archive.name + '.sha256').read_text().split()[0] == digest(archive)
|
assert archive.with_name(archive.name + '.sha256').read_text().split()[0] == digest(archive)
|
||||||
|
|
@ -33,16 +33,23 @@ def main():
|
||||||
assert all('__pycache__' not in Path(n).parts and '.git' not in Path(n).parts for n in names)
|
assert all('__pycache__' not in Path(n).parts and '.git' not in Path(n).parts for n in names)
|
||||||
for name in ('first', 'different-path'):
|
for name in ('first', 'different-path'):
|
||||||
source.extractall(root / name, filter='data')
|
source.extractall(root / name, filter='data')
|
||||||
env = dict(os.environ, SOURCE_DATE_EPOCH=str(epoch), MAKEFLAGS='', MFLAGS='')
|
env = dict(os.environ, SOURCE_DATE_EPOCH=str(epoch))
|
||||||
|
if args.generator:
|
||||||
|
env['CMAKE_GENERATOR'] = args.generator
|
||||||
builds = []
|
builds = []
|
||||||
for name in ('first', 'different-path'):
|
for name in ('first', 'different-path'):
|
||||||
project = root / name / top
|
project = root / name / top
|
||||||
log = root / (name + '.log')
|
log = root / (name + '.log')
|
||||||
make = shlex.split(env.get('MAKE', 'make'))
|
|
||||||
with log.open('w') as output:
|
with log.open('w') as output:
|
||||||
try:
|
try:
|
||||||
subprocess.run(make + ['BUILD_DIR=build', 'release'], cwd=project, env=env, stdout=output,
|
subprocess.run(['cmake', '-S', '.', '-B', 'build/release',
|
||||||
stderr=subprocess.STDOUT, check=True)
|
'-DCMAKE_BUILD_TYPE=Release', '-DXTC_REPRODUCIBLE=ON',
|
||||||
|
f'-DXTC_BUILD_GUI={"ON" if args.gui else "OFF"}'],
|
||||||
|
cwd=project, env=env, stdout=output, stderr=subprocess.STDOUT, check=True)
|
||||||
|
subprocess.run(['cmake', '--build', 'build/release', '--parallel', '3'],
|
||||||
|
cwd=project, env=env, stdout=output, stderr=subprocess.STDOUT, check=True)
|
||||||
|
subprocess.run(['ctest', '--test-dir', 'build/release', '--output-on-failure'],
|
||||||
|
cwd=project, env=env, stdout=output, stderr=subprocess.STDOUT, check=True)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
print(log.read_text()[-12000:])
|
print(log.read_text()[-12000:])
|
||||||
raise
|
raise
|
||||||
|
|
|
||||||
21
third_party/README.md
vendored
21
third_party/README.md
vendored
|
|
@ -29,3 +29,24 @@ vendored headers. The inspected JUCE 9.0.4 revision is AGPLv3/commercial; a
|
||||||
commercial licence may be required. Original example source does not relicense
|
commercial licence may be required. Original example source does not relicense
|
||||||
JUCE or its dependencies. JUCE-linked outputs stay outside normal install and
|
JUCE or its dependencies. JUCE-linked outputs stay outside normal install and
|
||||||
package targets. See [JUCE dependency/license details](../docs/JUCE.md).
|
package targets. See [JUCE dependency/license details](../docs/JUCE.md).
|
||||||
|
|
||||||
|
## CMake integration
|
||||||
|
|
||||||
|
The root CMake target `xtc-core` uses the pinned CLAP/VST3 directories as private
|
||||||
|
system include paths. No download step or SDK runtime is required. Configure
|
||||||
|
optional full SDK builds explicitly:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DXTC_BUILD_STEINBERG=ON -DXTC_VST3_SDK_ROOT=/path/to/vst3sdk \
|
||||||
|
-DXTC_BUILD_JUCE=ON -DXTC_JUCE_ROOT=/path/to/JUCE
|
||||||
|
cmake --build build --parallel 3
|
||||||
|
ctest --test-dir build --output-on-failure -R 'steinberg|juce'
|
||||||
|
```
|
||||||
|
|
||||||
|
Leave both options off for normal builds. ASIO's native Windows diagnostic
|
||||||
|
retains its separate CMake configuration described in the Steinberg examples;
|
||||||
|
the Linux core is not a Windows/ASIO backend. See [BUILD.md](../docs/BUILD.md)
|
||||||
|
for target options and [RELEASING.md](../docs/RELEASING.md) for staging. The
|
||||||
|
owned install inventory retains the CLAP and VST3 C-header license notices;
|
||||||
|
JUCE/official SDK plugin binaries are excluded from normal install/package targets.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if not shutil.which("clang"):
|
if not shutil.which("clang"):
|
||||||
sys.exit("clang is required for make analyze")
|
sys.exit("clang is required for the CMake analyze target")
|
||||||
jack = subprocess.run(["pkg-config", "--cflags", "jack"], capture_output=True, text=True) if shutil.which("pkg-config") else None
|
jack = subprocess.run(["pkg-config", "--cflags", "jack"], capture_output=True, text=True) if shutil.which("pkg-config") else None
|
||||||
for source in sys.argv[1:]:
|
for source in sys.argv[1:]:
|
||||||
flags = []
|
flags = []
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
import shlex
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
@ -29,9 +28,23 @@ def main():
|
||||||
a.output.parent.mkdir(parents=True, exist_ok=True)
|
a.output.parent.mkdir(parents=True, exist_ok=True)
|
||||||
with tempfile.TemporaryDirectory(prefix='xtc-binary-stage-') as temporary:
|
with tempfile.TemporaryDirectory(prefix='xtc-binary-stage-') as temporary:
|
||||||
stage = Path(temporary)
|
stage = Path(temporary)
|
||||||
env = dict(os.environ, MAKEFLAGS='', MFLAGS='')
|
env = dict(os.environ)
|
||||||
subprocess.run(shlex.split(env.get('MAKE', 'make')) + ['install-gui' if a.gui else 'install',
|
driver = stage / 'cmake-driver'
|
||||||
f'BUILD_DIR={a.build_dir.resolve()}', f'DESTDIR={stage}', 'PREFIX=/usr'], env=env, check=True)
|
cache = (a.build_dir / 'CMakeCache.txt').read_text()
|
||||||
|
generator = next(line.partition('=')[2] for line in cache.splitlines()
|
||||||
|
if line.startswith('CMAKE_GENERATOR:INTERNAL='))
|
||||||
|
jack = 'OFF' if 'XTC_WITH_JACK:BOOL=OFF' in cache else 'ON'
|
||||||
|
subprocess.run(['cmake', '-G', generator, '-S', str(Path.cwd()), '-B', str(driver),
|
||||||
|
'-DBUILD_TESTING=OFF', '-DCMAKE_INSTALL_PREFIX=/usr', '-DCMAKE_INSTALL_LIBDIR=lib',
|
||||||
|
f'-DXTC_BUILD_GUI={"ON" if a.gui else "OFF"}',
|
||||||
|
'-DXTC_INSTALL_PKGCONFIGDIR=lib/pkgconfig',
|
||||||
|
f'-DXTC_INSTALL_BUILD_DIR={a.build_dir.resolve()}',
|
||||||
|
f'-DXTC_WITH_JACK={jack}', f'-DXTC_INSTALL_GUI={"ON" if a.gui else "OFF"}'],
|
||||||
|
env=env, check=True)
|
||||||
|
subprocess.run(['cmake', '--install', str(driver)], env=dict(env, DESTDIR=str(stage)), check=True)
|
||||||
|
# Only the installed /usr tree belongs to the archive.
|
||||||
|
import shutil
|
||||||
|
shutil.rmtree(driver)
|
||||||
pc = stage / 'usr/lib/pkgconfig/xtc.pc'
|
pc = stage / 'usr/lib/pkgconfig/xtc.pc'
|
||||||
pc.write_text(pc.read_text().replace('prefix=/usr\n', 'prefix=${pcfiledir}/../..\n'))
|
pc.write_text(pc.read_text().replace('prefix=/usr\n', 'prefix=${pcfiledir}/../..\n'))
|
||||||
entries = []
|
entries = []
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue