DPF-plugin.cmake (37241B)
1 # DISTRHO Plugin Framework (DPF) 2 # Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru> 3 # Copyright (C) 2022-2024 Filipe Coelho <falktx@falktx.com> 4 # 5 # SPDX-License-Identifier: ISC 6 7 # ------------------------------------------------------------------------------ 8 # CMake support module for the DISTRHO Plugin Framework 9 # 10 # The purpose of this module is to help building music plugins easily, when the 11 # project uses CMake as its build system. 12 # 13 # In order to use the helpers provided by this module, a plugin author should 14 # add DPF as a subproject, making the function `dpf_add_plugin` available. 15 # The usage of this function is documented below in greater detail. 16 # 17 # Example project `CMakeLists.txt`: 18 # 19 # ``` 20 # cmake_minimum_required(VERSION 3.7) 21 # project(MyPlugin) 22 # 23 # add_subdirectory(DPF) 24 # 25 # dpf_add_plugin(MyPlugin 26 # TARGETS clap lv2 vst2 vst3 27 # UI_TYPE opengl 28 # FILES_DSP 29 # src/MyPlugin.cpp 30 # FILES_UI 31 # src/MyUI.cpp) 32 # 33 # target_include_directories(MyPlugin 34 # PUBLIC src) 35 # ``` 36 # 37 # Important: note that properties, such as include directories, definitions, 38 # and linked libraries *must* be marked with `PUBLIC` so they take effect and 39 # propagate into all the plugin targets. 40 41 include(CMakeParseArguments) 42 43 # ------------------------------------------------------------------------------ 44 # DPF public functions 45 # ------------------------------------------------------------------------------ 46 47 # dpf_add_plugin(name <args...>) 48 # ------------------------------------------------------------------------------ 49 # 50 # Add a plugin built using the DISTRHO Plugin Framework. 51 # 52 # ------------------------------------------------------------------------------ 53 # Created targets: 54 # 55 # `<name>` 56 # static library: the common part of the plugin 57 # The public properties set on this target apply to both DSP and UI. 58 # 59 # `<name>-dsp` 60 # static library: the DSP part of the plugin 61 # The public properties set on this target apply to the DSP only. 62 # 63 # `<name>-ui` 64 # static library: the UI part of the plugin 65 # The public properties set on this target apply to the UI only. 66 # 67 # `<name>-<target>` for each target specified with the `TARGETS` argument. 68 # This is target-dependent and not intended for public use. 69 # 70 # ------------------------------------------------------------------------------ 71 # Arguments: 72 # 73 # `TARGETS` <tgt1>...<tgtN> 74 # a list of one of more of the following target types: 75 # `jack`, `ladspa`, `dssi`, `lv2`, `vst2`, `vst3`, `clap` 76 # 77 # `UI_TYPE` <type> 78 # the user interface type: `opengl` (default), `cairo`, `external` 79 # 80 # `FILES_COMMON` <file1>...<fileN> 81 # list of sources which are part of both DSP and UI 82 # 83 # `FILES_DSP` <file1>...<fileN> 84 # list of sources which are part of the DSP 85 # 86 # `FILES_UI` <file1>...<fileN> 87 # list of sources which are part of the UI 88 # empty indicates the plugin does not have UI 89 # 90 # `MODGUI_CLASS_NAME` 91 # class name to use for modgui builds 92 # 93 # `MONOLITHIC` 94 # build LV2 as a single binary for UI and DSP 95 # 96 # `NO_SHARED_RESOURCES` 97 # do not build DPF shared resources (fonts, etc) 98 # 99 function(dpf_add_plugin NAME) 100 set(options MONOLITHIC NO_SHARED_RESOURCES) 101 set(oneValueArgs MODGUI_CLASS_NAME UI_TYPE) 102 set(multiValueArgs FILES_COMMON FILES_DSP FILES_UI TARGETS) 103 cmake_parse_arguments(_dpf_plugin "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 104 105 if("${_dpf_plugin_UI_TYPE}" STREQUAL "") 106 set(_dpf_plugin_UI_TYPE "opengl") 107 endif() 108 109 set(_dgl_library) 110 set(_dgl_external OFF) 111 if(_dpf_plugin_FILES_UI) 112 if(_dpf_plugin_UI_TYPE STREQUAL "cairo") 113 dpf__add_dgl_cairo("${_dpf_plugin_NO_SHARED_RESOURCES}") 114 set(_dgl_library dgl-cairo) 115 elseif(_dpf_plugin_UI_TYPE STREQUAL "opengl") 116 dpf__add_dgl_opengl("${_dpf_plugin_NO_SHARED_RESOURCES}") 117 set(_dgl_library dgl-opengl) 118 elseif(_dpf_plugin_UI_TYPE STREQUAL "external") 119 set(_dgl_external ON) 120 else() 121 message(FATAL_ERROR "Unrecognized UI type for plugin: ${_dpf_plugin_UI_TYPE}") 122 endif() 123 endif() 124 125 set(_dgl_has_ui OFF) 126 if(_dgl_library OR _dgl_external) 127 set(_dgl_has_ui ON) 128 endif() 129 130 ### 131 dpf__ensure_sources_non_empty(_dpf_plugin_FILES_COMMON) 132 dpf__ensure_sources_non_empty(_dpf_plugin_FILES_DSP) 133 dpf__ensure_sources_non_empty(_dpf_plugin_FILES_UI) 134 135 ### 136 dpf__add_static_library("${NAME}" ${_dpf_plugin_FILES_COMMON}) 137 target_include_directories("${NAME}" PUBLIC 138 "${DPF_ROOT_DIR}/distrho") 139 140 if(_dpf_plugin_MODGUI_CLASS_NAME) 141 target_compile_definitions("${NAME}" PUBLIC "DISTRHO_PLUGIN_MODGUI_CLASS_NAME=\"${_dpf_plugin_MODGUI_CLASS_NAME}\"") 142 endif() 143 144 if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU)) 145 target_link_libraries("${NAME}" PRIVATE "dl") 146 endif() 147 148 if(_dgl_library AND NOT _dgl_external) 149 # make sure that all code will see DGL_* definitions 150 target_link_libraries("${NAME}" PUBLIC 151 "${_dgl_library}-definitions" 152 dgl-system-libs-definitions 153 dgl-system-libs) 154 endif() 155 156 dpf__add_static_library("${NAME}-dsp" ${_dpf_plugin_FILES_DSP}) 157 target_link_libraries("${NAME}-dsp" PUBLIC "${NAME}") 158 159 if(_dgl_library AND NOT _dgl_external) 160 dpf__add_static_library("${NAME}-ui" ${_dpf_plugin_FILES_UI}) 161 target_link_libraries("${NAME}-ui" PUBLIC "${NAME}" ${_dgl_library}) 162 if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU)) 163 target_link_libraries("${NAME}-ui" PRIVATE "dl") 164 endif() 165 # add the files containing Objective-C classes 166 dpf__add_plugin_specific_ui_sources("${NAME}-ui") 167 elseif(_dgl_external) 168 dpf__add_static_library("${NAME}-ui" ${_dpf_plugin_FILES_UI}) 169 target_link_libraries("${NAME}-ui" PUBLIC "${NAME}") 170 if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU)) 171 target_link_libraries("${NAME}-ui" PRIVATE "dl") 172 endif() 173 # add the files containing Objective-C classes 174 dpf__add_plugin_specific_ui_sources("${NAME}-ui") 175 else() 176 add_library("${NAME}-ui" INTERFACE) 177 endif() 178 179 ### 180 foreach(_target ${_dpf_plugin_TARGETS}) 181 if(_target STREQUAL "jack") 182 dpf__build_jack("${NAME}" "${_dgl_has_ui}") 183 elseif(_target STREQUAL "ladspa") 184 dpf__build_ladspa("${NAME}") 185 elseif(_target STREQUAL "dssi") 186 dpf__build_dssi("${NAME}" "${_dgl_has_ui}") 187 elseif(_target STREQUAL "lv2") 188 dpf__build_lv2("${NAME}" "${_dgl_has_ui}" "${_dpf_plugin_MONOLITHIC}") 189 elseif(_target STREQUAL "vst2") 190 dpf__build_vst2("${NAME}" "${_dgl_has_ui}") 191 elseif(_target STREQUAL "vst3") 192 dpf__build_vst3("${NAME}" "${_dgl_has_ui}") 193 elseif(_target STREQUAL "clap") 194 dpf__build_clap("${NAME}" "${_dgl_has_ui}") 195 elseif(_target STREQUAL "au") 196 if (APPLE) 197 dpf__build_au("${NAME}" "${_dgl_has_ui}") 198 endif() 199 elseif(_target STREQUAL "static") 200 dpf__build_static("${NAME}" "${_dgl_has_ui}") 201 else() 202 message(FATAL_ERROR "Unrecognized target type for plugin: ${_target}") 203 endif() 204 endforeach() 205 endfunction() 206 207 # ------------------------------------------------------------------------------ 208 # DPF private functions (prefixed with `dpf__`) 209 # ------------------------------------------------------------------------------ 210 211 # Note: The $<0:> trick is to prevent MSVC from appending the build type 212 # to the output directory. 213 # 214 215 # dpf__build_jack 216 # ------------------------------------------------------------------------------ 217 # 218 # Add build rules for a JACK/Standalone program. 219 # 220 function(dpf__build_jack NAME HAS_UI) 221 dpf__create_dummy_source_list(_no_srcs) 222 223 dpf__add_executable("${NAME}-jack" ${_no_srcs}) 224 dpf__add_plugin_main("${NAME}-jack" "jack") 225 dpf__add_ui_main("${NAME}-jack" "jack" "${HAS_UI}") 226 target_link_libraries("${NAME}-jack" PRIVATE "${NAME}-dsp" "${NAME}-ui") 227 set_target_properties("${NAME}-jack" PROPERTIES 228 RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" 229 OUTPUT_NAME "${NAME}") 230 231 target_compile_definitions("${NAME}" PUBLIC "HAVE_JACK") 232 target_compile_definitions("${NAME}-jack" PRIVATE "HAVE_GETTIMEOFDAY") 233 234 find_package(PkgConfig) 235 pkg_check_modules(SDL2 "sdl2") 236 if(SDL2_FOUND) 237 target_compile_definitions("${NAME}" PUBLIC "HAVE_SDL2") 238 target_include_directories("${NAME}-jack" PRIVATE ${SDL2_STATIC_INCLUDE_DIRS}) 239 target_link_libraries("${NAME}-jack" PRIVATE ${SDL2_STATIC_LIBRARIES}) 240 dpf__target_link_directories("${NAME}-jack" "${SDL2_STATIC_LIBRARY_DIRS}") 241 endif() 242 243 if(APPLE OR WIN32) 244 target_compile_definitions("${NAME}" PUBLIC "HAVE_RTAUDIO") 245 else() 246 find_package(Threads) 247 pkg_check_modules(ALSA "alsa") 248 pkg_check_modules(PULSEAUDIO "libpulse-simple") 249 if(ALSA_FOUND) 250 target_compile_definitions("${NAME}" PUBLIC "HAVE_ALSA") 251 target_include_directories("${NAME}-jack" PRIVATE ${ALSA_INCLUDE_DIRS}) 252 target_link_libraries("${NAME}-jack" PRIVATE ${ALSA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) 253 dpf__target_link_directories("${NAME}-jack" "${ALSA_LIBRARY_DIRS}") 254 endif() 255 if(PULSEAUDIO_FOUND) 256 target_compile_definitions("${NAME}" PUBLIC "HAVE_PULSEAUDIO") 257 target_include_directories("${NAME}-jack" PRIVATE ${PULSEAUDIO_INCLUDE_DIRS}) 258 target_link_libraries("${NAME}-jack" PRIVATE ${PULSEAUDIO_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) 259 dpf__target_link_directories("${NAME}-jack" "${PULSEAUDIO_LIBRARY_DIRS}") 260 endif() 261 if(ALSA_FOUND OR PULSEAUDIO_FOUND) 262 target_compile_definitions("${NAME}" PUBLIC "HAVE_RTAUDIO") 263 endif() 264 endif() 265 266 # for RtAudio native fallback 267 if(APPLE) 268 find_library(APPLE_COREAUDIO_FRAMEWORK "CoreAudio") 269 find_library(APPLE_COREFOUNDATION_FRAMEWORK "CoreFoundation") 270 find_library(APPLE_COREMIDI_FRAMEWORK "CoreMIDI") 271 target_link_libraries("${NAME}-jack" PRIVATE 272 "${APPLE_COREAUDIO_FRAMEWORK}" 273 "${APPLE_COREFOUNDATION_FRAMEWORK}" 274 "${APPLE_COREMIDI_FRAMEWORK}") 275 elseif(WIN32) 276 target_link_libraries("${NAME}-jack" PRIVATE "ksuser" "mfplat" "mfuuid" "ole32" "winmm" "wmcodecdspuuid") 277 if(HAS_UI AND MINGW) 278 set_target_properties("${NAME}-jack" PROPERTIES WIN32_EXECUTABLE TRUE) 279 endif() 280 endif() 281 endfunction() 282 283 # dpf__build_ladspa 284 # ------------------------------------------------------------------------------ 285 # 286 # Add build rules for a LADSPA plugin. 287 # 288 function(dpf__build_ladspa NAME) 289 dpf__create_dummy_source_list(_no_srcs) 290 291 dpf__add_module("${NAME}-ladspa" ${_no_srcs}) 292 dpf__add_plugin_main("${NAME}-ladspa" "ladspa") 293 dpf__set_module_export_list("${NAME}-ladspa" "ladspa") 294 target_link_libraries("${NAME}-ladspa" PRIVATE "${NAME}-dsp") 295 set_target_properties("${NAME}-ladspa" PROPERTIES 296 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" 297 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/ladspa/$<0:>" 298 OUTPUT_NAME "${NAME}-ladspa" 299 PREFIX "") 300 endfunction() 301 302 # dpf__build_dssi 303 # ------------------------------------------------------------------------------ 304 # 305 # Add build rules for a DSSI plugin. 306 # 307 function(dpf__build_dssi NAME HAS_UI) 308 find_package(PkgConfig) 309 pkg_check_modules(LIBLO "liblo") 310 if(NOT LIBLO_FOUND) 311 dpf__warn_once_only(missing_liblo 312 "liblo is not found, skipping the `dssi` plugin targets") 313 return() 314 endif() 315 316 dpf__create_dummy_source_list(_no_srcs) 317 318 dpf__add_module("${NAME}-dssi" ${_no_srcs}) 319 dpf__add_plugin_main("${NAME}-dssi" "dssi") 320 dpf__set_module_export_list("${NAME}-dssi" "dssi") 321 target_link_libraries("${NAME}-dssi" PRIVATE "${NAME}-dsp") 322 set_target_properties("${NAME}-dssi" PROPERTIES 323 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" 324 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/dssi/$<0:>" 325 OUTPUT_NAME "${NAME}-dssi" 326 PREFIX "") 327 328 if(HAS_UI) 329 dpf__add_executable("${NAME}-dssi-ui" ${_no_srcs}) 330 dpf__add_ui_main("${NAME}-dssi-ui" "dssi" "${HAS_UI}") 331 target_link_libraries("${NAME}-dssi-ui" PRIVATE "${NAME}-ui") 332 set_target_properties("${NAME}-dssi-ui" PROPERTIES 333 RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}-dssi/$<0:>" 334 OUTPUT_NAME "${NAME}_ui") 335 336 target_compile_definitions("${NAME}" PUBLIC "HAVE_LIBLO") 337 target_include_directories("${NAME}-dssi-ui" PRIVATE ${LIBLO_INCLUDE_DIRS}) 338 target_link_libraries("${NAME}-dssi-ui" PRIVATE ${LIBLO_LIBRARIES}) 339 dpf__target_link_directories("${NAME}-dssi-ui" "${LIBLO_LIBRARY_DIRS}") 340 endif() 341 endfunction() 342 343 # dpf__build_lv2 344 # ------------------------------------------------------------------------------ 345 # 346 # Add build rules for an LV2 plugin. 347 # 348 function(dpf__build_lv2 NAME HAS_UI MONOLITHIC) 349 dpf__create_dummy_source_list(_no_srcs) 350 351 dpf__add_module("${NAME}-lv2" ${_no_srcs}) 352 dpf__add_plugin_main("${NAME}-lv2" "lv2") 353 if(HAS_UI AND MONOLITHIC) 354 dpf__set_module_export_list("${NAME}-lv2" "lv2") 355 else() 356 dpf__set_module_export_list("${NAME}-lv2" "lv2-dsp") 357 endif() 358 target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-dsp") 359 set_target_properties("${NAME}-lv2" PROPERTIES 360 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" 361 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/lv2/$<0:>" 362 OUTPUT_NAME "${NAME}_dsp" 363 PREFIX "") 364 365 if(HAS_UI) 366 if(MONOLITHIC) 367 dpf__add_ui_main("${NAME}-lv2" "lv2" "${HAS_UI}") 368 target_link_libraries("${NAME}-lv2" PRIVATE "${NAME}-ui") 369 set_target_properties("${NAME}-lv2" PROPERTIES 370 OUTPUT_NAME "${NAME}") 371 else() 372 dpf__add_module("${NAME}-lv2-ui" ${_no_srcs}) 373 dpf__add_ui_main("${NAME}-lv2-ui" "lv2" "${HAS_UI}") 374 dpf__set_module_export_list("${NAME}-lv2-ui" "lv2-ui") 375 target_link_libraries("${NAME}-lv2-ui" PRIVATE "${NAME}-ui") 376 set_target_properties("${NAME}-lv2-ui" PROPERTIES 377 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2/$<0:>" 378 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/lv2/$<0:>" 379 OUTPUT_NAME "${NAME}_ui" 380 PREFIX "") 381 endif() 382 endif() 383 384 dpf__add_lv2_ttl_generator() 385 add_dependencies("${NAME}-lv2" lv2_ttl_generator) 386 387 separate_arguments(CMAKE_CROSSCOMPILING_EMULATOR) 388 389 add_custom_command(TARGET "${NAME}-lv2" POST_BUILD 390 COMMAND 391 ${CMAKE_CROSSCOMPILING_EMULATOR} 392 "$<TARGET_FILE:lv2_ttl_generator>" 393 "$<TARGET_FILE:${NAME}-lv2>" 394 WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.lv2" 395 DEPENDS lv2_ttl_generator) 396 endfunction() 397 398 # dpf__build_vst2 399 # ------------------------------------------------------------------------------ 400 # 401 # Add build rules for a VST2 plugin. 402 # 403 function(dpf__build_vst2 NAME HAS_UI) 404 dpf__create_dummy_source_list(_no_srcs) 405 406 dpf__add_module("${NAME}-vst2" ${_no_srcs}) 407 dpf__add_plugin_main("${NAME}-vst2" "vst2") 408 dpf__add_ui_main("${NAME}-vst2" "vst2" "${HAS_UI}") 409 dpf__set_module_export_list("${NAME}-vst2" "vst2") 410 target_link_libraries("${NAME}-vst2" PRIVATE "${NAME}-dsp" "${NAME}-ui") 411 set_target_properties("${NAME}-vst2" PROPERTIES 412 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" 413 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/vst2/$<0:>" 414 OUTPUT_NAME "${NAME}-vst2" 415 PREFIX "") 416 if(APPLE) 417 set_target_properties("${NAME}-vst2" PROPERTIES 418 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst/Contents/MacOS/$<0:>" 419 OUTPUT_NAME "${NAME}" 420 SUFFIX "") 421 set(INFO_PLIST_PROJECT_NAME "${NAME}") 422 configure_file("${DPF_ROOT_DIR}/utils/plugin.bundle/Contents/Info.plist" 423 "${PROJECT_BINARY_DIR}/bin/${NAME}.vst/Contents/Info.plist" @ONLY) 424 file(COPY "${DPF_ROOT_DIR}/utils/plugin.bundle/Contents/PkgInfo" 425 DESTINATION "${PROJECT_BINARY_DIR}/bin/${NAME}.vst/Contents") 426 endif() 427 endfunction() 428 429 # dpf__determine_vst3_package_architecture 430 # ------------------------------------------------------------------------------ 431 # 432 # Determines the package architecture for a VST3 plugin target. 433 # 434 function(dpf__determine_vst3_package_architecture OUTPUT_VARIABLE) 435 # if set by variable, override the detection 436 if(DPF_VST3_ARCHITECTURE) 437 set("${OUTPUT_VARIABLE}" "${DPF_VST3_ARCHITECTURE}" PARENT_SCOPE) 438 return() 439 endif() 440 441 # not used on Apple, which supports universal binary 442 if(APPLE) 443 set("${OUTPUT_VARIABLE}" "universal" PARENT_SCOPE) 444 return() 445 endif() 446 447 # identify the target processor (special case of MSVC, problematic sometimes) 448 if(MSVC) 449 set(vst3_system_arch "${MSVC_CXX_ARCHITECTURE_ID}") 450 else() 451 set(vst3_system_arch "${CMAKE_SYSTEM_PROCESSOR}") 452 endif() 453 454 # transform the processor name to a format that VST3 recognizes 455 if(vst3_system_arch MATCHES "^(x86_64|amd64|AMD64|x64|X64)$") 456 set(vst3_package_arch "x86_64") 457 elseif(vst3_system_arch MATCHES "^(i.86|x86|X86)$") 458 if(WIN32) 459 set(vst3_package_arch "x86") 460 else() 461 set(vst3_package_arch "i386") 462 endif() 463 elseif(vst3_system_arch MATCHES "^(armv[3-8][a-z]*|ppc(64)?(le)?)$") 464 set(vst3_package_arch "${vst3_system_arch}") 465 elseif(vst3_system_arch MATCHES "^(aarch64)$") 466 set(vst3_package_arch "aarch64") 467 else() 468 message(FATAL_ERROR "We don't know this architecture for VST3: ${vst3_system_arch}.") 469 endif() 470 471 # TODO: the detections for Windows arm/arm64 when supported 472 473 set("${OUTPUT_VARIABLE}" "${vst3_package_arch}" PARENT_SCOPE) 474 endfunction() 475 476 # dpf__build_vst3 477 # ------------------------------------------------------------------------------ 478 # 479 # Add build rules for a VST3 plugin. 480 # 481 function(dpf__build_vst3 NAME HAS_UI) 482 dpf__determine_vst3_package_architecture(vst3_arch) 483 484 dpf__create_dummy_source_list(_no_srcs) 485 486 dpf__add_module("${NAME}-vst3" ${_no_srcs}) 487 dpf__add_plugin_main("${NAME}-vst3" "vst3") 488 dpf__add_ui_main("${NAME}-vst3" "vst3" "${HAS_UI}") 489 dpf__set_module_export_list("${NAME}-vst3" "vst3") 490 target_link_libraries("${NAME}-vst3" PRIVATE "${NAME}-dsp" "${NAME}-ui") 491 set_target_properties("${NAME}-vst3" PROPERTIES 492 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/vst3/$<0:>" 493 OUTPUT_NAME "${NAME}" 494 PREFIX "") 495 496 if(APPLE) 497 set_target_properties("${NAME}-vst3" PROPERTIES 498 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/MacOS/$<0:>" 499 SUFFIX "") 500 elseif(WIN32) 501 set_target_properties("${NAME}-vst3" PROPERTIES 502 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/${vst3_arch}-win/$<0:>" SUFFIX ".vst3") 503 else() 504 set_target_properties("${NAME}-vst3" PROPERTIES 505 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/${vst3_arch}-linux/$<0:>") 506 endif() 507 508 if(APPLE) 509 # Uses the same macOS bundle template as VST2 510 set(INFO_PLIST_PROJECT_NAME "${NAME}") 511 configure_file("${DPF_ROOT_DIR}/utils/plugin.bundle/Contents/Info.plist" 512 "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/Info.plist" @ONLY) 513 file(COPY "${DPF_ROOT_DIR}/utils/plugin.bundle/Contents/PkgInfo" 514 DESTINATION "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents") 515 endif() 516 endfunction() 517 518 # dpf__build_clap 519 # ------------------------------------------------------------------------------ 520 # 521 # Add build rules for a CLAP plugin. 522 # 523 function(dpf__build_clap NAME HAS_UI) 524 dpf__create_dummy_source_list(_no_srcs) 525 526 dpf__add_module("${NAME}-clap" ${_no_srcs}) 527 dpf__add_plugin_main("${NAME}-clap" "clap") 528 dpf__add_ui_main("${NAME}-clap" "clap" "${HAS_UI}") 529 dpf__set_module_export_list("${NAME}-clap" "clap") 530 target_link_libraries("${NAME}-clap" PRIVATE "${NAME}-dsp" "${NAME}-ui") 531 set_target_properties("${NAME}-clap" PROPERTIES 532 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" 533 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/clap/$<0:>" 534 OUTPUT_NAME "${NAME}" 535 PREFIX "" 536 SUFFIX ".clap") 537 538 if(APPLE) 539 set_target_properties("${NAME}-clap" PROPERTIES 540 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.clap/Contents/MacOS/$<0:>" 541 OUTPUT_NAME "${NAME}" 542 SUFFIX "") 543 set(INFO_PLIST_PROJECT_NAME "${NAME}") 544 configure_file("${DPF_ROOT_DIR}/utils/plugin.bundle/Contents/Info.plist" 545 "${PROJECT_BINARY_DIR}/bin/${NAME}.clap/Contents/Info.plist" @ONLY) 546 file(COPY "${DPF_ROOT_DIR}/utils/plugin.bundle/Contents/PkgInfo" 547 DESTINATION "${PROJECT_BINARY_DIR}/bin/${NAME}.clap/Contents") 548 endif() 549 endfunction() 550 551 # dpf__build_au 552 # ------------------------------------------------------------------------------ 553 # 554 # Add build rules for an AUv2 plugin. 555 # 556 function(dpf__build_au NAME HAS_UI) 557 dpf__create_dummy_source_list(_no_srcs) 558 559 dpf__add_module("${NAME}-au" ${_no_srcs}) 560 dpf__add_plugin_main("${NAME}-au" "au") 561 dpf__add_ui_main("${NAME}-au" "au" "${HAS_UI}") 562 dpf__set_module_export_list("${NAME}-au" "au") 563 find_library(APPLE_AUDIOTOOLBOX_FRAMEWORK "AudioToolbox") 564 find_library(APPLE_AUDIOUNIT_FRAMEWORK "AudioUnit") 565 find_library(APPLE_COREFOUNDATION_FRAMEWORK "CoreFoundation") 566 target_compile_options("${NAME}-au" PRIVATE "-ObjC++") 567 target_link_libraries("${NAME}-au" PRIVATE 568 "${NAME}-dsp" 569 "${NAME}-ui" 570 "${APPLE_AUDIOTOOLBOX_FRAMEWORK}" 571 "${APPLE_AUDIOUNIT_FRAMEWORK}" 572 "${APPLE_COREFOUNDATION_FRAMEWORK}") 573 set_target_properties("${NAME}-au" PROPERTIES 574 LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.component/Contents/MacOS/$<0:>" 575 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/au/$<0:>" 576 OUTPUT_NAME "${NAME}" 577 PREFIX "" 578 SUFFIX "") 579 580 dpf__add_executable("${NAME}-export" ${_no_srcs}) 581 dpf__add_plugin_main("${NAME}-export" "export") 582 dpf__add_ui_main("${NAME}-export" "export" "${HAS_UI}") 583 target_link_libraries("${NAME}-export" PRIVATE "${NAME}-dsp" "${NAME}-ui") 584 585 separate_arguments(CMAKE_CROSSCOMPILING_EMULATOR) 586 587 add_custom_command(TARGET "${NAME}-au" POST_BUILD 588 COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} "$<TARGET_FILE:${NAME}-export>" "${NAME}" 589 WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.component/Contents" 590 DEPENDS "${NAME}-export") 591 592 add_dependencies("${NAME}-au" "${NAME}-export") 593 594 file(COPY "${DPF_ROOT_DIR}/utils/plugin.bundle/Contents/PkgInfo" 595 DESTINATION "${PROJECT_BINARY_DIR}/bin/${NAME}.component/Contents") 596 endfunction() 597 598 # dpf__build_static 599 # ------------------------------------------------------------------------------ 600 # 601 # Add build rules for a static library. 602 # 603 function(dpf__build_static NAME HAS_UI) 604 dpf__create_dummy_source_list(_no_srcs) 605 606 dpf__add_module("${NAME}-static" ${_no_srcs} STATIC) 607 dpf__add_plugin_main("${NAME}-static" "static") 608 dpf__add_ui_main("${NAME}-static" "static" "${HAS_UI}") 609 target_link_libraries("${NAME}-static" PRIVATE "${NAME}-dsp" "${NAME}-ui") 610 611 get_target_property(dsp_srcs "${NAME}-dsp" SOURCES) 612 get_target_property(ui_srcs "${NAME}-ui" SOURCES) 613 foreach(src ${dsp_srcs}) 614 target_sources("${NAME}-static" PRIVATE ${src}) 615 endforeach() 616 foreach(src ${ui_srcs}) 617 target_sources("${NAME}-static" PRIVATE ${src}) 618 endforeach() 619 620 set_target_properties("${NAME}-static" PROPERTIES 621 ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/$<0:>" 622 OUTPUT_NAME "${NAME}" 623 PREFIX "") 624 endfunction() 625 626 # dpf__add_dgl_cairo 627 # ------------------------------------------------------------------------------ 628 # 629 # Add the Cairo variant of DGL, if not already available. 630 # 631 function(dpf__add_dgl_cairo NO_SHARED_RESOURCES) 632 if(TARGET dgl-cairo) 633 return() 634 endif() 635 636 find_package(PkgConfig) 637 pkg_check_modules(CAIRO "cairo" REQUIRED) 638 639 link_directories(${CAIRO_LIBRARY_DIRS}) 640 641 dpf__add_static_library(dgl-cairo STATIC 642 "${DPF_ROOT_DIR}/dgl/src/Application.cpp" 643 "${DPF_ROOT_DIR}/dgl/src/ApplicationPrivateData.cpp" 644 "${DPF_ROOT_DIR}/dgl/src/Color.cpp" 645 "${DPF_ROOT_DIR}/dgl/src/EventHandlers.cpp" 646 "${DPF_ROOT_DIR}/dgl/src/Geometry.cpp" 647 "${DPF_ROOT_DIR}/dgl/src/ImageBase.cpp" 648 "${DPF_ROOT_DIR}/dgl/src/ImageBaseWidgets.cpp" 649 "${DPF_ROOT_DIR}/dgl/src/Layout.cpp" 650 "${DPF_ROOT_DIR}/dgl/src/SubWidget.cpp" 651 "${DPF_ROOT_DIR}/dgl/src/SubWidgetPrivateData.cpp" 652 "${DPF_ROOT_DIR}/dgl/src/TopLevelWidget.cpp" 653 "${DPF_ROOT_DIR}/dgl/src/TopLevelWidgetPrivateData.cpp" 654 "${DPF_ROOT_DIR}/dgl/src/Widget.cpp" 655 "${DPF_ROOT_DIR}/dgl/src/WidgetPrivateData.cpp" 656 "${DPF_ROOT_DIR}/dgl/src/Window.cpp" 657 "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" 658 "${DPF_ROOT_DIR}/dgl/src/Cairo.cpp") 659 if(NO_SHARED_RESOURCES) 660 target_compile_definitions(dgl-cairo PUBLIC "DGL_NO_SHARED_RESOURCES") 661 else() 662 target_sources(dgl-cairo PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") 663 endif() 664 if(APPLE) 665 target_sources(dgl-cairo PRIVATE 666 "${DPF_ROOT_DIR}/dgl/src/pugl.mm") 667 else() 668 target_sources(dgl-cairo PRIVATE 669 "${DPF_ROOT_DIR}/dgl/src/pugl.cpp") 670 endif() 671 target_include_directories(dgl-cairo PUBLIC 672 "${DPF_ROOT_DIR}/dgl") 673 target_include_directories(dgl-cairo PUBLIC 674 "${DPF_ROOT_DIR}/dgl/src/pugl-upstream/include") 675 676 dpf__add_dgl_system_libs() 677 target_link_libraries(dgl-cairo PRIVATE dgl-system-libs) 678 679 add_library(dgl-cairo-definitions INTERFACE) 680 target_compile_definitions(dgl-cairo-definitions INTERFACE "DGL_CAIRO" "HAVE_CAIRO" "HAVE_DGL") 681 682 target_include_directories(dgl-cairo PUBLIC ${CAIRO_INCLUDE_DIRS}) 683 if(MINGW) 684 target_link_libraries(dgl-cairo PRIVATE ${CAIRO_STATIC_LIBRARIES}) 685 else() 686 target_link_libraries(dgl-cairo PRIVATE ${CAIRO_LIBRARIES}) 687 endif() 688 target_link_libraries(dgl-cairo PRIVATE dgl-cairo-definitions) 689 endfunction() 690 691 # dpf__add_dgl_opengl 692 # ------------------------------------------------------------------------------ 693 # 694 # Add the OpenGL variant of DGL, if not already available. 695 # 696 function(dpf__add_dgl_opengl NO_SHARED_RESOURCES) 697 if(TARGET dgl-opengl) 698 return() 699 endif() 700 701 if(NOT OpenGL_GL_PREFERENCE) 702 set(OpenGL_GL_PREFERENCE "LEGACY") 703 endif() 704 705 find_package(OpenGL REQUIRED) 706 707 dpf__add_static_library(dgl-opengl STATIC 708 "${DPF_ROOT_DIR}/dgl/src/Application.cpp" 709 "${DPF_ROOT_DIR}/dgl/src/ApplicationPrivateData.cpp" 710 "${DPF_ROOT_DIR}/dgl/src/Color.cpp" 711 "${DPF_ROOT_DIR}/dgl/src/EventHandlers.cpp" 712 "${DPF_ROOT_DIR}/dgl/src/Geometry.cpp" 713 "${DPF_ROOT_DIR}/dgl/src/ImageBase.cpp" 714 "${DPF_ROOT_DIR}/dgl/src/ImageBaseWidgets.cpp" 715 "${DPF_ROOT_DIR}/dgl/src/Layout.cpp" 716 "${DPF_ROOT_DIR}/dgl/src/SubWidget.cpp" 717 "${DPF_ROOT_DIR}/dgl/src/SubWidgetPrivateData.cpp" 718 "${DPF_ROOT_DIR}/dgl/src/TopLevelWidget.cpp" 719 "${DPF_ROOT_DIR}/dgl/src/TopLevelWidgetPrivateData.cpp" 720 "${DPF_ROOT_DIR}/dgl/src/Widget.cpp" 721 "${DPF_ROOT_DIR}/dgl/src/WidgetPrivateData.cpp" 722 "${DPF_ROOT_DIR}/dgl/src/Window.cpp" 723 "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" 724 "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" 725 "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") 726 if(NO_SHARED_RESOURCES) 727 target_compile_definitions(dgl-opengl PUBLIC "DGL_NO_SHARED_RESOURCES") 728 else() 729 target_sources(dgl-opengl PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") 730 endif() 731 if(APPLE) 732 target_sources(dgl-opengl PRIVATE 733 "${DPF_ROOT_DIR}/dgl/src/pugl.mm") 734 else() 735 target_sources(dgl-opengl PRIVATE 736 "${DPF_ROOT_DIR}/dgl/src/pugl.cpp") 737 endif() 738 target_include_directories(dgl-opengl PUBLIC 739 "${DPF_ROOT_DIR}/dgl") 740 target_include_directories(dgl-opengl PUBLIC 741 "${DPF_ROOT_DIR}/dgl/src/pugl-upstream/include") 742 743 if(APPLE) 744 target_compile_definitions(dgl-opengl PUBLIC "GL_SILENCE_DEPRECATION") 745 endif() 746 747 dpf__add_dgl_system_libs() 748 target_link_libraries(dgl-opengl PRIVATE dgl-system-libs) 749 750 add_library(dgl-opengl-definitions INTERFACE) 751 target_compile_definitions(dgl-opengl-definitions INTERFACE "DGL_OPENGL" "HAVE_OPENGL" "HAVE_DGL") 752 753 target_include_directories(dgl-opengl PUBLIC "${OPENGL_INCLUDE_DIR}") 754 target_link_libraries(dgl-opengl PRIVATE dgl-opengl-definitions "${OPENGL_gl_LIBRARY}") 755 endfunction() 756 757 # dpf__add_plugin_specific_ui_sources 758 # ------------------------------------------------------------------------------ 759 # 760 # Compile system specific files, for now it is just Objective-C code 761 # 762 function(dpf__add_plugin_specific_ui_sources NAME) 763 if(APPLE) 764 target_sources("${NAME}" PRIVATE 765 "${DPF_ROOT_DIR}/distrho/DistrhoUI_macOS.mm") 766 endif() 767 endfunction() 768 769 # dpf__add_dgl_system_libs 770 # ------------------------------------------------------------------------------ 771 # 772 # Find system libraries required by DGL and add them as an interface target. 773 # 774 function(dpf__add_dgl_system_libs) 775 if(TARGET dgl-system-libs) 776 return() 777 endif() 778 add_library(dgl-system-libs INTERFACE) 779 add_library(dgl-system-libs-definitions INTERFACE) 780 if(APPLE) 781 find_library(APPLE_COCOA_FRAMEWORK "Cocoa") 782 find_library(APPLE_COREVIDEO_FRAMEWORK "CoreVideo") 783 target_link_libraries(dgl-system-libs INTERFACE "${APPLE_COCOA_FRAMEWORK}" "${APPLE_COREVIDEO_FRAMEWORK}") 784 elseif(EMSCRIPTEN) 785 elseif(HAIKU) 786 target_link_libraries(dgl-system-libs INTERFACE "be") 787 elseif(WIN32) 788 target_link_libraries(dgl-system-libs INTERFACE "comdlg32" "dwmapi" "gdi32") 789 else() 790 find_package(PkgConfig) 791 pkg_check_modules(DBUS "dbus-1") 792 if(DBUS_FOUND) 793 target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_DBUS") 794 target_include_directories(dgl-system-libs INTERFACE "${DBUS_INCLUDE_DIRS}") 795 target_link_libraries(dgl-system-libs INTERFACE "${DBUS_LIBRARIES}") 796 endif() 797 find_package(X11 REQUIRED) 798 target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_X11") 799 target_include_directories(dgl-system-libs INTERFACE "${X11_INCLUDE_DIR}") 800 target_link_libraries(dgl-system-libs INTERFACE "${X11_X11_LIB}") 801 if(X11_Xcursor_FOUND) 802 target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XCURSOR") 803 target_link_libraries(dgl-system-libs INTERFACE "${X11_Xcursor_LIB}") 804 endif() 805 if(X11_Xext_FOUND) 806 target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XEXT") 807 target_link_libraries(dgl-system-libs INTERFACE "${X11_Xext_LIB}") 808 endif() 809 if(X11_Xrandr_FOUND) 810 target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XRANDR") 811 target_link_libraries(dgl-system-libs INTERFACE "${X11_Xrandr_LIB}") 812 endif() 813 if(X11_XSync_FOUND) 814 target_compile_definitions(dgl-system-libs-definitions INTERFACE "HAVE_XSYNC") 815 target_link_libraries(dgl-system-libs INTERFACE "${X11_XSync_LIB}") 816 endif() 817 endif() 818 819 if(MSVC) 820 file(MAKE_DIRECTORY "${DPF_ROOT_DIR}/khronos/GL") 821 foreach(_gl_header "glext.h") 822 if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}") 823 file(DOWNLOAD "https://www.khronos.org/registry/OpenGL/api/GL/${_gl_header}" "${DPF_ROOT_DIR}/khronos/GL/${_gl_header}" SHOW_PROGRESS) 824 endif() 825 endforeach() 826 foreach(_khr_header "khrplatform.h") 827 if(NOT EXISTS "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}") 828 file(DOWNLOAD "https://www.khronos.org/registry/EGL/api/KHR/${_khr_header}" "${DPF_ROOT_DIR}/khronos/KHR/${_khr_header}" SHOW_PROGRESS) 829 endif() 830 endforeach() 831 target_include_directories(dgl-system-libs-definitions INTERFACE "${DPF_ROOT_DIR}/khronos") 832 endif() 833 834 target_link_libraries(dgl-system-libs INTERFACE dgl-system-libs-definitions) 835 endfunction() 836 837 # dpf__add_executable 838 # ------------------------------------------------------------------------------ 839 # 840 # Adds an executable target, and set some default properties on the target. 841 # 842 function(dpf__add_executable NAME) 843 add_executable("${NAME}" ${ARGN}) 844 dpf__set_target_defaults("${NAME}") 845 if(MINGW) 846 target_link_libraries("${NAME}" PRIVATE "-static") 847 endif() 848 endfunction() 849 850 # dpf__add_module 851 # ------------------------------------------------------------------------------ 852 # 853 # Adds a module target, and set some default properties on the target. 854 # 855 function(dpf__add_module NAME) 856 add_library("${NAME}" MODULE ${ARGN}) 857 dpf__set_target_defaults("${NAME}") 858 if(APPLE) 859 set_target_properties("${NAME}" PROPERTIES SUFFIX ".dylib") 860 elseif(MINGW) 861 target_link_libraries("${NAME}" PRIVATE "-static") 862 endif() 863 endfunction() 864 865 # dpf__add_static_library 866 # ------------------------------------------------------------------------------ 867 # 868 # Adds a static library target, and set some default properties on the target. 869 # 870 function(dpf__add_static_library NAME) 871 add_library("${NAME}" STATIC ${ARGN}) 872 dpf__set_target_defaults("${NAME}") 873 endfunction() 874 875 # dpf__set_module_export_list 876 # ------------------------------------------------------------------------------ 877 # 878 # Applies a list of exported symbols to the module target. 879 # 880 function(dpf__set_module_export_list NAME EXPORTS) 881 if(WIN32) 882 target_sources("${NAME}" PRIVATE "${DPF_ROOT_DIR}/utils/symbols/${EXPORTS}.def") 883 elseif(APPLE) 884 set_property(TARGET "${NAME}" APPEND PROPERTY LINK_OPTIONS 885 "-Xlinker" "-exported_symbols_list" 886 "-Xlinker" "${DPF_ROOT_DIR}/utils/symbols/${EXPORTS}.exp") 887 else() 888 set_property(TARGET "${NAME}" APPEND PROPERTY LINK_OPTIONS 889 "-Xlinker" "--version-script=${DPF_ROOT_DIR}/utils/symbols/${EXPORTS}.version") 890 endif() 891 endfunction() 892 893 # dpf__set_target_defaults 894 # ------------------------------------------------------------------------------ 895 # 896 # Set default properties which must apply to all DPF-defined targets. 897 # 898 function(dpf__set_target_defaults NAME) 899 set_target_properties("${NAME}" PROPERTIES 900 POSITION_INDEPENDENT_CODE TRUE 901 C_VISIBILITY_PRESET "hidden" 902 CXX_VISIBILITY_PRESET "hidden" 903 VISIBILITY_INLINES_HIDDEN TRUE) 904 if(WIN32) 905 target_compile_definitions("${NAME}" PUBLIC "NOMINMAX") 906 endif() 907 if (MINGW) 908 target_compile_options("${NAME}" PUBLIC "-mstackrealign") 909 endif() 910 if (MSVC) 911 target_compile_options("${NAME}" PUBLIC "/UTF-8") 912 target_compile_definitions("${NAME}" PUBLIC "_CRT_SECURE_NO_WARNINGS") 913 endif() 914 if (CMAKE_COMPILER_IS_GNUCXX) 915 target_compile_options("${NAME}" PUBLIC "-fno-gnu-unique") 916 endif() 917 endfunction() 918 919 # dpf__add_plugin_main 920 # ------------------------------------------------------------------------------ 921 # 922 # Adds plugin code to the given target. 923 # 924 function(dpf__add_plugin_main NAME TARGET) 925 target_sources("${NAME}" PRIVATE 926 "${DPF_ROOT_DIR}/distrho/DistrhoPluginMain.cpp") 927 dpf__add_plugin_target_definition("${NAME}" "${TARGET}") 928 endfunction() 929 930 # dpf__add_ui_main 931 # ------------------------------------------------------------------------------ 932 # 933 # Adds UI code to the given target (only if the target has UI). 934 # 935 function(dpf__add_ui_main NAME TARGET HAS_UI) 936 if(HAS_UI) 937 target_sources("${NAME}" PRIVATE 938 "${DPF_ROOT_DIR}/distrho/DistrhoUIMain.cpp") 939 dpf__add_plugin_target_definition("${NAME}" "${TARGET}") 940 endif() 941 endfunction() 942 943 # dpf__add_plugin_target_definition 944 # ------------------------------------------------------------------------------ 945 # 946 # Adds the plugins target macro definition. 947 # This selects which entry file is compiled according to the target type. 948 # 949 function(dpf__add_plugin_target_definition NAME TARGET) 950 string(TOUPPER "${TARGET}" _upperTarget) 951 target_compile_definitions("${NAME}" PRIVATE "DISTRHO_PLUGIN_TARGET_${_upperTarget}") 952 endfunction() 953 954 # dpf__add_lv2_ttl_generator 955 # ------------------------------------------------------------------------------ 956 # 957 # Build the LV2 TTL generator. 958 # 959 function(dpf__add_lv2_ttl_generator) 960 if(TARGET lv2_ttl_generator) 961 return() 962 endif() 963 add_executable(lv2_ttl_generator "${DPF_ROOT_DIR}/utils/lv2-ttl-generator/lv2_ttl_generator.c") 964 if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU)) 965 target_link_libraries(lv2_ttl_generator PRIVATE "dl") 966 endif() 967 endfunction() 968 969 # dpf__ensure_sources_non_empty 970 # ------------------------------------------------------------------------------ 971 # 972 # Ensure the given source list contains at least one file. 973 # The function appends an empty source file to the list if necessary. 974 # This is useful when CMake does not permit to add targets without sources. 975 # 976 function(dpf__ensure_sources_non_empty VAR) 977 if(NOT "" STREQUAL "${${VAR}}") 978 return() 979 endif() 980 set(_file "${CMAKE_CURRENT_BINARY_DIR}/_dpf_empty.c") 981 if(NOT EXISTS "${_file}") 982 file(WRITE "${_file}" "") 983 endif() 984 set("${VAR}" "${_file}" PARENT_SCOPE) 985 endfunction() 986 987 # dpf__create_dummy_source_list 988 # ------------------------------------------------------------------------------ 989 # 990 # Create a dummy source list which is equivalent to compiling nothing. 991 # This is only for compatibility with older CMake versions, which refuse to add 992 # targets without any sources. 993 # 994 macro(dpf__create_dummy_source_list VAR) 995 set("${VAR}") 996 if(CMAKE_VERSION VERSION_LESS "3.11") 997 dpf__ensure_sources_non_empty("${VAR}") 998 endif() 999 endmacro() 1000 1001 # dpf__target_link_directories 1002 # ------------------------------------------------------------------------------ 1003 # 1004 # Call `target_link_directories` if cmake >= 3.13, 1005 # otherwise fallback to global `link_directories`. 1006 # 1007 macro(dpf__target_link_directories NAME DIRS) 1008 if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.13") 1009 target_link_directories("${NAME}" PUBLIC ${DIRS}) 1010 else() 1011 link_directories(${DIRS}) 1012 endif() 1013 endmacro() 1014 1015 # dpf__warn_once 1016 # ------------------------------------------------------------------------------ 1017 # 1018 # Prints a warning message once only. 1019 # 1020 function(dpf__warn_once_only TOKEN MESSAGE) 1021 get_property(_warned GLOBAL PROPERTY "dpf__have_warned_${TOKEN}") 1022 if(NOT _warned) 1023 set_property(GLOBAL PROPERTY "dpf__have_warned_${TOKEN}" TRUE) 1024 message(WARNING "${MESSAGE}") 1025 endif() 1026 endfunction()