Browse Source

Add cmake integration for LV2 and VST2 old interface

Signed-off-by: falkTX <falktx@falktx.com>
v6.1.6-distrho
falkTX 2 years ago
parent
commit
cba864f7e2
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
4 changed files with 211 additions and 27 deletions
  1. +2
    -2
      extras/Build/CMake/JUCEModuleSupport.cmake
  2. +37
    -25
      extras/Build/CMake/JUCEUtils.cmake
  3. +145
    -0
      extras/Build/CMake/lv2_ttl_generator.c
  4. +27
    -0
      modules/juce_audio_plugin_client/juce_audio_plugin_client_LV2.cpp

+ 2
- 2
extras/Build/CMake/JUCEModuleSupport.cmake View File

@@ -234,7 +234,7 @@ endfunction()
# ==================================================================================================

function(_juce_get_all_plugin_kinds out)
set(${out} AU AUv3 AAX Standalone Unity VST VST3 PARENT_SCOPE)
set(${out} AU AUv3 AAX Standalone Unity VST VST3 LV2 PARENT_SCOPE)
endfunction()

function(_juce_get_platform_plugin_kinds out)
@@ -249,7 +249,7 @@ function(_juce_get_platform_plugin_kinds out)
endif()

if(NOT CMAKE_SYSTEM_NAME STREQUAL "iOS" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
list(APPEND result AAX Unity VST VST3)
list(APPEND result AAX Unity VST VST3 LV2)
endif()

set(${out} ${result} PARENT_SCOPE)


+ 37
- 25
extras/Build/CMake/JUCEUtils.cmake View File

@@ -75,6 +75,10 @@ define_property(TARGET PROPERTY JUCE_UNITY_COPY_DIR INHERITED
BRIEF_DOCS "Install location for Unity plugins"
FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled")

define_property(TARGET PROPERTY JUCE_LV2_COPY_DIR INHERITED
BRIEF_DOCS "Install location for LV2 plugins"
FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled")

define_property(TARGET PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD INHERITED
BRIEF_DOCS "Whether or not plugins should be copied after building"
FULL_DOCS "Whether or not plugins should be copied after building")
@@ -115,6 +119,7 @@ function(_juce_set_default_properties)
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{HOME}/.vst")
set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "$ENV{HOME}/.vst3")
set_property(GLOBAL PROPERTY JUCE_LV2_COPY_DIR "$ENV{HOME}/.lv2")
endif()
endfunction()

@@ -916,6 +921,7 @@ function(_juce_set_plugin_target_properties shared_code_target kind)
elseif(kind STREQUAL "VST")
set_target_properties(${target_name} PROPERTIES
BUNDLE_EXTENSION vst
PREFIX ""
BUNDLE TRUE
XCODE_ATTRIBUTE_WRAPPER_EXTENSION vst
XCODE_ATTRIBUTE_LIBRARY_STYLE Bundle
@@ -928,6 +934,30 @@ function(_juce_set_plugin_target_properties shared_code_target kind)
endif()

_juce_set_copy_properties(${shared_code_target} ${target_name} "${output_path}" JUCE_VST_COPY_DIR)
elseif(kind STREQUAL "LV2")
set(output_path "${products_folder}/${product_name}.lv2")

set_target_properties(${target_name} PROPERTIES
BUNDLE_EXTENSION lv2
PREFIX ""
BUNDLE TRUE
LIBRARY_OUTPUT_DIRECTORY "${output_path}"
XCODE_ATTRIBUTE_WRAPPER_EXTENSION lv2
XCODE_ATTRIBUTE_LIBRARY_STYLE Bundle
XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE NO)

if(NOT SKIP_LV2_TTL_GENERATOR)
# generate .ttl files
add_executable(${target_name}_lv2_ttl_generator ${JUCE_CMAKE_UTILS_DIR}/lv2_ttl_generator.c)
target_link_libraries(${target_name}_lv2_ttl_generator dl)
add_custom_command(TARGET ${target_name} POST_BUILD
COMMAND ${CROSSCOMPILING_EMULATOR} "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_lv2_ttl_generator" "./${product_name}${CMAKE_SHARED_LIBRARY_SUFFIX}"
DEPENDS ${target_name} ${target_name}_lv2_ttl_generator
WORKING_DIRECTORY "${output_path}"
VERBATIM)
endif()

_juce_set_copy_properties(${shared_code_target} ${target_name} "${output_path}" JUCE_LV2_COPY_DIR)
elseif(kind STREQUAL "AU")
set_target_properties(${target_name} PROPERTIES
BUNDLE_EXTENSION component
@@ -1025,6 +1055,8 @@ function(_juce_get_plugin_kind_name kind out_var)
set(${out_var} "VST" PARENT_SCOPE)
elseif(kind STREQUAL "VST3")
set(${out_var} "VST3" PARENT_SCOPE)
elseif(kind STREQUAL "LV2")
set(${out_var} "LV2" PARENT_SCOPE)
endif()
endfunction()

@@ -1181,6 +1213,7 @@ function(_juce_configure_plugin_targets target)
JucePlugin_VSTUniqueID=JucePlugin_PluginCode
JucePlugin_VSTCategory=$<TARGET_PROPERTY:${target},JUCE_VST2_CATEGORY>
JucePlugin_Vst3Category="${vst3_category_string}"
JucePlugin_LV2URI="$<TARGET_PROPERTY:${target},JUCE_LV2_URI>"
JucePlugin_AUMainType=$<TARGET_PROPERTY:${target},JUCE_AU_MAIN_TYPE_CODE>
JucePlugin_AUSubType=JucePlugin_PluginCode
JucePlugin_AUExportPrefix=$<TARGET_PROPERTY:${target},JUCE_AU_EXPORT_PREFIX>
@@ -1529,6 +1562,7 @@ function(_juce_initialise_target target)
VST_NUM_MIDI_INS
VST_NUM_MIDI_OUTS
VST2_CATEGORY
LV2_URI
AU_MAIN_TYPE
AU_EXPORT_PREFIX
AU_SANDBOX_SAFE
@@ -1538,6 +1572,7 @@ function(_juce_initialise_target target)

VST_COPY_DIR
VST3_COPY_DIR
LV2_COPY_DIR
AAX_COPY_DIR
AU_COPY_DIR
UNITY_COPY_DIR
@@ -1586,6 +1621,7 @@ function(_juce_initialise_target target)
COMPANY_COPYRIGHT
VST_COPY_DIR
VST3_COPY_DIR
LV2_COPY_DIR
AU_COPY_DIR
AAX_COPY_DIR
UNITY_COPY_DIR
@@ -1608,7 +1644,6 @@ function(_juce_initialise_target target)

target_include_directories(${target} PRIVATE
$<TARGET_PROPERTY:${target},JUCE_GENERATED_SOURCES_DIRECTORY>)
target_link_libraries(${target} PUBLIC $<$<TARGET_EXISTS:juce_vst2_sdk>:juce_vst2_sdk>)

get_target_property(is_pluginhost_au ${target} JUCE_PLUGINHOST_AU)

@@ -1761,15 +1796,11 @@ function(juce_add_pip header)
list(APPEND extra_formats AAX)
endif()

if(TARGET juce_vst2_sdk)
list(APPEND extra_formats VST)
endif()

# Standalone plugins might want to access the mic
list(APPEND extra_target_args MICROPHONE_PERMISSION_ENABLED TRUE)

juce_add_plugin(${JUCE_PIP_NAME}
FORMATS AU AUv3 VST3 Unity Standalone ${extra_formats}
FORMATS AU AUv3 VST VST3 Unity Standalone ${extra_formats}
${extra_target_args})
elseif(pip_kind STREQUAL "Component")
set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPComponent.cpp.in")
@@ -1887,25 +1918,6 @@ function(juce_set_aax_sdk_path path)
set_target_properties(juce_aax_sdk PROPERTIES INTERFACE_JUCE_AAX_DEFAULT_ICON "${path}/Utilities/PlugIn.ico")
endfunction()

function(juce_set_vst2_sdk_path path)
if(TARGET juce_vst2_sdk)
message(FATAL_ERROR "juce_set_vst2_sdk_path should only be called once")
endif()

_juce_make_absolute(path)

if(NOT EXISTS "${path}")
message(FATAL_ERROR "Could not find VST2 SDK at the specified path: ${path}")
endif()

add_library(juce_vst2_sdk INTERFACE IMPORTED GLOBAL)

# This is a bit of a hack, but we really need the VST2 paths to always follow the VST3 paths.
target_include_directories(juce_vst2_sdk INTERFACE
$<TARGET_PROPERTY:juce::juce_vst3_headers,INTERFACE_INCLUDE_DIRECTORIES>
"${path}")
endfunction()

function(juce_set_vst3_sdk_path path)
if(TARGET juce_vst3_sdk)
message(FATAL_ERROR "juce_set_vst3_sdk_path should only be called once")


+ 145
- 0
extras/Build/CMake/lv2_ttl_generator.c View File

@@ -0,0 +1,145 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#include <windows.h>
#define TTL_GENERATOR_WINDOWS
#else
#include <dlfcn.h>
#endif

#ifndef nullptr
#define nullptr (0)
#endif

typedef void (*TTL_Generator_Function)(const char* basename);

static int isPathSeparator(char c);
static char* makeNormalPath(const char* path);

// TODO support Unicode paths on the Windows platform

int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("usage: %s /path/to/plugin-DLL\n", argv[0]);
return 1;
}

const char* path = argv[1];

#ifdef TTL_GENERATOR_WINDOWS
const HMODULE handle = LoadLibraryA(path);
#else
void* const handle = dlopen(path, RTLD_LAZY);
#endif

if (! handle)
{
#ifdef TTL_GENERATOR_WINDOWS
printf("Failed to open plugin DLL\n");
#else
printf("Failed to open plugin DLL, error was:\n%s\n", dlerror());
#endif
return 2;
}

#ifdef TTL_GENERATOR_WINDOWS
# if defined(__GNUC__) && (__GNUC__ >= 9)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-function-type"
# endif
const TTL_Generator_Function ttlFn = (TTL_Generator_Function)GetProcAddress(handle, "lv2_generate_ttl");
# if defined(__GNUC__) && (__GNUC__ >= 9)
# pragma GCC diagnostic pop
# endif
#else
const TTL_Generator_Function ttlFn = (TTL_Generator_Function)dlsym(handle, "lv2_generate_ttl");
#endif

if (ttlFn != NULL)
{
// convert the paths to a normalized form, such that path separators are
// replaced with '/', and duplicate separators are removed
char* normalPath = makeNormalPath(path);

// get rid of any "./" prefixes
path = normalPath;
while (path[0] == '.' && path[1] == '/')
path += 2;

// extract the file name part
char* basename = strrchr(path, '/');
if (basename != NULL)
basename += 1;
else
basename = (char*)path;

// remove the file extension
char* dotPos = strrchr(basename, '.');
if (dotPos)
*dotPos = '\0';

printf("Generate ttl data for '%s', basename: '%s'\n", path, basename);

ttlFn(basename);

free(normalPath);
}
else
printf("Failed to find 'lv2_generate_ttl' function\n");

#ifdef TTL_GENERATOR_WINDOWS
FreeLibrary(handle);
#else
dlclose(handle);
#endif

return 0;
}

static int isPathSeparator(char c)
{
#ifdef TTL_GENERATOR_WINDOWS
return c == '/' || c == '\\';
#else
return c == '/';
#endif
}

static char* makeNormalPath(const char* path)
{
size_t i, j;
size_t len = strlen(path);
char* result = (char*)malloc(len + 1);
int isSep, wasSep = 0;
for (i = 0, j = 0; i < len; ++i)
{
isSep = isPathSeparator(path[i]);
if (!isSep)
result[j++] = path[i];
else if (!wasSep)
result[j++] = '/';
wasSep = isSep;
}
result[j] = '\0';
return result;
}

+ 27
- 0
modules/juce_audio_plugin_client/juce_audio_plugin_client_LV2.cpp View File

@@ -0,0 +1,27 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "LV2/juce_LV2_Wrapper.cpp"

Loading…
Cancel
Save