Skip to content

Commit

Permalink
Changes to allow to work as subordinate cmake (#91)
Browse files Browse the repository at this point in the history
These changes allow the cmake functions to work at a not-top-level
and to supress the default targets so you can augment your targets
with wrapitude.

The changes mostly amount to

1. CACHE STRING vs PARENT_SCOPE. Some thing sjust need a lifetime
   beyond the parent scope when PARENT_SCOPE is not top level.
2. The functions called from anywhere mean we can't rely on
   the working directory being the current soruce, so cache
   current source and use it in a couple of key places.
3. Add an option to skip the build or activate it, with them
   on by default. I chose a "DONT ADD" rather than "ADD" flag
   here but might change it. This also pushes us to cmake 3.21 for
   PROJECT TOP LEVEL
4. Set visibilty flags for objective c as well as c++. Enable OBJC
   explicitly
5. Supress some warnings from the VST3 SDK we can't fix
6. Have the github actions show what was built
7. Make the '_selfcontained' style of linkage work on linux
8. Self-contained vst3 with in-library clap_entry works (as well
   as in-bundle plugin)
  • Loading branch information
baconpaul authored Sep 5, 2023
1 parent 8a4ffc4 commit c07ac2d
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 69 deletions.
14 changes: 13 additions & 1 deletion .github/workflows/pullreq.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ jobs:
cmake -S . -B ./build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DCLAP_SDK_ROOT=deps/clap -DVST3_SDK_ROOT=deps/vst3sdk -DCLAP_WRAPPER_OUTPUT_NAME=testplug
cmake --build ./build --config Debug
- name: Show Build Results
shell: bash
run: |
find build -name testplug.vst3 -print
find build -name testplug.component -print
build_feature_cpm_download:
Expand All @@ -60,6 +66,12 @@ jobs:

- name: Build project
run: |
cmake -S . -B ./build -DCMAKE_BUILD_TYPE=Debug -DCLAP_WRAPPER_DOWNLOAD_DEPENDENCIES=TRUE -DCLAP_WRAPPER_BUILD_AUV2=TRUE
cmake -S . -B ./build -DCMAKE_BUILD_TYPE=Debug -DCLAP_WRAPPER_DOWNLOAD_DEPENDENCIES=TRUE -DCLAP_WRAPPER_BUILD_AUV2=TRUE -DCLAP_WRAPPER_OUTPUT_NAME=downloadplug
cmake --build ./build --config Debug
- name: Show Build Results
shell: bash
run: |
find build -name downloadplug.vst3 -print
find build -name downloadplug.component -print
87 changes: 54 additions & 33 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
# CLAP_WRAPPER_BUNDLE_VERSION the macOS Bundle Version. Defaults to 1.0
# CLAP_WRAPPER_WINDOWS_SINGLE_FILE if set to TRUE (default) the windows .vst3 is a single file; false a 3.7 spec folder
# CLAP_WRAPPER_DOWNLOAD_DEPENDENCIES if set will download the needed SDKs using CPM from github
#
# CLAP_WRAPPER_DONT_ADD_TARGETS if included in a CMakeList above skip adding targets

cmake_minimum_required(VERSION 3.20)
cmake_minimum_required(VERSION 3.21)
cmake_policy(SET CMP0091 NEW)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.11 CACHE STRING "Minimum macOS version")
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build Universal Always")
Expand All @@ -39,48 +39,69 @@ project(clap-wrapper
DESCRIPTION "CLAP-as-X wrappers"
)

if (APPLE)
enable_language(OBJC)
enable_language(OBJCXX)
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_OBJC_VISIBILITY_PRESET hidden)
set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)

# discover the plugin paths and enable them
# discover the plugin paths and enable them. The library
# defines functions relative to this, so needs a cache
# variable with the source dir
set(CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE STRING "Clap Wrapper Source Location")
include(cmake/enable_sdks.cmake)

# provide the CLAP_WRAPPER_OUTPUT_NAME to specify the matching plugin name.
if((NOT CLAP_WRAPPER_OUTPUT_NAME ) OR (CLAP_WRAPPER_OUTPUT_NAME STREQUAL ""))
set(CLAP_WRAPPER_OUTPUT_NAME "clapasvst3")
message(WARNING "clap-wrapper: CLAP_WRAPPER_OUTPUT_NAME not set - continuing with a default name `clapasvst3`")
set(skipbuild FALSE)
if (NOT PROJECT_IS_TOP_LEVEL)
if(DEFINED CLAP_WRAPPER_DONT_ADD_TARGETS)
set(skipbuild TRUE)
endif()
endif()

string(MAKE_C_IDENTIFIER ${CLAP_WRAPPER_OUTPUT_NAME} pluginname)
if (${skipbuild})
message(STATUS "clap-wrapper: Skipping clap wrapper target ejection")
else()
# provide the CLAP_WRAPPER_OUTPUT_NAME to specify the matching plugin name.
if((NOT CLAP_WRAPPER_OUTPUT_NAME ) OR (CLAP_WRAPPER_OUTPUT_NAME STREQUAL ""))
set(CLAP_WRAPPER_OUTPUT_NAME "clapasvst3")
message(WARNING "clap-wrapper: CLAP_WRAPPER_OUTPUT_NAME not set - continuing with a default name `clapasvst3`")
endif()

string(MAKE_C_IDENTIFIER ${CLAP_WRAPPER_OUTPUT_NAME} pluginname)

# Link the actual plugin library
add_library(${pluginname}_as_vst3 MODULE)
target_add_vst3_wrapper(
TARGET ${pluginname}_as_vst3
OUTPUT_NAME "${CLAP_WRAPPER_OUTPUT_NAME}"
SUPPORTS_ALL_NOTE_EXPRESSIONS $<BOOL:${CLAP_SUPPORTS_ALL_NOTE_EXPRESSIONS}>
SINGLE_PLUGIN_TUID "${CLAP_VST3_TUID_STRING}"
BUNDLE_IDENTIFIER "${CLAP_WRAPPER_BUNDLE_IDENTIFIER}"
BUNDLE_VERSION "${CLAP_WRAPPER_BUNDLE_VERSION}"
)
# Link the actual plugin library
add_library(${pluginname}_as_vst3 MODULE)
target_add_vst3_wrapper(
TARGET ${pluginname}_as_vst3
OUTPUT_NAME "${CLAP_WRAPPER_OUTPUT_NAME}"
SUPPORTS_ALL_NOTE_EXPRESSIONS $<BOOL:${CLAP_SUPPORTS_ALL_NOTE_EXPRESSIONS}>
SINGLE_PLUGIN_TUID "${CLAP_VST3_TUID_STRING}"
BUNDLE_IDENTIFIER "${CLAP_WRAPPER_BUNDLE_IDENTIFIER}"
BUNDLE_VERSION "${CLAP_WRAPPER_BUNDLE_VERSION}"
)

if (APPLE)
if (${CLAP_WRAPPER_BUILD_AUV2})
add_library(${pluginname}_as_auv2 MODULE)
target_add_auv2_wrapper(
TARGET ${pluginname}_as_auv2
OUTPUT_NAME "${CLAP_WRAPPER_OUTPUT_NAME}"
BUNDLE_IDENTIFIER "${CLAP_WRAPPER_BUNDLE_IDENTIFIER}"
BUNDLE_VERSION "${CLAP_WRAPPER_BUNDLE_VERSION}"
if (APPLE)
if (${CLAP_WRAPPER_BUILD_AUV2})
add_library(${pluginname}_as_auv2 MODULE)
target_add_auv2_wrapper(
TARGET ${pluginname}_as_auv2
OUTPUT_NAME "${CLAP_WRAPPER_OUTPUT_NAME}"
BUNDLE_IDENTIFIER "${CLAP_WRAPPER_BUNDLE_IDENTIFIER}"
BUNDLE_VERSION "${CLAP_WRAPPER_BUNDLE_VERSION}"

# AUv2 is still a work in progress. For now make this an
# explict option to the single plugin version
INSTRUMENT_TYPE "aumu"
MANUFACTURER_NAME "cleveraudio.org"
MANUFACTURER_CODE "clAd"
SUBTYPE_CODE "gWrp"
)
# AUv2 is still a work in progress. For now make this an
# explict option to the single plugin version
INSTRUMENT_TYPE "aumu"
MANUFACTURER_NAME "cleveraudio.org"
MANUFACTURER_CODE "clAd"
SUBTYPE_CODE "gWrp"
)
endif()
endif()
endif()
95 changes: 62 additions & 33 deletions cmake/enable_sdks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#
# options
# set(CLAP_WRAPPER_OUTPUT_NAME "" CACHE STRING "The output name of the dynamically wrapped plugin")
set(CLAP_SDK_ROOT "" CACHE STRING "Path to CLAP SDK")
set(VST3_SDK_ROOT "" CACHE STRING "Path to VST3 SDK")

# make CPM available
include(cmake/CPM.cmake)
Expand All @@ -22,17 +20,21 @@ if (${CLAP_WRAPPER_DOWNLOAD_DEPENDENCIES})
DOWNLOAD_ONLY TRUE
SOURCE_DIR cpm/vst3sdk
)
set(VST3_SDK_ROOT "${CMAKE_BINARY_DIR}/cpm/vst3sdk")

CPMAddPackage(
NAME "clap"
GITHUB_REPOSITORY "free-audio/clap"
GIT_TAG "1.1.8"
EXCLUDE_FROM_ALL TRUE
DOWNLOAD_ONLY TRUE
SOURCE_DIR cpm/clap
)
set(CLAP_SDK_ROOT "${CMAKE_BINARY_DIR}/cpm/clap")
set(VST3_SDK_ROOT "${CMAKE_CURRENT_BINARY_DIR}/cpm/vst3sdk" CACHE STRING "Path to downloaded VST3SDK")
message(STATUS "clap-wrapper: configuring vst3sdk in ${VST3_SDK_ROOT}")

if(NOT TARGET clap-core)
CPMAddPackage(
NAME "clap"
GITHUB_REPOSITORY "free-audio/clap"
GIT_TAG "1.1.8"
EXCLUDE_FROM_ALL TRUE
DOWNLOAD_ONLY TRUE
SOURCE_DIR cpm/clap
)
set(CLAP_SDK_ROOT "${CMAKE_CURRENT_BINARY_DIR}/cpm/clap" CACHE STRING "Path to downloaded CLAP SDK")
message(STATUS "clap-wrapper: configuring clap in ${CLAP_SDK_ROOT}")
endif()

if (APPLE)
if (${CLAP_WRAPPER_BUILD_AUV2})
Expand All @@ -44,9 +46,14 @@ if (${CLAP_WRAPPER_DOWNLOAD_DEPENDENCIES})
DOWNLOAD_ONLY TRUE
SOURCE_DIR cpm/AudioUnitSDK
)
set(AUDIOUNIT_SDK_ROOT "${CMAKE_BINARY_DIR}/cpm/AudioUnitSDK")
set(AUDIOUNIT_SDK_ROOT "${CMAKE_CURRENT_BINARY_DIR}/cpm/AudioUnitSDK" CACHE STRING "Path to downloaded AUV2 SDK")
message(STATUS "clap-wrapper: configuring AudioUnitSDK in ${AUDIOUNIT_SDK_ROOT}")
endif()
endif()
else()
set(CLAP_SDK_ROOT "" CACHE STRING "Path to CLAP SDK")
set(VST3_SDK_ROOT "" CACHE STRING "Path to VST3 SDK")
set(AUDIOUNIT_SDK_ROOT "" CACHE STRING "Path to VST3 SDK")
endif()

function(LibrarySearchPath)
Expand All @@ -73,7 +80,7 @@ function(LibrarySearchPath)
endif()

if(RES STREQUAL "")
message(FATAL_ERROR "Unable to detect ${SEARCH_SDKDIR}! Have you set -D${SEARCH_RESULT}=/path/to/sdk?")
message(FATAL_ERROR "Unable to detect ${SEARCH_SDKDIR}! Have you set -D${SEARCH_RESULT}=/path/to/sdk or CLAP_WRAPPER_DOWNLOAD_DEPENDENCIES=TRUE")
endif()

cmake_path(CONVERT "${RES}" TO_CMAKE_PATH_LIST RES)
Expand Down Expand Up @@ -135,7 +142,7 @@ function(DefineCLAPASVST3Sources)
${VST3_SDK_ROOT}/public.sdk/source/vst/vstbus.cpp
${VST3_SDK_ROOT}/public.sdk/source/vst/vstparameters.cpp
${VST3_SDK_ROOT}/public.sdk/source/vst/utility/stringconvert.cpp
PARENT_SCOPE
CACHE STRING "VST3 SDK Source List"
)

if( UNIX AND NOT APPLE )
Expand Down Expand Up @@ -183,11 +190,11 @@ function(DefineCLAPASVST3Sources)
src/detail/os/osutil.h
src/detail/clap/automation.h
${os_wrappersources}
PARENT_SCOPE)
CACHE STRING "Clap Wrapper Library Sources")

set(wrappersources_vst3_entry
src/wrapasvst3_export_entry.cpp
PARENT_SCOPE)
${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/wrapasvst3_export_entry.cpp
CACHE STRING "Clap Wrapper Entry Point Sources")

endfunction(DefineCLAPASVST3Sources)

Expand Down Expand Up @@ -225,11 +232,11 @@ DefineCLAPASVST3Sources()
# define platforms

if (APPLE)
set(PLATFORM "MAC")
set(CLAP_WRAPPER_PLATFORM "MAC" CACHE STRING "Clap Wrapper Platform: MAC")
elseif(UNIX)
set(PLATFORM "LIN")
set(CLAP_WRAPPER_PLATFORM "LIN" CACHE STRING "Clap Wrapper Platform: Linux")
elseif(WIN32)
set(PLATFORM "WIN")
set(CLAP_WRAPPER_PLATFORM "WIN" CACHE STRING "Clap Wrapper Platform: Windows")
endif()


Expand Down Expand Up @@ -276,23 +283,40 @@ function(target_add_vst3_wrapper)
target_sources(${V3_TARGET} PRIVATE ${wrappersources_vst3_entry})

if (NOT TARGET vst3-pluginbase)
message(STATUS "clap-wrapper: creating vst3 library")
message(STATUS "clap-wrapper: creating vst3 library with root ${VST3_SDK_ROOT}")
add_library(vst3-pluginbase STATIC ${vst3sources})
target_include_directories(vst3-pluginbase PUBLIC ${VST3_SDK_ROOT} ${VST3_SDK_ROOT}/public.sdk ${VST3_SDK_ROOT}/pluginterfaces)
target_compile_options(vst3-pluginbase PUBLIC $<IF:$<CONFIG:Debug>,-DDEVELOPMENT=1,-DRELEASE=1>) # work through steinbergs alternate choices for these
# The VST3SDK uses sprintf, not snprintf, which macOS flags as deprecated
# to move people to snprintf. Silence that warning on the VST3 build
if (APPLE)
target_compile_options(vst3-pluginbase PUBLIC -Wno-deprecated-declarations)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
# The VST3 SDK confuses lld and long long int in format statements in some situations it seems
target_compile_options(vst3-pluginbase PUBLIC -Wno-format)

# The SDK also does things like `#warning DEPRECATED No Linux implementation
# assert (false && "DEPRECATED No Linux implementation");` for some methods which
# generates a cpp warning. Since we won't fix this do
target_compile_options(vst3-pluginbase PUBLIC -Wno-cpp)
endif()
endif()


# Define the VST3 plugin name and include the sources directly.
# We need to indivduate this target since it will be different
# for different options
if (NOT TARGET clap-wrapper-vst3-${V3_TARGET})
add_library(clap-wrapper-vst3-${V3_TARGET} STATIC ${wrappersources_vst3})
target_include_directories(clap-wrapper-vst3-${V3_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
set(wsv3 ${wrappersources_vst3})
list(TRANSFORM wsv3 PREPEND "${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/")

add_library(clap-wrapper-vst3-${V3_TARGET} STATIC ${wsv3})
target_include_directories(clap-wrapper-vst3-${V3_TARGET} PRIVATE "${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(clap-wrapper-vst3-${V3_TARGET} PUBLIC clap-core vst3-pluginbase)

# clap-wrapper-extensions are PUBLIC, so a clap linking the library can access the clap-wrapper-extensions
target_compile_definitions(clap-wrapper-vst3-${V3_TARGET} PUBLIC -D${PLATFORM}=1)
target_compile_definitions(clap-wrapper-vst3-${V3_TARGET} PUBLIC -D${CLAP_WRAPPER_PLATFORM}=1)
target_link_libraries(clap-wrapper-vst3-${V3_TARGET} PUBLIC clap-wrapper-extensions)

target_compile_options(clap-wrapper-vst3-${V3_TARGET} PRIVATE
Expand Down Expand Up @@ -328,16 +352,18 @@ function(target_add_vst3_wrapper)
set_target_properties(${V3_TARGET} PROPERTIES
BUNDLE True
BUNDLE_EXTENSION vst3
LIBRARY_OUTPUT_NAME ${V3_OUTPUT_NAME}
MACOSX_BUNDLE_GUI_IDENTIFIER ${V3_BUNDLE_IDENTIFIER}
MACOSX_BUNDLE_BUNDLE_NAME ${V3_OUTPUT_NAME}
MACOSX_BUNDLE_BUNDLE_VERSION ${V3_BUNDLE_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${V3_BUNDLE_VERSION}
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/VST3_Info.plist.in
MACOSX_BUNDLE_INFO_PLIST ${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/cmake/VST3_Info.plist.in
)
if (NOT ${CMAKE_GENERATOR} STREQUAL "Xcode")
add_custom_command(TARGET ${V3_TARGET} POST_BUILD
WORKING_DIRECTORY $<TARGET_PROPERTY:${V3_TARGET},LIBRARY_OUTPUT_DIRECTORY>
COMMAND SetFile -a B "$<TARGET_PROPERTY:${V3_TARGET},MACOSX_BUNDLE_BUNDLE_NAME>.$<TARGET_PROPERTY:${V3_TARGET},BUNDLE_EXTENSION>")
COMMAND SetFile -a B "$<TARGET_PROPERTY:${V3_TARGET},LIBRARY_OUTPUT_NAME>.$<TARGET_PROPERTY:${V3_TARGET},BUNDLE_EXTENSION>"
)
endif()

if (NOT ${V3_MACOS_EMBEDDED_CLAP_LOCATION} STREQUAL "")
Expand All @@ -357,29 +383,31 @@ function(target_add_vst3_wrapper)
COMMAND ${CMAKE_COMMAND} -E make_directory "$<IF:$<CONFIG:Debug>,Debug,Release>/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-linux"
)
set_target_properties(${V3_TARGET} PROPERTIES
LIBRARY_OUTPUT_NAME ${V3_OUTPUT_NAME}
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<IF:$<CONFIG:Debug>,Debug,Release>/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-linux"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/Debug/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-linux"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-linux"
SUFFIX ".so" PREFIX "")
else()
if (NOT ${V3_WINDOWS_FOLDER_VST3})
message(STATUS "clap-wrapper: Building VST3 Single File")
set_target_properties(${V3_TARGET} PROPERTIES SUFFIX ".vst3")
set_target_properties(${V3_TARGET} PROPERTIES
LIBRARY_OUTPUT_NAME ${V3_OUTPUT_NAME}
SUFFIX ".vst3")
else()
message(STATUS "clap-wrapper: Building VST3 Bundle Folder")
add_custom_command(TARGET ${V3_TARGET} PRE_BUILD
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory "$<IF:$<CONFIG:Debug>,Debug,Release>/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-win"
)
set_target_properties(${V3_TARGET} PROPERTIES
LIBRARY_OUTPUT_NAME ${V3_OUTPUT_NAME}
LIBRARY_OUTPUT_DIRECTORY "$<IF:$<CONFIG:Debug>,Debug,Release>/${CMAKE_BINARY_DIR}/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-win"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/Debug/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-win"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release/${V3_OUTPUT_NAME}.vst3/Contents/x86_64-win"
SUFFIX ".vst3")
endif()
endif()


endfunction(target_add_vst3_wrapper)


Expand Down Expand Up @@ -475,7 +503,7 @@ if (APPLE)
target_link_libraries(clap-wrapper-auv2-${AUV2_TARGET} INTERFACE clap-core auv2_sdk)

# clap-wrapper-extensions are PUBLIC, so a clap linking the library can access the clap-wrapper-extensions
target_compile_definitions(clap-wrapper-auv2-${AUV2_TARGET} INTERFACE -D${PLATFORM}=1)
target_compile_definitions(clap-wrapper-auv2-${AUV2_TARGET} INTERFACE -D${CLAP_WRAPPER_PLATFORM}=1)
target_link_libraries(clap-wrapper-auv2-${AUV2_TARGET} INTERFACE clap-wrapper-extensions ghc_filesystem)
endif()

Expand All @@ -498,6 +526,7 @@ if (APPLE)
set_target_properties(${AUV2_TARGET} PROPERTIES
BUNDLE True
BUNDLE_EXTENSION component
LIBRARY_OUTPUT_NAME ${AUV2_OUTPUT_NAME}
MACOSX_BUNDLE_GUI_IDENTIFIER "${AUV2_BUNDLE_IDENTIFIER}.component"
MACOSX_BUNDLE_BUNDLE_NAME ${AUV2_OUTPUT_NAME}
MACOSX_BUNDLE_BUNDLE_VERSION ${AUV2_BUNDLE_VERSION}
Expand Down Expand Up @@ -534,5 +563,5 @@ if(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
# a 32 bit build is odd enough that it might be an error. Chirp.
message(STATUS "clap-wrapper: configured as 32 bit build. Intentional?")
endif()
message(STATUS "clap-wrapper: source dir is ${CMAKE_CURRENT_SOURCE_DIR}, platform is ${PLATFORM}")
message(STATUS "clap-wrapper: source dir is ${CMAKE_CURRENT_SOURCE_DIR}, platform is ${CLAP_WRAPPER_PLATFORM}")

Loading

0 comments on commit c07ac2d

Please sign in to comment.