Merge cmake-cleanup: per-directory CMakeLists split, shared target helpers, and one-mechanism core/ linkage

This commit is contained in:
2026-07-30 12:41:56 -04:00
21 changed files with 576 additions and 1378 deletions
+2 -2
View File
@@ -42,7 +42,7 @@ Vendors three submodules (see `.gitmodules`):
cmake --build build cmake --build build
ctest --test-dir build ctest --test-dir build
Every pure module has a corresponding `<module>_tests` executable target that runs without REAPER or a DAW. `CMakeLists.txt` is the authoritative target list. The two loadable-module targets are `reaper_reasampler` (the REAPER extension `.dll`/`.dylib`/`.so`) and `reasampler_vst` (the VST3 instrument; Windows-only, omitted if the `vendor/vst3sdk` slice is absent). The `sample_usage_tests` executable target runs the pure unit tests for `sample_usage` (no REAPER, no DAW). Every pure module has a corresponding `<module>_tests` executable target that runs without REAPER or a DAW. Targets are declared per directory: each `src/**/CMakeLists.txt` owns its own libraries and their test targets, added via `add_subdirectory` from the root, which keeps only repo-global settings (version, channel, vendor paths). `cmake/reasampler_targets.cmake` holds the two shared declaration helpers. The two loadable-module targets are `reaper_reasampler` (the REAPER extension `.dll`/`.dylib`/`.so`) and `reasampler_vst` (the VST3 instrument; Windows-only, omitted if the `vendor/vst3sdk` slice is absent). The `sample_usage_tests` executable target runs the pure unit tests for `sample_usage` (no REAPER, no DAW).
### Beta channel build ### Beta channel build
@@ -61,7 +61,7 @@ The VST3 target forks identically: `REASAMPLER_CHANNEL=beta` produces `reasample
php vendor/WDL/WDL/swell/swell_resgen.php src/resource.rc # macOS; Linux reuses the output php vendor/WDL/WDL/swell/swell_resgen.php src/resource.rc # macOS; Linux reuses the output
Add the generated file to the appropriate `APPLE` / Linux `target_sources` block in CMakeLists.txt. The SWS extension build is the canonical reference for this step. Add the generated file to the appropriate `APPLE` / Linux `target_sources` block in `src/app/CMakeLists.txt`. The SWS extension build is the canonical reference for this step.
### Install / reload ### Install / reload
+45 -1373
View File
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
# The two shapes that repeat across src/: a pure static library and its CTest target.
# Both are thin pass-throughs — LINK is forwarded to target_link_libraries verbatim, so
# PUBLIC/PRIVATE keywords and link order stay visible at the call site rather than being
# invented by the helper. Targets that genuinely deviate are written out longhand.
# Every pure library carries src/ as a PUBLIC include dir: headers are included rooted
# there ("core/json/json.h"), so a consumer needs only the link edge.
function(reasampler_pure_library name)
cmake_parse_arguments(ARG "" "" "SOURCES;LINK" ${ARGN})
add_library(${name} STATIC ${ARG_SOURCES})
target_include_directories(${name} PUBLIC ${REASAMPLER_SRC_DIR})
if(ARG_LINK)
target_link_libraries(${name} ${ARG_LINK})
endif()
endfunction()
# Test naming is exceptionless: target <name>_tests is built from tests/test_<name>.cpp
# and registered under its own target name.
function(reasampler_test name)
cmake_parse_arguments(ARG "" "" "LINK" ${ARGN})
add_executable(${name}_tests ${REASAMPLER_TESTS_DIR}/test_${name}.cpp)
target_link_libraries(${name}_tests PRIVATE ${ARG_LINK})
add_test(NAME ${name}_tests COMMAND ${name}_tests)
endfunction()
+90
View File
@@ -0,0 +1,90 @@
# The REAPER extension — a loadable module REAPER dlopen()s, never linked against. Paths
# below are rooted at src/, not relative to this directory.
# No core/ TU is ever compiled into this source list; every core/ TU enters through a link edge
# instead. Compiling one here too would give it its own copy, built under this target's own
# compile definitions and include dirs — free to diverge from the library copy every other
# consumer (the <module>_tests targets, reasampler_vst) links, with nothing to detect it.
add_library(reaper_reasampler MODULE
${REASAMPLER_SRC_DIR}/app/main.cpp
${REASAMPLER_SRC_DIR}/shell/capture/capture.cpp
${REASAMPLER_SRC_DIR}/shell/capture/capture_orchestrator.cpp
${REASAMPLER_SRC_DIR}/shell/capture/capture_batch.cpp
${REASAMPLER_SRC_DIR}/shell/capture/scope_resolve.cpp
${REASAMPLER_SRC_DIR}/shell/capture/realtime_lifecycle.cpp
${REASAMPLER_SRC_DIR}/shell/capture/capture_realtime_shell.cpp
${REASAMPLER_SRC_DIR}/shell/capture/capture_realtime_finalize.cpp
${REASAMPLER_SRC_DIR}/shell/persist/session.cpp
${REASAMPLER_SRC_DIR}/shell/persist/ext_state_io.cpp
${REASAMPLER_SRC_DIR}/shell/persist/prune_fs.cpp
${REASAMPLER_SRC_DIR}/shell/bank_ops/bank_ops.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_audition.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_bank_ops.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_drag.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_input.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_layout.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_render.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_thumbnails.cpp
${REASAMPLER_SRC_DIR}/shell/panel/panel_window.cpp
# draw_kit is compiled into each module rather than being a static library — see root
# CMakeLists.txt's LICE_SRC comment for why.
${REASAMPLER_SRC_DIR}/shell/panel/draw_kit.cpp
${LICE_SRC}
${REASAMPLER_SRC_DIR}/shell/capture/insert.cpp
${REASAMPLER_SRC_DIR}/shell/view/view.cpp
${REASAMPLER_SRC_DIR}/shell/capture/track_guid.cpp
${REASAMPLER_SRC_DIR}/shell/capture/provenance_shell.cpp
${REASAMPLER_SRC_DIR}/shell/capture/item_read.cpp
${REASAMPLER_SRC_DIR}/shell/actions/action_registry.cpp
${REASAMPLER_SRC_DIR}/shell/actions/design_view_actions.cpp
${REASAMPLER_SRC_DIR}/shell/actions/bank_actions.cpp
${REASAMPLER_SRC_DIR}/shell/actions/prune_action.cpp
${REASAMPLER_SRC_DIR}/shell/actions/ingest.cpp
${REASAMPLER_SRC_DIR}/shell/actions/drag_out_win.cpp
${REASAMPLER_SRC_DIR}/shell/actions/instrument_drop_win.cpp
${REASAMPLER_SRC_DIR}/shell/persist/usage_scan.cpp
)
target_link_libraries(reaper_reasampler PRIVATE json wire file_bytes bank_model capture_paths peaks bank_grid mode_switch tab_strip view_mode_model view_tree guid_diff lane_keys insert_plan render_settings batch_capture tail_control capture_realtime bank_book wav_codec owned_manifest prune_reconcile prune_button app_version provenance drag_out instrument_drop theme component_geometry action_bar footer_bar overflow_menu mode_enable tooltip card_meta card_drag assignment_request bank_sync sample_usage)
target_include_directories(reaper_reasampler PRIVATE ${SDK_INC} ${WDL_INC})
# OUTPUT_NAME is channel-derived; the CMake target name stays "reaper_reasampler" for both
# configs, since REAPER dlopen's any reaper_* module and the two channels' artifacts load
# side-by-side. LIBRARY_OUTPUT_DIRECTORY pins the module to the top of the build tree even
# though this target is declared in a subdirectory — the install step copies it from there.
# ARCHIVE_OUTPUT_DIRECTORY pins the same for MODULE targets: CMake emits an import-lib
# sidecar (.lib/.exp on MSVC) keyed off ARCHIVE_OUTPUT_DIRECTORY, not LIBRARY_OUTPUT_DIRECTORY,
# so it needs pinning too even though nothing links against this import lib.
set_target_properties(reaper_reasampler PROPERTIES
PREFIX ""
OUTPUT_NAME "${REASAMPLER_OUTPUT_NAME}"
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
if(WIN32)
# Native Win32; REAPER provides nothing extra to link. The bank-panel dialog template
# is compiled from resource.rc by the platform RC compiler.
target_sources(reaper_reasampler PRIVATE ${REASAMPLER_SRC_DIR}/resource.rc)
elseif(APPLE)
# Use REAPER's OWN SWELL at runtime via the modstub. Do NOT build full SWELL —
# SWELL_PROVIDED_BY_APP routes calls to the host.
target_sources(reaper_reasampler PRIVATE ${SWELL}/swell-modstub.mm)
target_compile_definitions(reaper_reasampler PRIVATE SWELL_PROVIDED_BY_APP)
target_link_libraries(reaper_reasampler PRIVATE "-framework AppKit")
set_target_properties(reaper_reasampler PROPERTIES SUFFIX ".dylib")
# SWELL can't read a Win32 .rc directly. Run resgen once to turn resource.rc into a
# C++ source, then add it here:
# php ${WDL_INC}/swell/mac_resgen.php src/resource.rc
# target_sources(reaper_reasampler PRIVATE ${REASAMPLER_SRC_DIR}/resource.rc_mac_dlg.h)
else()
# Linux: REAPER's libSwell.so is used at runtime via the generic modstub. With
# SWELL_PROVIDED_BY_APP you can drop pkg-config / -lX11 entirely.
target_sources(reaper_reasampler PRIVATE ${SWELL}/swell-modstub-generic.cpp)
target_compile_definitions(reaper_reasampler PRIVATE SWELL_PROVIDED_BY_APP)
set_target_properties(reaper_reasampler PROPERTIES SUFFIX ".so")
# Reuse the macOS resgen output (see CLAUDE.md, SWELL dialog resources), then add the
# generated source:
# php ${WDL_INC}/swell/mac_resgen.php src/resource.rc
# target_sources(reaper_reasampler PRIVATE ${REASAMPLER_SRC_DIR}/resource.rc_mac_dlg.h)
endif()
+17
View File
@@ -0,0 +1,17 @@
# The pure substrate — see root CLAUDE.md's architecture section for the core/ purity invariant.
#
# Declaration order below runs base-first so the file reads as a dependency ladder; CMake
# itself does not require it (link names resolve at generate time), and a few edges do run
# backwards — core/wire's instrument_drop reuses the instrument's own state codec.
add_subdirectory(json)
add_subdirectory(util)
add_subdirectory(wire)
add_subdirectory(audio)
add_subdirectory(model)
add_subdirectory(capture)
add_subdirectory(reclaim)
add_subdirectory(version)
add_subdirectory(view)
add_subdirectory(ui)
add_subdirectory(instrument)
+2
View File
@@ -0,0 +1,2 @@
reasampler_pure_library(peaks SOURCES peaks.cpp)
reasampler_test(peaks LINK peaks)
+22
View File
@@ -0,0 +1,22 @@
reasampler_pure_library(capture_paths SOURCES capture_paths.cpp)
reasampler_test(capture_paths LINK capture_paths)
reasampler_pure_library(insert_plan SOURCES insert_plan.cpp)
reasampler_test(insert_plan LINK insert_plan)
reasampler_pure_library(render_settings SOURCES render_settings.cpp LINK PUBLIC bank_model)
reasampler_test(render_settings LINK render_settings)
reasampler_pure_library(batch_capture SOURCES batch_capture.cpp)
reasampler_test(batch_capture LINK batch_capture)
reasampler_pure_library(tail_control
SOURCES tail_control.cpp
LINK PUBLIC render_settings PRIVATE json)
reasampler_test(tail_control LINK tail_control)
reasampler_pure_library(capture_realtime SOURCES capture_realtime.cpp LINK PUBLIC bank_model)
reasampler_test(capture_realtime LINK capture_realtime)
reasampler_pure_library(wav_codec SOURCES wav_codec.cpp LINK PUBLIC peaks)
reasampler_test(wav_codec LINK wav_codec)
+3
View File
@@ -0,0 +1,3 @@
add_subdirectory(engine)
add_subdirectory(map)
add_subdirectory(ui)
+26
View File
@@ -0,0 +1,26 @@
# The shifter is hand-rolled rather than WDL_SimplePitchShifter because that header drags
# <windows.h> in via wdltypes.h, which cannot enter the pure engine.
reasampler_pure_library(pitch_shift SOURCES pitch_shift.cpp LINK PUBLIC peaks)
# Links only pitch_shift: linking more would break the plain-data-boundary proof — and
# specifically the compile-time proof it does not drag in the WDL <windows.h> chain.
reasampler_test(pitch_shift LINK pitch_shift)
reasampler_pure_library(velocity_curve SOURCES velocity_curve.cpp)
# Links only velocity_curve, deliberately not editor_geometry: the proof the engine can
# depend on the curve without inheriting the editor's layout types.
reasampler_test(velocity_curve LINK velocity_curve)
reasampler_pure_library(master_gain SOURCES master_gain.cpp)
reasampler_test(master_gain LINK master_gain)
# Two TUs on the engine's own responsibility seam (per-note setup vs. note routing and
# block render). The per-sample render half stays inline in voice.h precisely so this TU
# boundary costs the hot path nothing.
reasampler_pure_library(sampler_core
SOURCES voice.cpp voice_engine.cpp
LINK PUBLIC peaks pitch_shift velocity_curve)
# Links only sampler_core: linking more would break the plain-data-boundary proof — a VST3
# or REAPER type reaching the core would fail to compile or link here.
reasampler_test(sampler_core LINK sampler_core)
add_subdirectory(filter)
@@ -0,0 +1,15 @@
# Control mapping, SVF coefficients, morph weights, and the filter type each get their own
# TU; VoiceFilter::process stays header-inline so the kernel still inlines at the call site.
reasampler_pure_library(filter SOURCES
filter_params.cpp
filter_coeffs.cpp
filter_morph.cpp
voice_filter.cpp)
# Four test targets along the module's own seams so each asserts one domain. filter_tests
# alone owns the analytic reference and the steady-state gain measurement — a forked copy of
# a measurement reference is a worse defect than a long file.
reasampler_test(filter_params LINK filter)
reasampler_test(filter_morph LINK filter)
reasampler_test(filter_state LINK filter)
reasampler_test(filter LINK filter)
+31
View File
@@ -0,0 +1,31 @@
reasampler_pure_library(bridge_marshal SOURCES bridge_marshal.cpp)
reasampler_test(bridge_marshal LINK bridge_marshal)
reasampler_pure_library(trigger_seam SOURCES trigger_seam.cpp)
# Links only trigger_seam — not even editor_geometry — the plainest data-boundary proof
# available.
reasampler_test(trigger_seam LINK trigger_seam)
reasampler_pure_library(bank_sync
SOURCES bank_sync.cpp
LINK PUBLIC assignment_request PRIVATE wire)
# Links only bank_sync (+ its assignment_request dep): linking more would break the
# plain-data-boundary proof.
reasampler_test(bank_sync LINK bank_sync)
# The state codec is shared with the extension's preset-blob path, so it must link WITHOUT
# the voice engine: velocity_curve (the curve field) and master_gain (the wire gain cap) only.
reasampler_pure_library(component_state_io
SOURCES component_state_io.cpp
LINK PUBLIC velocity_curve master_gain)
# Links only component_state_io, deliberately no sampler_core/pitch_shift: the structural
# proof the codec is engine-free, which is what keeps engine object code out of the extension.
reasampler_test(component_state_io LINK component_state_io)
# The mapping's product is plain SampleData, so the voice engine is not a dependency.
reasampler_pure_library(sample_map
SOURCES sample_map.cpp
LINK PUBLIC bank_book wav_codec velocity_curve peaks)
# Links only sample_map + component_state_io: the same plain-data-boundary proof, spanning
# both halves of the mapping/codec split where the frozen-format assertions live.
reasampler_test(sample_map LINK sample_map component_state_io)
+48
View File
@@ -0,0 +1,48 @@
# The geometry vocabulary every instrument UI module speaks (the Rect alias + contains())
# is header-only, hence INTERFACE.
add_library(editor_geometry INTERFACE)
target_include_directories(editor_geometry INTERFACE ${REASAMPLER_SRC_DIR})
reasampler_pure_library(sample_bands SOURCES sample_bands.cpp LINK PUBLIC editor_geometry)
reasampler_test(sample_bands LINK sample_bands)
reasampler_pure_library(sample_chrome SOURCES sample_chrome.cpp LINK PUBLIC sample_bands)
reasampler_test(sample_chrome LINK sample_chrome)
reasampler_pure_library(embed_strip SOURCES embed_strip.cpp LINK PUBLIC editor_geometry)
reasampler_test(embed_strip LINK embed_strip)
reasampler_pure_library(capture_browser SOURCES capture_browser.cpp LINK PUBLIC editor_geometry)
reasampler_test(capture_browser LINK capture_browser)
reasampler_pure_library(keyboard_strip SOURCES keyboard_strip.cpp LINK PUBLIC editor_geometry)
reasampler_test(keyboard_strip LINK keyboard_strip sample_bands sample_chrome)
# sample_bands is PRIVATE: the lane split is used internally and nothing in the public
# header needs it.
reasampler_pure_library(waveform_view
SOURCES waveform_view.cpp
LINK PUBLIC editor_geometry peaks PRIVATE sample_bands)
# sample_bands is linked directly here because the test exercises the lane metrics that
# waveform_view does not re-export.
reasampler_test(waveform_view LINK waveform_view sample_bands)
reasampler_pure_library(browser_scroll
SOURCES browser_scroll.cpp
LINK PUBLIC capture_browser sample_chrome)
reasampler_test(browser_scroll LINK browser_scroll)
reasampler_pure_library(param_slider SOURCES param_slider.cpp LINK PUBLIC editor_geometry)
reasampler_test(param_slider LINK param_slider)
reasampler_pure_library(envelope_overlay SOURCES envelope_overlay.cpp LINK PUBLIC editor_geometry)
reasampler_test(envelope_overlay LINK envelope_overlay)
reasampler_pure_library(envelope_edit SOURCES envelope_edit.cpp LINK PUBLIC envelope_overlay)
reasampler_test(envelope_edit LINK envelope_edit)
reasampler_pure_library(knob_deck SOURCES knob_deck.cpp LINK PUBLIC editor_geometry)
reasampler_test(knob_deck LINK knob_deck)
reasampler_pure_library(curve_popup SOURCES curve_popup.cpp LINK PUBLIC editor_geometry)
reasampler_test(curve_popup LINK curve_popup)
+2
View File
@@ -0,0 +1,2 @@
reasampler_pure_library(json SOURCES json.cpp)
reasampler_test(json LINK json)
+17
View File
@@ -0,0 +1,17 @@
reasampler_pure_library(bank_model SOURCES bank_model.cpp LINK PRIVATE json)
reasampler_test(bank_model LINK bank_model)
reasampler_pure_library(slot_map SOURCES slot_map.cpp LINK PRIVATE json)
reasampler_test(slot_map LINK slot_map json)
reasampler_pure_library(bank_book
SOURCES bank_book.cpp bank_book_json.cpp
LINK PUBLIC bank_model slot_map PRIVATE json)
reasampler_test(bank_book LINK bank_book)
reasampler_pure_library(owned_manifest SOURCES owned_manifest.cpp LINK PRIVATE json)
reasampler_test(owned_manifest LINK owned_manifest)
reasampler_pure_library(provenance SOURCES provenance.cpp LINK PRIVATE wire)
# bank_model: the test proves the recorded recipe survives the Sample-JSON round-trip.
reasampler_test(provenance LINK provenance bank_model)
+3
View File
@@ -0,0 +1,3 @@
reasampler_pure_library(prune_reconcile SOURCES prune_reconcile.cpp)
# bank_book supplies the cross-bank referenced-file union the orphan set is computed against.
reasampler_test(prune_reconcile LINK prune_reconcile bank_book)
+40
View File
@@ -0,0 +1,40 @@
reasampler_pure_library(bank_grid SOURCES bank_grid.cpp)
reasampler_test(bank_grid LINK bank_grid)
reasampler_pure_library(tab_strip SOURCES tab_strip.cpp)
reasampler_test(tab_strip LINK tab_strip)
reasampler_pure_library(prune_button SOURCES prune_button.cpp)
reasampler_test(prune_button LINK prune_button)
reasampler_pure_library(drag_out SOURCES drag_out.cpp)
reasampler_test(drag_out LINK drag_out)
reasampler_pure_library(theme SOURCES theme.cpp)
reasampler_test(theme LINK theme)
reasampler_pure_library(component_geometry SOURCES component_geometry.cpp)
reasampler_test(component_geometry LINK component_geometry)
reasampler_pure_library(action_bar SOURCES action_bar.cpp)
reasampler_test(action_bar LINK action_bar)
# prune_button owns the FooterRect input type the footer layout reuses.
reasampler_pure_library(footer_bar SOURCES footer_bar.cpp LINK PUBLIC prune_button)
reasampler_test(footer_bar LINK footer_bar)
reasampler_pure_library(overflow_menu SOURCES overflow_menu.cpp)
reasampler_test(overflow_menu LINK overflow_menu)
# view_mode_model owns the seed mode ids the predicate compares against.
reasampler_pure_library(mode_enable SOURCES mode_enable.cpp LINK PUBLIC view_mode_model)
reasampler_test(mode_enable LINK mode_enable)
reasampler_pure_library(tooltip SOURCES tooltip.cpp)
reasampler_test(tooltip LINK tooltip)
reasampler_pure_library(card_meta SOURCES card_meta.cpp)
reasampler_test(card_meta LINK card_meta)
reasampler_pure_library(card_drag SOURCES card_drag.cpp LINK PUBLIC drag_out bank_grid)
reasampler_test(card_drag LINK card_drag)
+2
View File
@@ -0,0 +1,2 @@
reasampler_pure_library(file_bytes SOURCES file_bytes.cpp)
reasampler_test(file_bytes LINK file_bytes)
+42
View File
@@ -0,0 +1,42 @@
reasampler_pure_library(app_version SOURCES app_version.cpp)
# version_generated.h, configured at the root from the one REASAMPLER_VERSION string.
# PUBLIC so every consumer of the channel bit sees it.
target_include_directories(app_version PUBLIC ${PROJECT_BINARY_DIR}/generated)
reasampler_test(app_version LINK app_version)
# Anti-normalization padding canary (rationale in tests/test_app_version_padding.cpp). The
# live-version assertions in app_version_tests are version-shape-blind relative checks
# such as appVersion() == stampVersion() hold whether the string was threaded verbatim or
# reconstructed from numeric components so that suite cannot detect a
# reconstruct-from-components regression at all. So: run the SAME template through
# configure_file a second time with a SYNTHETIC padded version, and compile the SAME
# app_version.cpp against it.
#
# "0.9.01" is a permanent test fixture, NOT the shipped version. It must match the literals
# in test_app_version_padding.cpp and must NEVER be bumped on release.
#
# Coverage boundary: this catches reconstruct-from-components inside app_version.cpp. It
# cannot see the live source-of-truth line becoming a CMake variable derivation the
# comment block at the top of the root CMakeLists.txt guards that half.
function(_configure_padding_canary)
# set() inside a function is function-scoped, so this clobber cannot leak to the parent
# scope no save/restore dance needed. REASAMPLER_CHANNEL_IS_BETA and the directory
# variables are inherited read-only.
set(REASAMPLER_VERSION "0.9.01")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/version_generated.h.in
${PROJECT_BINARY_DIR}/generated_padding_canary/version_generated.h
@ONLY)
endfunction()
_configure_padding_canary()
# Longhand rather than reasampler_test: the canary RECOMPILES app_version.cpp instead of
# linking the library, which is what lets the include-dir substitution work it must see
# generated_padding_canary/ in place of the live generated/ dir. If app_version ever gains
# a link dependency, mirror it here.
add_executable(app_version_padding_tests
${REASAMPLER_TESTS_DIR}/test_app_version_padding.cpp
app_version.cpp)
target_include_directories(app_version_padding_tests PRIVATE
${PROJECT_BINARY_DIR}/generated_padding_canary ${REASAMPLER_SRC_DIR})
add_test(NAME app_version_padding_tests COMMAND app_version_padding_tests)
+18
View File
@@ -0,0 +1,18 @@
reasampler_pure_library(lane_keys SOURCES lane_keys.cpp)
reasampler_test(lane_keys LINK lane_keys)
# lane_keys is PUBLIC: the lane-minting plan names managed lanes through the one durable-key
# convention, so every consumer has to resolve that symbol too.
reasampler_pure_library(view_mode_model
SOURCES view_mode_model.cpp
LINK PRIVATE json PUBLIC lane_keys)
reasampler_test(view_mode_model LINK view_mode_model)
reasampler_pure_library(view_tree SOURCES view_tree.cpp LINK PUBLIC view_mode_model)
reasampler_test(view_tree LINK view_tree)
reasampler_pure_library(guid_diff SOURCES guid_diff.cpp)
reasampler_test(guid_diff LINK guid_diff)
reasampler_pure_library(mode_switch SOURCES mode_switch.cpp)
reasampler_test(mode_switch LINK mode_switch)
+18
View File
@@ -0,0 +1,18 @@
reasampler_pure_library(wire SOURCES wire.cpp)
reasampler_test(wire LINK wire)
reasampler_pure_library(assignment_request SOURCES assignment_request.cpp LINK PRIVATE wire)
reasampler_test(assignment_request LINK assignment_request)
reasampler_pure_library(sample_usage SOURCES sample_usage.cpp LINK PRIVATE wire)
# prune_reconcile composes the protection proof at the pure layer: a capture held by a live
# instance lands in the referenced union, so pruneOrphans can never emit it.
reasampler_test(sample_usage LINK sample_usage prune_reconcile)
# The drop payload is built through the instrument's OWN state serializer rather than a
# parallel byte writer, so the cross-artifact contract cannot drift hence the link to
# component_state_io, which stays engine-free. The class-ID string derives from the frozen
# UID macros, channel-selected via the generated version header, hence its include dir.
reasampler_pure_library(instrument_drop SOURCES instrument_drop.cpp LINK PUBLIC component_state_io)
target_include_directories(instrument_drop PUBLIC ${PROJECT_BINARY_DIR}/generated)
reasampler_test(instrument_drop LINK instrument_drop)
+106
View File
@@ -0,0 +1,106 @@
# ReaSampler 9000 the second build artifact: a Windows-only VST3 instrument the user
# instantiates on an instrument track. Additive; the extension builds unchanged.
#
# The nested vst3sdk slice (pluginterfaces / base / public.sdk) is a one-time submodule
# step documented in CLAUDE.md. When it is absent a fresh clone that ran only the
# top-level init skip this module rather than fail configure on missing sources: the pure
# libraries and their CTest targets still build and test without the SDK. Probe one
# representative source file.
if(WIN32 AND EXISTS "${VST3_SDK}/public.sdk/source/main/pluginfactory.cpp")
# The bounded slice of the Steinberg VST3 SDK this instrument needs. Enumerated rather
# than add_subdirectory of the whole SDK to keep the build hermetic and lean: no VSTGUI,
# no examples, no SDK-global CMake helpers or install machinery. The submodule is pinned
# to tag v3.7.9_build_61, so the list is fixed re-verify this set if the tag is bumped.
add_library(vst3_sdk STATIC
${VST3_SDK}/pluginterfaces/base/funknown.cpp
${VST3_SDK}/pluginterfaces/base/coreiids.cpp
${VST3_SDK}/pluginterfaces/base/conststringtable.cpp
${VST3_SDK}/pluginterfaces/base/ustring.cpp
${VST3_SDK}/base/source/fobject.cpp
${VST3_SDK}/base/source/fstring.cpp
${VST3_SDK}/base/source/fbuffer.cpp
${VST3_SDK}/base/source/fstreamer.cpp
${VST3_SDK}/base/source/fdebug.cpp
${VST3_SDK}/base/source/baseiids.cpp
${VST3_SDK}/base/source/updatehandler.cpp
${VST3_SDK}/base/thread/source/flock.cpp
# vstsinglecomponenteffect.cpp #includes vsteditcontroller.cpp unity-style, so
# vsteditcontroller.cpp must NOT be listed separately (double definition).
${VST3_SDK}/public.sdk/source/vst/vstsinglecomponenteffect.cpp
${VST3_SDK}/public.sdk/source/vst/vstcomponentbase.cpp
${VST3_SDK}/public.sdk/source/vst/vstbus.cpp
${VST3_SDK}/public.sdk/source/vst/vstparameters.cpp
${VST3_SDK}/public.sdk/source/vst/vstinitiids.cpp
${VST3_SDK}/public.sdk/source/common/pluginview.cpp
${VST3_SDK}/public.sdk/source/common/commoniids.cpp
# dllmain.cpp + moduleinit.cpp are NOT here see the module target below.
${VST3_SDK}/public.sdk/source/main/pluginfactory.cpp
)
target_include_directories(vst3_sdk PUBLIC ${VST3_SDK})
# The SDK requires exactly one of RELEASE / DEVELOPMENT (fdebug.cpp keys off it).
target_compile_definitions(vst3_sdk PUBLIC $<IF:$<CONFIG:Debug>,DEVELOPMENT=1,RELEASE=1>)
add_library(reasampler_vst MODULE
vst_entry.cpp
reasampler_processor.cpp
processor_state.cpp
processor_reload.cpp
# The editor family is split on the Sample face's band axis: session/bridge state,
# param plumbing plus the shared band-layout resolve, then paint and input in
# matching sets, plus the two band-independent surfaces and the platform TU.
editor_session.cpp
editor_controls.cpp
editor_paint.cpp
editor_paint_chrome.cpp
editor_paint_waveform.cpp
editor_paint_deck.cpp
editor_paint_browse.cpp
editor_paint_curve.cpp
editor_input.cpp
editor_input_chrome.cpp
editor_input_waveform.cpp
editor_input_deck.cpp
editor_input_browse.cpp
editor_input_curve.cpp
editor_platform.cpp
reasampler_embed.cpp
reaper_bridge.cpp
# draw_kit is compiled into each module rather than being a static library see root
# CMakeLists.txt's LICE_SRC comment for why.
${REASAMPLER_SRC_DIR}/shell/panel/draw_kit.cpp
# Compiled into the module, NOT into vst3_sdk: their SMTG_EXPORT_SYMBOL functions
# (InitDll/ExitDll) have no internal referrer, so the linker strips them from a
# static library. Compiling them here keeps the exports.
${VST3_SDK}/public.sdk/source/main/dllmain.cpp
${VST3_SDK}/public.sdk/source/main/moduleinit.cpp
${LICE_SRC}
)
# sample_map's build yields plain SampleData, so it does NOT pull the voice engine
# sampler_core is linked directly. app_version's PUBLIC include dir carries the
# generated version header, so the instrument reads the SAME channel-derived ext-state
# namespace the extension writes.
target_link_libraries(reasampler_vst PRIVATE vst3_sdk editor_geometry bridge_marshal
sampler_core sample_map component_state_io capture_paths embed_strip app_version
capture_browser keyboard_strip sample_bands sample_chrome
waveform_view bank_sync browser_scroll param_slider tooltip
theme component_geometry bank_grid trigger_seam envelope_overlay envelope_edit
knob_deck curve_popup master_gain sample_usage file_bytes)
# SDK_INC gives the REAPER VST3 interfaces + API header for the bridge; WDL_INC gives
# LICE for the editor. The VST3 SDK headers arrive via vst3_sdk PUBLIC.
target_include_directories(reasampler_vst PRIVATE ${REASAMPLER_SRC_DIR} ${SDK_INC} ${WDL_INC})
# A .vst3 is a DLL with a .vst3 extension and no lib prefix. OUTPUT_NAME is channel-
# forked from the one channel decision at the root and must match
# app_version::vstOutputName(); the two channels install side-by-side, and the
# per-channel VST3 class UID keeps a saved instance bound to its own channel.
# LIBRARY_OUTPUT_DIRECTORY / ARCHIVE_OUTPUT_DIRECTORY pin the module to the top of the
# build tree even though this target is declared in a subdirectory see src/app/CMakeLists.txt's
# set_target_properties comment for why both properties are needed.
set_target_properties(reasampler_vst PROPERTIES
PREFIX ""
SUFFIX ".vst3"
OUTPUT_NAME "${REASAMPLER_VST_OUTPUT_NAME}"
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
endif()