DISTRHO Plugin Framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1249 lines
44KB

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