build: extract CMake plugin/harness modules and add platform build scripts

Split CMakeLists.txt into cmake/Plugin.cmake (production formats and
MinGW link flags) and cmake/Harness.cmake (console test harness with
CTest registration). Add SERUMALT_BUILD_PLUGIN and SERUMALT_BUILD_TESTS
options so production and harness builds are mutually exclusive and
each omits the other's targets.

Add build_linux.sh, build_macos.sh, and build_harness.sh with host
validation, env-overridable build dirs, and explicit option flags.
Rewrite build_windows.sh to use the checked-in mingw64-toolchain.cmake
instead of regenerating it, validate all required tools, and stage
with cmake -E copy_directory.

Broaden .gitignore to cover all build_*/ directories.
This commit is contained in:
2026-09-09 13:24:09 +02:00
parent a1feeb76f0
commit f10409ad1e
8 changed files with 260 additions and 118 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# CMake build directories # CMake build directories
/build/ /build/
/build_windows/ /build_*/
/cmake-build-*/ /cmake-build-*/
# Windows output staging # Windows output staging
+27 -63
View File
@@ -9,43 +9,20 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
option(SERUMALT_BUILD_PLUGIN "Build production plugin and standalone formats" ON)
option(SERUMALT_BUILD_TESTS "Build the headless QA harness" OFF)
if(NOT SERUMALT_BUILD_PLUGIN AND NOT SERUMALT_BUILD_TESTS)
message(FATAL_ERROR "Enable SERUMALT_BUILD_PLUGIN or SERUMALT_BUILD_TESTS")
endif()
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# JUCE # JUCE
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
if(NOT DEFINED JUCE_ROOT) if(NOT DEFINED JUCE_ROOT)
set(JUCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/third_party/JUCE") set(JUCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/third_party/JUCE")
endif() endif()
add_subdirectory("${JUCE_ROOT}") add_subdirectory("${JUCE_ROOT}" "${CMAKE_CURRENT_BINARY_DIR}/third_party/JUCE")
# ---------------------------------------------------------------------------
# Plugin target
# ---------------------------------------------------------------------------
# JUCE 7.0.12 builds its VST3 manifest helper (juce_vst3_helper) with the same
# toolchain as the plugin itself. When cross-compiling, that produces a Windows
# .exe which cannot run on the Linux build host, so we disable the automatic
# manifest step and inject a platform-independent moduleinfo.json afterwards
# (see build_windows.sh). Native builds keep the automatic step.
set(SERUMALT_VST3_AUTO_MANIFEST TRUE)
if(CMAKE_CROSSCOMPILING)
set(SERUMALT_VST3_AUTO_MANIFEST FALSE)
endif()
juce_add_plugin(SerumAlt
VERSION 1.0.0
COMPANY_NAME "SerumAlt Audio"
IS_SYNTH TRUE
NEEDS_MIDI_INPUT TRUE
NEEDS_MIDI_OUTPUT FALSE
IS_MIDI_EFFECT FALSE
EDITOR_WANTS_KEYBOARD_FOCUS FALSE
PLUGIN_MANUFACTURER_CODE Salt
PLUGIN_CODE Sera
BUNDLE_ID com.serumalt.SerumAlt
FORMATS VST3 AU Standalone
PRODUCT_NAME "SerumAlt"
VST3_AUTO_MANIFEST ${SERUMALT_VST3_AUTO_MANIFEST})
juce_generate_juce_header(SerumAlt)
set(SERUMALT_SOURCES set(SERUMALT_SOURCES
Source/PluginProcessor.cpp Source/PluginProcessor.cpp
@@ -86,46 +63,33 @@ set(SERUMALT_SOURCES
Source/GUI/Panel.cpp Source/GUI/Panel.cpp
Source/Presets/FactoryPresets.cpp) Source/Presets/FactoryPresets.cpp)
target_sources(SerumAlt PRIVATE ${SERUMALT_SOURCES}) function(serumalt_configure_target target)
juce_generate_juce_header(${target})
target_compile_definitions(SerumAlt target_sources(${target} PRIVATE ${SERUMALT_SOURCES})
PUBLIC target_compile_definitions(${target}
JUCE_WEB_BROWSER=0
JUCE_USE_CURL=0
JUCE_VST3_CAN_REPLACE_VST2=0)
target_link_libraries(SerumAlt
PRIVATE
juce::juce_audio_utils
juce::juce_dsp
PUBLIC
juce::juce_recommended_config_flags
juce::juce_recommended_warning_flags)
# ---------------------------------------------------------------------------
# Headless QA harness (console app that drives the processor and checks output)
# ---------------------------------------------------------------------------
option(SERUMALT_BUILD_TESTS "Build the headless QA harness" ON)
if(SERUMALT_BUILD_TESTS)
juce_add_console_app(SerumAltTest)
juce_generate_juce_header(SerumAltTest)
target_sources(SerumAltTest PRIVATE ${SERUMALT_SOURCES} Source/Tests/TestMain.cpp)
target_compile_definitions(SerumAltTest
PUBLIC PUBLIC
JUCE_WEB_BROWSER=0 JUCE_WEB_BROWSER=0
JUCE_USE_CURL=0) JUCE_USE_CURL=0
target_link_libraries(SerumAltTest JUCE_VST3_CAN_REPLACE_VST2=0)
target_link_libraries(${target}
PRIVATE PRIVATE
juce::juce_audio_utils juce::juce_audio_utils
juce::juce_dsp juce::juce_dsp
PUBLIC PUBLIC
juce::juce_recommended_config_flags juce::juce_recommended_config_flags
juce::juce_recommended_warning_flags) juce::juce_recommended_warning_flags)
if(MSVC)
target_compile_options(${target} PRIVATE /W4)
else()
target_compile_options(${target} PRIVATE -Wall -Wextra)
endif()
endfunction()
if(SERUMALT_BUILD_PLUGIN)
include(cmake/Plugin.cmake)
endif() endif()
if(MSVC) if(SERUMALT_BUILD_TESTS)
target_compile_options(SerumAlt PRIVATE /W4) enable_testing()
else() include(cmake/Harness.cmake)
target_compile_options(SerumAlt PRIVATE -Wall -Wextra)
endif() endif()
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
BUILD_DIR="${BUILD_DIR:-$SCRIPT_DIR/build_harness}"
BUILD_TYPE="${BUILD_TYPE:-Release}"
export CMAKE_BUILD_PARALLEL_LEVEL="${CMAKE_BUILD_PARALLEL_LEVEL:-2}"
if [[ $# -gt 1 || ( $# -eq 1 && "$1" != --run ) ]]; then
echo "Usage: $0 [--run]" >&2
exit 1
fi
TOOLS=(cmake ninja "${CC:-cc}" "${CXX:-c++}")
case "$(uname -s)" in
Linux) TOOLS+=(pkg-config) ;;
Darwin) TOOLS+=(xcrun) ;;
*) echo "ERROR: build_harness.sh requires a native Linux or macOS host." >&2; exit 1 ;;
esac
if [[ $# -eq 1 ]]; then
TOOLS+=(ctest)
fi
for tool in "${TOOLS[@]}"; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "ERROR: $tool not found. See README.md prerequisites." >&2
exit 1
fi
done
if [[ "$(uname -s)" == Darwin ]]; then
xcrun --sdk macosx --show-sdk-path
fi
echo "Configuring the native QA harness only in $BUILD_DIR ($BUILD_TYPE)..."
cmake -S "$SCRIPT_DIR" -B "$BUILD_DIR" -G Ninja \
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
-DSERUMALT_BUILD_PLUGIN=OFF \
-DSERUMALT_BUILD_TESTS=ON
echo "Building SerumAltTest..."
cmake --build "$BUILD_DIR" --config "$BUILD_TYPE" --target SerumAltTest
if [[ $# -eq 1 ]]; then
echo "Running the QA harness with CTest..."
ctest --test-dir "$BUILD_DIR" --build-config "$BUILD_TYPE" --output-on-failure --no-tests=error
fi
echo "Done. QA harness: $BUILD_DIR/SerumAltTest_artefacts/$BUILD_TYPE/SerumAltTest"
Executable
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
BUILD_DIR="${BUILD_DIR:-$SCRIPT_DIR/build_linux}"
BUILD_TYPE="${BUILD_TYPE:-Release}"
export CMAKE_BUILD_PARALLEL_LEVEL="${CMAKE_BUILD_PARALLEL_LEVEL:-2}"
if [[ "$(uname -s)" != Linux ]]; then
echo "ERROR: build_linux.sh requires a Linux host." >&2
exit 1
fi
for tool in cmake ninja pkg-config "${CC:-cc}" "${CXX:-c++}"; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "ERROR: $tool not found. See README.md prerequisites." >&2
exit 1
fi
done
echo "Configuring Linux production targets in $BUILD_DIR ($BUILD_TYPE)..."
cmake -S "$SCRIPT_DIR" -B "$BUILD_DIR" -G Ninja \
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
-DSERUMALT_BUILD_PLUGIN=ON \
-DSERUMALT_BUILD_TESTS=OFF
echo "Building Linux VST3 and standalone..."
cmake --build "$BUILD_DIR" --config "$BUILD_TYPE" --target SerumAlt_VST3 SerumAlt_Standalone
echo "Done. Linux artifacts: $BUILD_DIR/SerumAlt_artefacts/$BUILD_TYPE"
Executable
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
BUILD_DIR="${BUILD_DIR:-$SCRIPT_DIR/build_macos}"
BUILD_TYPE="${BUILD_TYPE:-Release}"
export CMAKE_BUILD_PARALLEL_LEVEL="${CMAKE_BUILD_PARALLEL_LEVEL:-2}"
if [[ "$(uname -s)" != Darwin ]]; then
echo "ERROR: build_macos.sh requires macOS and the Apple SDK." >&2
exit 1
fi
for tool in cmake ninja xcrun "${CC:-clang}" "${CXX:-clang++}"; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "ERROR: $tool not found. See README.md prerequisites." >&2
exit 1
fi
done
xcrun --sdk macosx --show-sdk-path
OSX_OPTIONS=("-DCMAKE_BUILD_TYPE=$BUILD_TYPE")
if [[ -n "${CMAKE_OSX_ARCHITECTURES:-}" ]]; then
OSX_OPTIONS+=("-DCMAKE_OSX_ARCHITECTURES=$CMAKE_OSX_ARCHITECTURES")
fi
if [[ -n "${CMAKE_OSX_DEPLOYMENT_TARGET:-}" ]]; then
OSX_OPTIONS+=("-DCMAKE_OSX_DEPLOYMENT_TARGET=$CMAKE_OSX_DEPLOYMENT_TARGET")
fi
echo "Configuring macOS production targets in $BUILD_DIR ($BUILD_TYPE)..."
cmake -S "$SCRIPT_DIR" -B "$BUILD_DIR" -G Ninja \
"${OSX_OPTIONS[@]}" \
-DSERUMALT_BUILD_PLUGIN=ON \
-DSERUMALT_BUILD_TESTS=OFF
echo "Building macOS VST3, AU, and standalone..."
cmake --build "$BUILD_DIR" --config "$BUILD_TYPE" --target SerumAlt_VST3 SerumAlt_AU SerumAlt_Standalone
echo "Done. macOS artifacts: $BUILD_DIR/SerumAlt_artefacts/$BUILD_TYPE"
+50 -54
View File
@@ -7,60 +7,60 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR" cd "$SCRIPT_DIR"
TOOLCHAIN_FILE="mingw64-toolchain.cmake" TOOLCHAIN_FILE="$SCRIPT_DIR/mingw64-toolchain.cmake"
BUILD_DIR="build_windows" BUILD_DIR="${BUILD_DIR:-$SCRIPT_DIR/build_windows}"
OUTPUT_DIR="SerumAlt_Windows" BUILD_TYPE="${BUILD_TYPE:-Release}"
OUTPUT_DIR="${OUTPUT_DIR:-$SCRIPT_DIR/SerumAlt_Windows}"
PLUGIN_NAME="SerumAlt" PLUGIN_NAME="SerumAlt"
export CMAKE_BUILD_PARALLEL_LEVEL="${CMAKE_BUILD_PARALLEL_LEVEL:-2}"
# 1. Check for the MinGW-w64 cross-compiler and exit if it is not found. if [[ "$(uname -s)" != Linux ]]; then
if ! command -v x86_64-w64-mingw32-g++ >/dev/null 2>&1; then echo "ERROR: build_windows.sh cross-compiles from Linux using MinGW-w64." >&2
echo "ERROR: x86_64-w64-mingw32-g++ not found." >&2
echo "Please install the MinGW-w64 cross-compiler first, e.g.:" >&2
echo " sudo pacman -S mingw-w64-gcc" >&2
exit 1 exit 1
fi fi
# 1. Check for the host tools and MinGW-w64 cross-compiler.
for tool in cmake ninja pkg-config "${CC:-cc}" "${CXX:-c++}" \
x86_64-w64-mingw32-gcc x86_64-w64-mingw32-g++ \
x86_64-w64-mingw32-windres x86_64-w64-mingw32-ar \
x86_64-w64-mingw32-ranlib x86_64-w64-mingw32-strip; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "ERROR: $tool not found. See README.md prerequisites." >&2
exit 1
fi
done
echo "Found: $(command -v x86_64-w64-mingw32-g++)" echo "Found: $(command -v x86_64-w64-mingw32-g++)"
# 2. Generate the CMake toolchain file. # 2. Use the checked-in CMake toolchain file without overwriting it.
cat > "$TOOLCHAIN_FILE" <<'EOF' if [[ ! -f "$TOOLCHAIN_FILE" ]]; then
set(CMAKE_SYSTEM_NAME Windows) echo "ERROR: Toolchain file not found: $TOOLCHAIN_FILE" >&2
set(CMAKE_SYSTEM_PROCESSOR x86_64) exit 1
fi
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) echo "Using toolchain file: $TOOLCHAIN_FILE"
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
set(CMAKE_AR x86_64-w64-mingw32-ar)
set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib)
set(CMAKE_STRIP x86_64-w64-mingw32-strip)
set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOF
echo "Wrote toolchain file: $TOOLCHAIN_FILE"
# 3. Configure with CMake + Ninja (VST3-only cross build, no test harness). # 3. Configure with CMake + Ninja (VST3-only cross build, no test harness).
cmake -S . -B "$BUILD_DIR" -G Ninja \ echo "Configuring Windows VST3 in $BUILD_DIR ($BUILD_TYPE)..."
-DCMAKE_BUILD_TYPE=Release \ cmake -S "$SCRIPT_DIR" -B "$BUILD_DIR" -G Ninja \
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
-DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" \ -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" \
-DSERUMALT_BUILD_PLUGIN=ON \
-DSERUMALT_BUILD_TESTS=OFF -DSERUMALT_BUILD_TESTS=OFF
# 4. Build the VST3 target. # 4. Build the VST3 target.
cmake --build "$BUILD_DIR" --target SerumAlt_VST3 echo "Building Windows VST3..."
cmake --build "$BUILD_DIR" --config "$BUILD_TYPE" --target SerumAlt_VST3
# 5. Inject the VST3 moduleinfo.json. # 5. Inject the VST3 moduleinfo.json.
# The automatic manifest step is disabled when cross-compiling (see # The automatic manifest step is disabled when cross-compiling (see
# CMakeLists.txt), because JUCE's manifest helper is a host tool that would # cmake/Plugin.cmake), because JUCE's manifest helper is a host tool that would
# otherwise be built as a Windows executable. The moduleinfo content is # otherwise be built as a Windows executable. The moduleinfo content is
# deterministic and platform-independent: it depends only on the plugin's # deterministic for this Windows plugin: it depends on the plugin's
# name, manufacturer/plugin codes, and version, so we write the identical # name, manufacturer/plugin codes, and version, so we write the same metadata
# file that the native helper generates. Keep it in sync with the metadata # that the native Windows helper generates. Keep it in sync with the metadata
# in CMakeLists.txt (PLUGIN_CODE, PLUGIN_MANUFACTURER_CODE, VERSION). # in CMakeLists.txt and cmake/Plugin.cmake, including the vendored VST3 SDK version.
VST3_BUNDLE="$BUILD_DIR/${PLUGIN_NAME}_artefacts/Release/VST3/$PLUGIN_NAME.vst3" VST3_BUNDLE="$BUILD_DIR/${PLUGIN_NAME}_artefacts/$BUILD_TYPE/VST3/$PLUGIN_NAME.vst3"
echo "Writing Windows VST3 manifest..."
mkdir -p "$VST3_BUNDLE/Contents/Resources" mkdir -p "$VST3_BUNDLE/Contents/Resources"
cat > "$VST3_BUNDLE/Contents/Resources/moduleinfo.json" <<'EOF' cat > "$VST3_BUNDLE/Contents/Resources/moduleinfo.json" <<'EOF'
{ {
@@ -73,8 +73,8 @@ cat > "$VST3_BUNDLE/Contents/Resources/moduleinfo.json" <<'EOF'
"Flags": { "Flags": {
"Unicode": true, "Unicode": true,
"Classes Discardable": false, "Classes Discardable": false,
"Component Non Discardable": false, "Component Non Discardable": false
}, }
}, },
"Classes": [ "Classes": [
{ {
@@ -86,12 +86,11 @@ cat > "$VST3_BUNDLE/Contents/Resources/moduleinfo.json" <<'EOF'
"SDKVersion": "VST 3.7.8", "SDKVersion": "VST 3.7.8",
"Sub Categories": [ "Sub Categories": [
"Instrument", "Instrument",
"Synth", "Synth"
], ],
"Class Flags": 2, "Class Flags": 2,
"Cardinality": 2147483647, "Cardinality": 2147483647,
"Snapshots": [ "Snapshots": []
],
}, },
{ {
"CID": "ABCDEF011234ABCD53616C7453657261", "CID": "ABCDEF011234ABCD53616C7453657261",
@@ -102,12 +101,11 @@ cat > "$VST3_BUNDLE/Contents/Resources/moduleinfo.json" <<'EOF'
"SDKVersion": "VST 3.7.8", "SDKVersion": "VST 3.7.8",
"Sub Categories": [ "Sub Categories": [
"Instrument", "Instrument",
"Synth", "Synth"
], ],
"Class Flags": 2, "Class Flags": 2,
"Cardinality": 2147483647, "Cardinality": 2147483647,
"Snapshots": [ "Snapshots": []
],
}, },
{ {
"CID": "ABCDEF01C0DEF00D53616C7453657261", "CID": "ABCDEF01C0DEF00D53616C7453657261",
@@ -118,17 +116,15 @@ cat > "$VST3_BUNDLE/Contents/Resources/moduleinfo.json" <<'EOF'
"SDKVersion": "VST 3.7.8", "SDKVersion": "VST 3.7.8",
"Class Flags": 0, "Class Flags": 0,
"Cardinality": 2147483647, "Cardinality": 2147483647,
"Snapshots": [ "Snapshots": []
], }
}, ]
],
} }
EOF EOF
# 6. Copy the resulting .vst3 bundle to SerumAlt_Windows/. # 6. Copy the resulting .vst3 bundle to SerumAlt_Windows/ without deleting files.
mkdir -p "$OUTPUT_DIR" echo "Staging Windows VST3 in $OUTPUT_DIR..."
rm -rf "$OUTPUT_DIR/$PLUGIN_NAME.vst3" cmake -E copy_directory "$VST3_BUNDLE" "$OUTPUT_DIR/$PLUGIN_NAME.vst3"
cp -R "$BUILD_DIR/${PLUGIN_NAME}_artefacts/Release/VST3/$PLUGIN_NAME.vst3" "$OUTPUT_DIR/"
echo echo
echo "Done. Windows VST3 plugin at: $SCRIPT_DIR/$OUTPUT_DIR/$PLUGIN_NAME.vst3" echo "Done. Windows VST3 plugin at: $OUTPUT_DIR/$PLUGIN_NAME.vst3"
+7
View File
@@ -0,0 +1,7 @@
# ---------------------------------------------------------------------------
# Headless QA harness (console app that drives the processor and checks output)
# ---------------------------------------------------------------------------
juce_add_console_app(SerumAltTest)
serumalt_configure_target(SerumAltTest)
target_sources(SerumAltTest PRIVATE Source/Tests/TestMain.cpp)
add_test(NAME SerumAltTest COMMAND SerumAltTest)
+52
View File
@@ -0,0 +1,52 @@
# ---------------------------------------------------------------------------
# Plugin target
# ---------------------------------------------------------------------------
# JUCE 7.0.12 builds its VST3 manifest helper (juce_vst3_helper) with the same
# toolchain as the plugin itself. When cross-compiling, that produces a Windows
# .exe which cannot run on the Linux build host, so we disable the automatic
# manifest step and inject a Windows moduleinfo.json afterwards
# (see build_windows.sh). Native builds keep the automatic step.
set(SERUMALT_VST3_AUTO_MANIFEST TRUE)
if(CMAKE_CROSSCOMPILING)
set(SERUMALT_VST3_AUTO_MANIFEST FALSE)
endif()
set(SERUMALT_FORMATS VST3)
if(NOT WIN32)
list(APPEND SERUMALT_FORMATS Standalone)
endif()
if(APPLE)
list(APPEND SERUMALT_FORMATS AU)
endif()
juce_add_plugin(SerumAlt
VERSION ${PROJECT_VERSION}
COMPANY_NAME "SerumAlt Audio"
IS_SYNTH TRUE
NEEDS_MIDI_INPUT TRUE
NEEDS_MIDI_OUTPUT FALSE
IS_MIDI_EFFECT FALSE
EDITOR_WANTS_KEYBOARD_FOCUS FALSE
PLUGIN_MANUFACTURER_CODE Salt
PLUGIN_CODE Sera
BUNDLE_ID com.serumalt.SerumAlt
FORMATS ${SERUMALT_FORMATS}
PRODUCT_NAME "SerumAlt"
VST3_AUTO_MANIFEST ${SERUMALT_VST3_AUTO_MANIFEST})
serumalt_configure_target(SerumAlt)
# ---------------------------------------------------------------------------
# MinGW cross-build: static C++/threading runtime
# ---------------------------------------------------------------------------
# When cross-compiling for Windows with MinGW, link libgcc / libstdc++ /
# winpthread statically so the VST3 DLL is self-contained. Otherwise the DLL
# imports libgcc_s_seh-1.dll, libstdc++-6.dll and libwinpthread-1.dll, none of
# which ship with the bundle (or exist on a stock Windows host), so the host's
# scan would fail to load the plugin. Native (Linux) builds are unaffected.
if(MINGW)
target_link_options(SerumAlt_VST3 PRIVATE
-static-libgcc
-static-libstdc++
-static)
endif()