Skip to content

Commit a5d5b08

Browse files
authored
Merge pull request #141 from Tracktion/use-as-dependency
Pluginval as dependency
2 parents 82bab76 + 77252e2 commit a5d5b08

File tree

10 files changed

+185
-36
lines changed

10 files changed

+185
-36
lines changed

.github/workflows/build.yaml

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ jobs:
4848
apt install -y sudo cmake curl tree
4949
5050
- uses: actions/checkout@v4
51-
with:
52-
submodules: true
5351

5452
- name: Setup Environment Variables
5553
shell: bash
@@ -58,12 +56,11 @@ jobs:
5856
echo "VERSION=$VERSION" >> $GITHUB_ENV
5957
echo "APP_DIR=${{ env.BUILD_DIR }}/${{ env.BINARY_NAME }}_artefacts/${{ env.BUILD_TYPE }}" >> $GITHUB_ENV
6058
echo "ZIP_FILE_NAME=${{ env.BINARY_NAME }}_${{ matrix.name }}.zip" >> $GITHUB_ENV
61-
echo "JUCE_SHA1=$(git rev-parse HEAD:modules/juce)" >> $GITHUB_ENV
62-
echo "PLUGIN_BUILD_DIR=modules/juce/Builds" >> $GITHUB_ENV
63-
59+
6460
# This needs to be absolute to make action/cache happy
61+
# JUCE examples are built from within the CPM-fetched JUCE source directory
6562
WORKING_DIR=$(pwd)
66-
echo "PLUGIN_CACHE_PATH=$WORKING_DIR/modules/juce/Builds/examples/Plugins" >> $GITHUB_ENV
63+
echo "PLUGIN_CACHE_PATH=$WORKING_DIR/${{ env.BUILD_DIR }}/_deps/juce-src/Builds/examples/Plugins" >> $GITHUB_ENV
6764
6865
- name: Install dependencies (Linux)
6966
if: ${{ matrix.name == 'Linux' }}
@@ -91,7 +88,7 @@ jobs:
9188
- name: ccache
9289
uses: hendrikmuhs/ccache-action@v1.2
9390
with:
94-
key: v2-${{ matrix.name }}-${{ env.BUILD_TYPE }}
91+
key: v3-${{ matrix.name }}-${{ env.BUILD_TYPE }}
9592

9693
- name: Configure
9794
shell: bash
@@ -115,11 +112,11 @@ jobs:
115112
with:
116113
path: ${{ env.PLUGIN_CACHE_PATH }}
117114
# Increment the version in the key below to manually break plugin cache
118-
key: v7-${{ runner.os }}-${{ env.JUCE_SHA1 }}
115+
key: v9-${{ runner.os }}
119116

120117
- name: Build JUCE example plugins
121118
if: steps.cache-plugins.outputs.cache-hit != 'true'
122-
working-directory: modules/juce
119+
working-directory: ${{ env.BUILD_DIR }}/_deps/juce-src
123120
shell: bash
124121
run: |
125122
cmake -B Builds -DJUCE_BUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .
@@ -171,6 +168,33 @@ jobs:
171168
name: ${{ env.ZIP_FILE_NAME }}
172169
path: ${{ env.APP_DIR }}/${{ env.ZIP_FILE_NAME }}
173170

171+
# Test pluginval as a dependency in another JUCE project
172+
as_dependency:
173+
name: Pluginval as Dependency
174+
strategy:
175+
fail-fast: false
176+
matrix:
177+
os: [ubuntu-latest, macos-15, windows-latest]
178+
juce: ["8.0.3", "8.0.11"]
179+
runs-on: ${{ matrix.os }}
180+
steps:
181+
- uses: actions/checkout@v4
182+
183+
- name: Install dependencies (Linux)
184+
if: runner.os == 'Linux'
185+
run: |
186+
sudo apt-get update
187+
sudo apt-get install -y libasound2-dev libfreetype6-dev libx11-dev libxcomposite-dev libxcursor-dev libxinerama-dev libxrandr-dev mesa-common-dev libwebkit2gtk-4.1-dev ladspa-sdk
188+
189+
- name: Configure
190+
run: cmake -B build -S tests/pluginval_as_dependency -DJUCE_VERSION="${{ matrix.juce }}"
191+
192+
- name: Build
193+
run: cmake --build build --target pluginval --parallel 4
194+
195+
- name: Verify
196+
run: cmake --build build --target verify_pluginval
197+
174198
# Create release for tagged refs
175199
deploy:
176200
if: contains(github.ref, 'tags/v')

.gitmodules

Lines changed: 0 additions & 4 deletions
This file was deleted.

CMakeLists.txt

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@ cmake_minimum_required(VERSION 3.15)
33
file(STRINGS VERSION CURRENT_VERSION LIMIT_COUNT 1)
44
project(pluginval VERSION ${CURRENT_VERSION})
55

6-
if (APPLE)
7-
# Target OS versions down to 10.11
8-
set (CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE INTERNAL "")
9-
10-
# Uncomment to produce a universal binary
11-
# set(CMAKE_OSX_ARCHITECTURES arm64 x86_64)
12-
set(PLUGINVAL_ENABLE_RTCHECK ON)
13-
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
14-
# Disable rtcheck on Linux for now until further testing on real Linux systems has been done
15-
# set(PLUGINVAL_ENABLE_RTCHECK ON)
6+
# Just compliing pluginval
7+
if (pluginval_IS_TOP_LEVEL)
8+
if (APPLE)
9+
# Target OS versions down to 10.11
10+
set (CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE INTERNAL "")
11+
12+
# Uncomment to produce a universal binary
13+
# set(CMAKE_OSX_ARCHITECTURES arm64 x86_64)
14+
set(PLUGINVAL_ENABLE_RTCHECK ON)
15+
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
16+
# Disable rtcheck on Linux for now until further testing on real Linux systems has been done
17+
# set(PLUGINVAL_ENABLE_RTCHECK ON)
18+
endif()
19+
else()
20+
# compiling as a "dependency" of another JUCE CMake project
21+
if (NOT COMMAND juce_add_module)
22+
message(FATAL_ERROR "JUCE must be added to your project before pluginval!")
23+
endif ()
1624
endif()
1725

1826
# sanitizer options, from https://github.com/sudara/cmake-includes/blob/main/Sanitizers.cmake
@@ -52,11 +60,9 @@ if(PLUGINVAL_ENABLE_RTCHECK)
5260
CPMAddPackage("gh:Tracktion/rtcheck#main")
5361
endif()
5462

55-
56-
option(PLUGINVAL_FETCH_JUCE "Fetch JUCE along with pluginval" ON)
57-
58-
if(PLUGINVAL_FETCH_JUCE)
59-
add_subdirectory(modules/juce)
63+
# Only fetch JUCE when top-level (when used as dependency, JUCE is already available)
64+
if (pluginval_IS_TOP_LEVEL)
65+
CPMAddPackage("gh:juce-framework/juce#8.0.3")
6066
endif()
6167

6268
if (DEFINED ENV{VST2_SDK_DIR})
@@ -151,11 +157,34 @@ if (PLUGINVAL_ENABLE_RTCHECK)
151157
endif ()
152158
endif()
153159

154-
set (cmdline_docs_out "${CMAKE_CURRENT_LIST_DIR}/docs/Command line options.md")
155-
156-
add_custom_command (OUTPUT "${cmdline_docs_out}"
157-
COMMAND pluginval --help > "${cmdline_docs_out}"
158-
COMMENT "Regenerating Command line options.md..."
159-
USES_TERMINAL)
160+
if (pluginval_IS_TOP_LEVEL)
161+
set (cmdline_docs_out "${CMAKE_CURRENT_LIST_DIR}/docs/Command line options.md")
160162

161-
add_custom_target (PluginvalDocs DEPENDS "${cmdline_docs_out}")
163+
add_custom_command (OUTPUT "${cmdline_docs_out}"
164+
COMMAND pluginval --help > "${cmdline_docs_out}"
165+
COMMENT "Regenerating Command line options.md..."
166+
USES_TERMINAL)
167+
add_custom_target (PluginvalDocs DEPENDS "${cmdline_docs_out}")
168+
else()
169+
# Custom pluginval CLI target
170+
set(PLUGINVAL_STRICTNESS_LEVEL 10 CACHE STRING "Pluginval --strictness argument (1-10)")
171+
set_property(CACHE PLUGINVAL_STRICTNESS_LEVEL PROPERTY STRINGS 1 2 3 4 5 6 7 8 9 10)
172+
173+
# Set the target based on the platform
174+
# Makes the assumption both are being built
175+
if(APPLE)
176+
set(PLUGINVAL_TARGET "${CMAKE_PROJECT_NAME}_AU")
177+
else()
178+
set(PLUGINVAL_TARGET "${CMAKE_PROJECT_NAME}_VST3")
179+
endif()
180+
181+
get_target_property(artefact ${PLUGINVAL_TARGET} JUCE_PLUGIN_ARTEFACT_FILE)
182+
183+
# TODO: This doesn't populate the executable in clion
184+
add_custom_target(${CMAKE_PROJECT_NAME}_pluginval_cli
185+
COMMAND $<TARGET_FILE:pluginval>
186+
--validate ${artefact}
187+
--strictness-level 10
188+
DEPENDS pluginval ${PLUGINVAL_TARGET}
189+
COMMENT "Run pluginval CLI with strict validation")
190+
endif()

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@ cmake -B Builds/Debug -DCMAKE_BUILD_TYPE=Debug . # configure
3232
cmake --build Builds/Debug --config Debug # build
3333
```
3434

35+
### Including within an existing JUCE project
36+
37+
Instead of running as a separate app, you can add pluginval as a CMake target to your existing JUCE plugin project. This not only makes for a convenient debugging workflow, it gives you better stack traces.
38+
39+
For example, if you add pluginval as a git submodule like so:
40+
```
41+
git submodule add -b develop git@github.com:Tracktion/pluginval.git modules/pluginval
42+
```
43+
44+
or added with CPM like so:
45+
46+
```
47+
CPMAddPackage("gh:tracktion/pluginval#develop")
48+
```
49+
50+
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`.
51+
52+
Note that only JUCE 8 is currently supported/tested for this method.
53+
3554
### Third-party Installation
3655
###### _Chocolatey (Windows):_
3756
```shell

Source/CommandLine.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,11 @@ namespace
241241
bool isPluginArgument (juce::String arg)
242242
{
243243
juce::AudioPluginFormatManager formatManager;
244+
#if JUCE_VERSION >= 0x08000B
244245
juce::addDefaultFormatsToManager (formatManager);
246+
#else
247+
formatManager.addDefaultFormats();
248+
#endif
245249

246250
for (auto format : formatManager.getFormats())
247251
if (format->fileMightContainThisPluginType (arg))

Source/MainComponent.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,11 @@ namespace
331331
MainComponent::MainComponent (Validator& v)
332332
: validator (v)
333333
{
334+
#if JUCE_VERSION >= 0x08000B
334335
juce::addDefaultFormatsToManager (formatManager);
336+
#else
337+
formatManager.addDefaultFormats();
338+
#endif
335339

336340
menuBar.setModel (this);
337341
addAndMakeVisible (menuBar);

Source/PluginTests.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ PluginTests::PluginTests (const juce::String& fileOrIdentifier, Options opts)
6969
{
7070
jassert (fileOrIdentifier.isNotEmpty());
7171
jassert (juce::isPositiveAndNotGreaterThan (options.strictnessLevel, 10));
72+
#if JUCE_VERSION >= 0x08000B
7273
juce::addDefaultFormatsToManager (formatManager);
74+
#else
75+
formatManager.addDefaultFormats();
76+
#endif
7377
}
7478

7579
PluginTests::PluginTests (const juce::PluginDescription& desc, Options opts)

modules/juce

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
cmake_minimum_required(VERSION 3.22)
2+
project(PluginvalAsDependency VERSION 1.0.0)
3+
4+
set(JUCE_VERSION "8.0.3" CACHE STRING "JUCE version to test against")
5+
6+
include(${CMAKE_CURRENT_LIST_DIR}/../../cmake/CPM.cmake)
7+
8+
CPMAddPackage("gh:juce-framework/JUCE#${JUCE_VERSION}")
9+
10+
# Minimal plugin to test pluginval as a dependency
11+
# Plugin name must match CMAKE_PROJECT_NAME for pluginval's CLI target to work
12+
# Must be defined BEFORE adding pluginval
13+
juce_add_plugin(${CMAKE_PROJECT_NAME}
14+
PLUGIN_MANUFACTURER_CODE Test
15+
PLUGIN_CODE Test
16+
FORMATS VST3 AU
17+
PRODUCT_NAME "TestPlugin")
18+
19+
target_sources(${CMAKE_PROJECT_NAME} PRIVATE TestPlugin.cpp)
20+
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE juce::juce_audio_processors)
21+
22+
CPMAddPackage(
23+
NAME pluginval
24+
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..
25+
)
26+
27+
# Verify pluginval runs and reports the expected JUCE version
28+
add_custom_target(verify_pluginval
29+
COMMAND $<TARGET_FILE:pluginval> --help | grep "JUCE v${JUCE_VERSION}"
30+
DEPENDS pluginval
31+
COMMENT "Verify pluginval built with JUCE ${JUCE_VERSION}")
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Minimal JUCE plugin to test pluginval builds as a dependency
2+
#include <juce_audio_processors/juce_audio_processors.h>
3+
4+
class TestProcessor : public juce::AudioProcessor
5+
{
6+
public:
7+
TestProcessor()
8+
: AudioProcessor (BusesProperties()
9+
.withInput ("Input", juce::AudioChannelSet::stereo(), true)
10+
.withOutput ("Output", juce::AudioChannelSet::stereo(), true))
11+
{
12+
}
13+
14+
const juce::String getName() const override { return "TestPlugin"; }
15+
bool acceptsMidi() const override { return false; }
16+
bool producesMidi() const override { return false; }
17+
double getTailLengthSeconds() const override { return 0.0; }
18+
19+
int getNumPrograms() override { return 1; }
20+
int getCurrentProgram() override { return 0; }
21+
void setCurrentProgram (int) override {}
22+
const juce::String getProgramName (int) override { return {}; }
23+
void changeProgramName (int, const juce::String&) override {}
24+
25+
void prepareToPlay (double, int) override {}
26+
void releaseResources() override {}
27+
void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override {}
28+
29+
bool hasEditor() const override { return false; }
30+
juce::AudioProcessorEditor* createEditor() override { return nullptr; }
31+
32+
void getStateInformation (juce::MemoryBlock&) override {}
33+
void setStateInformation (const void*, int) override {}
34+
};
35+
36+
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
37+
{
38+
return new TestProcessor();
39+
}

0 commit comments

Comments
 (0)