From 2c712efda50c638fdb7c265f4296d4f7d0b60a2c Mon Sep 17 00:00:00 2001 From: Sudara Date: Wed, 4 Dec 2024 12:41:13 +0100 Subject: [PATCH 01/12] Guard standalone logic with pluginval_IS_TOP_LEVEL --- CMakeLists.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f3f76a..daaf7c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,12 +3,18 @@ cmake_minimum_required(VERSION 3.15) file(STRINGS VERSION CURRENT_VERSION LIMIT_COUNT 1) project(pluginval VERSION ${CURRENT_VERSION}) -if (APPLE) - # Target OS versions down to 10.11 - set (CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE INTERNAL "") +# Executes when not compiling as a "dependency" of another CMake project +if (pluginval_IS_TOP_LEVEL) + add_subdirectory(modules/juce) + + if (APPLE) + # Target OS versions down to 10.11 + set (CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE INTERNAL "") + + # Uncomment to produce a universal binary + # set(CMAKE_OSX_ARCHITECTURES arm64 x86_64) + endif() - # Uncomment to produce a universal binary - # set(CMAKE_OSX_ARCHITECTURES arm64 x86_64) endif() # sanitizer options, from https://github.com/sudara/cmake-includes/blob/main/Sanitizers.cmake @@ -41,12 +47,6 @@ endif () set_property(GLOBAL PROPERTY USE_FOLDERS YES) option(JUCE_ENABLE_MODULE_SOURCE_GROUPS "Enable Module Source Groups" ON) -option(PLUGINVAL_FETCH_JUCE "Fetch JUCE along with PluginVal" ON) - -if(PLUGINVAL_FETCH_JUCE) - add_subdirectory(modules/juce) -endif() - if (DEFINED ENV{VST2_SDK_DIR}) MESSAGE(STATUS "Building with VST2 SDK: $ENV{VST2_SDK_DIR}") juce_set_vst2_sdk_path($ENV{VST2_SDK_DIR}) From 7c61a4a106acdbbb8ac52612dda1084932091da5 Mon Sep 17 00:00:00 2001 From: Sudara Date: Wed, 4 Dec 2024 16:47:50 +0100 Subject: [PATCH 02/12] Add a custom target when not top level --- CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index daaf7c0..b957659 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,23 @@ if (pluginval_IS_TOP_LEVEL) # set(CMAKE_OSX_ARCHITECTURES arm64 x86_64) endif() +else() + option(PLUGINVAL_STRICTNESS_LEVEL "Pluginval --strictness argument" 10) + + if(APPLE) + set(PLUGIN_TARGET "${CMAKE_PROJECT_NAME}_AU") + else() + set(PLUGIN_TARGET "${CMAKE_PROJECT_NAME}_VST3") + endif() + + add_custom_target(${CMAKE_PROJECT_NAME}_Pluginval + COMMAND + pluginval + --validate ${artefact} + --strictness-level ${PLUGINVAL_STRICTNESS_LEVEL} + DEPENDS ${PLUGIN_TARGET} pluginval + VERBATIM) + endif() # sanitizer options, from https://github.com/sudara/cmake-includes/blob/main/Sanitizers.cmake From b7d663c89ee70664131e5e4239d2955a0f941e1c Mon Sep 17 00:00:00 2001 From: Sudara Date: Wed, 4 Dec 2024 18:08:05 +0100 Subject: [PATCH 03/12] Add CLI option when dependency. Only compile docs when top-level. --- CMakeLists.txt | 58 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b957659..c8d10f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15) file(STRINGS VERSION CURRENT_VERSION LIMIT_COUNT 1) project(pluginval VERSION ${CURRENT_VERSION}) -# Executes when not compiling as a "dependency" of another CMake project +# Just compliing pluginval if (pluginval_IS_TOP_LEVEL) add_subdirectory(modules/juce) @@ -16,22 +16,10 @@ if (pluginval_IS_TOP_LEVEL) endif() else() - option(PLUGINVAL_STRICTNESS_LEVEL "Pluginval --strictness argument" 10) - - if(APPLE) - set(PLUGIN_TARGET "${CMAKE_PROJECT_NAME}_AU") - else() - set(PLUGIN_TARGET "${CMAKE_PROJECT_NAME}_VST3") - endif() - - add_custom_target(${CMAKE_PROJECT_NAME}_Pluginval - COMMAND - pluginval - --validate ${artefact} - --strictness-level ${PLUGINVAL_STRICTNESS_LEVEL} - DEPENDS ${PLUGIN_TARGET} pluginval - VERBATIM) - + # compiling as a "dependency" of another JUCE CMake project + if (NOT COMMAND juce_add_module) + message(FATAL_ERROR "JUCE must be added to your project before pluginval!") + endif () endif() # sanitizer options, from https://github.com/sudara/cmake-includes/blob/main/Sanitizers.cmake @@ -139,11 +127,35 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") -static-libstdc++) endif() -set (cmdline_docs_out "${CMAKE_CURRENT_LIST_DIR}/docs/Command line options.md") +if (pluginval_IS_TOP_LEVEL) + set (cmdline_docs_out "${CMAKE_CURRENT_LIST_DIR}/docs/Command line options.md") + + add_custom_command (OUTPUT "${cmdline_docs_out}" + COMMAND pluginval --help > "${cmdline_docs_out}" + COMMENT "Regenerating Command line options.md..." + USES_TERMINAL) + add_custom_target (PluginvalDocs DEPENDS "${cmdline_docs_out}") +else() + + # Custom pluginval CLI target + set(PLUGINVAL_STRICTNESS_LEVEL 10 CACHE STRING "Pluginval --strictness argument (1-10)") + set_property(CACHE PLUGINVAL_STRICTNESS_LEVEL PROPERTY STRINGS 1 2 3 4 5 6 7 8 9 10) + + # Set the target based on the platform + # Makes the assumption both are being built + if(APPLE) + set(PLUGINVAL_TARGET "${CMAKE_PROJECT_NAME}_AU") + else() + set(PLUGINVAL_TARGET "${CMAKE_PROJECT_NAME}_VST3") + endif() -add_custom_command (OUTPUT "${cmdline_docs_out}" - COMMAND pluginval --help > "${cmdline_docs_out}" - COMMENT "Regenerating Command line options.md..." - USES_TERMINAL) + get_target_property(artefact ${PLUGINVAL_TARGET} JUCE_PLUGIN_ARTEFACT_FILE) -add_custom_target (PluginvalDocs DEPENDS "${cmdline_docs_out}") + # TODO: This doesn't populate the executable in clion + add_custom_target(${CMAKE_PROJECT_NAME}_pluginval_cli + COMMAND $ + --validate ${artefact} + --strictness-level 10 + DEPENDS pluginval ${PLUGINVAL_TARGET} + COMMENT "Run pluginval CLI with strict validation") +endif() From b16312d07b691b7275835fd0fe24cd54dc6a4092 Mon Sep 17 00:00:00 2001 From: Sudara Date: Wed, 4 Dec 2024 18:27:16 +0100 Subject: [PATCH 04/12] Remove custom CLI command attempt --- CMakeLists.txt | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8d10f2..4a3cc4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,27 +135,4 @@ if (pluginval_IS_TOP_LEVEL) COMMENT "Regenerating Command line options.md..." USES_TERMINAL) add_custom_target (PluginvalDocs DEPENDS "${cmdline_docs_out}") -else() - - # Custom pluginval CLI target - set(PLUGINVAL_STRICTNESS_LEVEL 10 CACHE STRING "Pluginval --strictness argument (1-10)") - set_property(CACHE PLUGINVAL_STRICTNESS_LEVEL PROPERTY STRINGS 1 2 3 4 5 6 7 8 9 10) - - # Set the target based on the platform - # Makes the assumption both are being built - if(APPLE) - set(PLUGINVAL_TARGET "${CMAKE_PROJECT_NAME}_AU") - else() - set(PLUGINVAL_TARGET "${CMAKE_PROJECT_NAME}_VST3") - endif() - - get_target_property(artefact ${PLUGINVAL_TARGET} JUCE_PLUGIN_ARTEFACT_FILE) - - # TODO: This doesn't populate the executable in clion - add_custom_target(${CMAKE_PROJECT_NAME}_pluginval_cli - COMMAND $ - --validate ${artefact} - --strictness-level 10 - DEPENDS pluginval ${PLUGINVAL_TARGET} - COMMENT "Run pluginval CLI with strict validation") endif() From 7817fd17151e3b4df094e08be3e251e980c64785 Mon Sep 17 00:00:00 2001 From: Sudara Date: Fri, 6 Dec 2024 23:36:19 +0100 Subject: [PATCH 05/12] Move JUCE depedency from git submodule to CPM --- .gitmodules | 4 ---- CMakeLists.txt | 3 ++- cmake/CPM.cmake | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) delete mode 100644 .gitmodules create mode 100644 cmake/CPM.cmake diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b03a59d..0000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "modules/juce"] - path = modules/juce - url = https://github.com/juce-framework/JUCE - branch = develop diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a3cc4b..7b7e48b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,8 @@ project(pluginval VERSION ${CURRENT_VERSION}) # Just compliing pluginval if (pluginval_IS_TOP_LEVEL) - add_subdirectory(modules/juce) + include(cmake/CPM.cmake) + CPMAddPackage("gh:juce-framework/juce#8.0.4") if (APPLE) # Target OS versions down to 10.11 diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake new file mode 100644 index 0000000..baf2d8c --- /dev/null +++ b/cmake/CPM.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors + +set(CPM_DOWNLOAD_VERSION 0.40.2) +set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d") + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} +) + +include(${CPM_DOWNLOAD_LOCATION}) From 5f7492bc306193c15295774a62e097489501dc35 Mon Sep 17 00:00:00 2001 From: Sudara Date: Fri, 6 Dec 2024 23:45:07 +0100 Subject: [PATCH 06/12] Actions have cached the module, lets not checkout the submodule --- .github/workflows/build.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index df74d55..e06283d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -48,8 +48,6 @@ jobs: apt install -y sudo cmake curl tree - uses: actions/checkout@v4 - with: - submodules: true - name: Setup Environment Variables shell: bash From f8a84a9c7e2972a0ac1c7da22d5cb21d77a6b071 Mon Sep 17 00:00:00 2001 From: Sudara Date: Fri, 6 Dec 2024 23:45:32 +0100 Subject: [PATCH 07/12] Remove modules/juce --- modules/juce | 1 - 1 file changed, 1 deletion(-) delete mode 160000 modules/juce diff --git a/modules/juce b/modules/juce deleted file mode 160000 index 5179f4e..0000000 --- a/modules/juce +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5179f4e720d8406ebd1b5401c86aea8da6cc83c9 From 8a330d47761a5a57c9e3bebf2eb66a126d390b93 Mon Sep 17 00:00:00 2001 From: Sudara Date: Fri, 6 Dec 2024 23:06:29 +0100 Subject: [PATCH 08/12] Add docs for installing as a dep --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 963df15..a8dd6ca 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,24 @@ cmake -B Builds/Debug -DCMAKE_BUILD_TYPE=Debug . # configure cmake --build Builds/Debug --config Debug # build ``` +### Including within an existing JUCE project + +Instead of running as a separate app, you can add pluginval as a CMake target to your existing plugin project. This not only makes for a convenient debugging workflow, it gives you better stack traces. + +For example, if you add pluginval as a git submodule like so: +``` +git submodule add -b develop git@github.com:Tracktion/pluginval.git modules/pluginval +``` + +or added with CPM like so: + +``` +CPMAddPackage("gh:tracktion/pluginval#develop") +``` + +Then all you need to do is call `add_subdirectory ("modules/pluginval")` in your `CMakeLists.txt`. This should be done **after** your call to `juce_add_plugin`. + + ### Third-party Installation ###### _Chocolatey (Windows):_ ```shell From c4c79bf6481972a848aa0a81339965141e5a6920 Mon Sep 17 00:00:00 2001 From: Sudara Date: Sat, 7 Dec 2024 00:07:17 +0100 Subject: [PATCH 09/12] Revert to 8.0.3 and clear ccache --- .github/workflows/build.yaml | 2 +- CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index e06283d..651b2fa 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -88,7 +88,7 @@ jobs: - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: - key: v2-${{ matrix.name }}-${{ env.BUILD_TYPE }} + key: v3-${{ matrix.name }}-${{ env.BUILD_TYPE }} - name: Configure shell: bash diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b7e48b..2cc7ad5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(pluginval VERSION ${CURRENT_VERSION}) # Just compliing pluginval if (pluginval_IS_TOP_LEVEL) include(cmake/CPM.cmake) - CPMAddPackage("gh:juce-framework/juce#8.0.4") + CPMAddPackage("gh:juce-framework/juce#8.0.3") if (APPLE) # Target OS versions down to 10.11 From db9523e29fe2ae3e2e13c671ee9f104b6ecb4cda Mon Sep 17 00:00:00 2001 From: Sudara Date: Sat, 7 Dec 2024 14:46:17 +0100 Subject: [PATCH 10/12] CI: JUCE is now built in _deps, break plugin cache --- .github/workflows/build.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 651b2fa..1f4bc3d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -61,7 +61,7 @@ jobs: # This needs to be absolute to make action/cache happy WORKING_DIR=$(pwd) - echo "PLUGIN_CACHE_PATH=$WORKING_DIR/modules/juce/Builds/examples/Plugins" >> $GITHUB_ENV + echo "PLUGIN_CACHE_PATH=$WORKING_DIR/_deps/juce-build/examples/Plugins" >> $GITHUB_ENV - name: Install dependencies (Linux) if: ${{ matrix.name == 'Linux' }} @@ -112,11 +112,10 @@ jobs: with: path: ${{ env.PLUGIN_CACHE_PATH }} # Increment the version in the key below to manually break plugin cache - key: v7-${{ runner.os }}-${{ env.JUCE_SHA1 }} + key: v8-${{ runner.os }}-${{ env.JUCE_SHA1 }} - name: Build JUCE example plugins if: steps.cache-plugins.outputs.cache-hit != 'true' - working-directory: modules/juce shell: bash run: | cmake -B Builds -DJUCE_BUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache . From 6385bcf6c5927a429497877d2b5d5b016522137b Mon Sep 17 00:00:00 2001 From: Sudara Date: Sun, 13 Jul 2025 18:48:12 +0200 Subject: [PATCH 11/12] Don't call getAllValueStrings for non discrete parameters --- Source/tests/BasicTests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/tests/BasicTests.cpp b/Source/tests/BasicTests.cpp index c9844c4..600250d 100644 --- a/Source/tests/BasicTests.cpp +++ b/Source/tests/BasicTests.cpp @@ -486,7 +486,8 @@ namespace ParameterHelpers const int numSteps = parameter.getNumSteps(); const bool isDiscrete = parameter.isDiscrete(); const bool isBoolean = parameter.isBoolean(); - const juce::StringArray allValueStrings = parameter.getAllValueStrings(); + const juce::StringArray allValueStrings = parameter.isDiscrete() ? parameter.getAllValueStrings() : juce::StringArray(); + const bool isOrientationInverted = parameter.isOrientationInverted(); const bool isAutomatable = parameter.isAutomatable(); From dc9e598d218815930752d5a272dccdd45aba37e0 Mon Sep 17 00:00:00 2001 From: Sudara Date: Mon, 1 Dec 2025 18:25:28 +0100 Subject: [PATCH 12/12] Support JUCE 8.0.11 (addDefaultFormats is removed) --- Source/CommandLine.cpp | 4 ++++ Source/MainComponent.cpp | 4 ++++ Source/PluginTests.cpp | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/Source/CommandLine.cpp b/Source/CommandLine.cpp index 8790922..2d0dfd1 100644 --- a/Source/CommandLine.cpp +++ b/Source/CommandLine.cpp @@ -239,7 +239,11 @@ namespace bool isPluginArgument (juce::String arg) { juce::AudioPluginFormatManager formatManager; + #if JUCE_VERSION >= 0x08000B + addDefaultFormatsToManager (formatManager); + #else formatManager.addDefaultFormats(); + #endif for (auto format : formatManager.getFormats()) if (format->fileMightContainThisPluginType (arg)) diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 8a52d2c..96e5f12 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -246,7 +246,11 @@ namespace MainComponent::MainComponent (Validator& v) : validator (v) { + #if JUCE_VERSION >= 0x08000B + addDefaultFormatsToManager (formatManager); + #else formatManager.addDefaultFormats(); + #endif const auto tabCol = getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId); addAndMakeVisible (tabbedComponent); diff --git a/Source/PluginTests.cpp b/Source/PluginTests.cpp index abee411..ebecd54 100644 --- a/Source/PluginTests.cpp +++ b/Source/PluginTests.cpp @@ -52,7 +52,11 @@ PluginTests::PluginTests (const juce::String& fileOrIdentifier, Options opts) { jassert (fileOrIdentifier.isNotEmpty()); jassert (juce::isPositiveAndNotGreaterThan (options.strictnessLevel, 10)); + #if JUCE_VERSION >= 0x08000B + addDefaultFormatsToManager (formatManager); + #else formatManager.addDefaultFormats(); + #endif } PluginTests::PluginTests (const juce::PluginDescription& desc, Options opts)