The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

681 lines
27KB

  1. # ==============================================================================
  2. #
  3. # This file is part of the JUCE library.
  4. # Copyright (c) 2022 - Raw Material Software Limited
  5. #
  6. # JUCE is an open source library subject to commercial or open-source
  7. # licensing.
  8. #
  9. # By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  10. # Agreement and JUCE Privacy Policy.
  11. #
  12. # End User License Agreement: www.juce.com/juce-7-licence
  13. # Privacy Policy: www.juce.com/juce-privacy-policy
  14. #
  15. # Or: You may also use this code under the terms of the GPL v3 (see
  16. # www.gnu.org/licenses).
  17. #
  18. # JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  19. # EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  20. # DISCLAIMED.
  21. #
  22. # ==============================================================================
  23. # ==================================================================================================
  24. # JUCE Modules Support Helper Functions
  25. #
  26. # In this file, functions intended for use by end-users have the prefix `juce_`.
  27. # Functions beginning with an underscore should be considered private and susceptible to
  28. # change, so don't call them directly.
  29. #
  30. # See the readme at `docs/CMake API.md` for more information about CMake usage,
  31. # including documentation of the public functions in this file.
  32. # ==================================================================================================
  33. include_guard(GLOBAL)
  34. cmake_minimum_required(VERSION 3.15)
  35. # ==================================================================================================
  36. set(JUCE_CMAKE_UTILS_DIR ${CMAKE_CURRENT_LIST_DIR}
  37. CACHE INTERNAL "The path to the folder holding this file and other resources")
  38. include("${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake")
  39. include("${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake")
  40. # Tries to discover the target platform architecture, which is necessary for
  41. # naming VST3 bundle folders and including bundled libraries from modules
  42. function(_juce_find_target_architecture result)
  43. set(test_file "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp")
  44. try_compile(compile_result "${CMAKE_CURRENT_BINARY_DIR}" "${test_file}"
  45. OUTPUT_VARIABLE compile_output)
  46. string(REGEX REPLACE ".*JUCE_ARCH ([a-zA-Z0-9_-]*).*" "\\1" match_result "${compile_output}")
  47. set("${result}" "${match_result}" PARENT_SCOPE)
  48. endfunction()
  49. if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD") OR MSYS OR MINGW)
  50. # If you really need to override the detected arch for some reason,
  51. # you can configure the build with -DJUCE_TARGET_ARCHITECTURE=<custom arch>
  52. if(NOT DEFINED JUCE_TARGET_ARCHITECTURE)
  53. _juce_find_target_architecture(target_arch)
  54. set(JUCE_TARGET_ARCHITECTURE "${target_arch}"
  55. CACHE INTERNAL "The target architecture, used to name internal folders in VST3 bundles, and to locate bundled libraries in modules")
  56. endif()
  57. endif()
  58. # ==================================================================================================
  59. function(_juce_add_interface_library target)
  60. add_library(${target} INTERFACE)
  61. target_sources(${target} INTERFACE ${ARGN})
  62. endfunction()
  63. # ==================================================================================================
  64. function(_juce_add_standard_defs juce_target)
  65. target_compile_definitions(${juce_target} INTERFACE
  66. JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
  67. $<IF:$<CONFIG:DEBUG>,DEBUG=1 _DEBUG=1,NDEBUG=1 _NDEBUG=1>
  68. $<$<PLATFORM_ID:Android>:JUCE_ANDROID=1>)
  69. endfunction()
  70. # ==================================================================================================
  71. macro(_juce_make_absolute path)
  72. if(NOT IS_ABSOLUTE "${${path}}")
  73. get_filename_component(${path} "${${path}}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
  74. endif()
  75. string(REGEX REPLACE "\\\\" "/" ${path} "${${path}}")
  76. endmacro()
  77. macro(_juce_make_absolute_and_check path)
  78. _juce_make_absolute("${path}")
  79. if(NOT EXISTS "${${path}}")
  80. message(FATAL_ERROR "No file at path ${${path}}")
  81. endif()
  82. endmacro()
  83. # ==================================================================================================
  84. # This creates an imported interface library with a random name, and then adds
  85. # the fields from a JUCE module header to the target as INTERFACE_ properties.
  86. # We can extract properties later using `_juce_get_metadata`.
  87. # This way, the interface library ends up behaving a bit like a dictionary,
  88. # and we don't have to parse the module header from scratch every time we
  89. # want to find a specific key.
  90. function(_juce_extract_metadata_block delim_str file_with_block out_dict)
  91. string(RANDOM LENGTH 16 random_string)
  92. set(target_name "${random_string}_dict")
  93. set(${out_dict} "${target_name}" PARENT_SCOPE)
  94. add_library(${target_name} INTERFACE IMPORTED)
  95. if(NOT EXISTS ${file_with_block})
  96. message(FATAL_ERROR "Unable to find file ${file_with_block}")
  97. endif()
  98. file(STRINGS ${file_with_block} module_header_contents)
  99. set(last_written_key)
  100. set(append NO)
  101. foreach(line IN LISTS module_header_contents)
  102. if(NOT append)
  103. if(line MATCHES "[\t ]*BEGIN_${delim_str}[\t ]*")
  104. set(append YES)
  105. endif()
  106. continue()
  107. endif()
  108. if(append AND (line MATCHES "[\t ]*END_${delim_str}[\t ]*"))
  109. break()
  110. endif()
  111. if(line MATCHES "^[\t ]*([a-zA-Z]+):")
  112. set(last_written_key "${CMAKE_MATCH_1}")
  113. endif()
  114. string(REGEX REPLACE "^[\t ]*${last_written_key}:[\t ]*" "" line "${line}")
  115. string(REGEX REPLACE "[\t ,]+" ";" line "${line}")
  116. set_property(TARGET ${target_name} APPEND PROPERTY
  117. "INTERFACE_JUCE_${last_written_key}" "${line}")
  118. endforeach()
  119. endfunction()
  120. # Fetches properties attached to a metadata target.
  121. function(_juce_get_metadata target key out_var)
  122. get_target_property(content "${target}" "INTERFACE_JUCE_${key}")
  123. if(NOT "${content}" STREQUAL "content-NOTFOUND")
  124. set(${out_var} "${content}" PARENT_SCOPE)
  125. endif()
  126. endfunction()
  127. # ==================================================================================================
  128. function(_juce_should_build_module_source filename output_var)
  129. get_filename_component(trimmed_name "${filename}" NAME_WE)
  130. set(result TRUE)
  131. set(pairs
  132. "OSX\;Darwin"
  133. "Windows\;Windows"
  134. "Linux\;Linux"
  135. "Android\;Android"
  136. "iOS\;iOS")
  137. foreach(pair IN LISTS pairs)
  138. list(GET pair 0 suffix)
  139. list(GET pair 1 system_name)
  140. if((trimmed_name MATCHES "_${suffix}$") AND NOT (CMAKE_SYSTEM_NAME STREQUAL "${system_name}"))
  141. set(result FALSE)
  142. endif()
  143. endforeach()
  144. set("${output_var}" "${result}" PARENT_SCOPE)
  145. endfunction()
  146. function(_juce_module_sources module_path output_path built_sources other_sources)
  147. get_filename_component(module_parent_path ${module_path} DIRECTORY)
  148. get_filename_component(module_glob ${module_path} NAME)
  149. file(GLOB_RECURSE all_module_files
  150. CONFIGURE_DEPENDS LIST_DIRECTORIES FALSE
  151. RELATIVE "${module_parent_path}"
  152. "${module_path}/*")
  153. set(base_path "${module_glob}/${module_glob}")
  154. set(module_cpp ${all_module_files})
  155. list(FILTER module_cpp INCLUDE REGEX "^${base_path}[^/]*\\.(c|cc|cpp|cxx|s|asm)$")
  156. if(APPLE)
  157. set(module_mm ${all_module_files})
  158. list(FILTER module_mm INCLUDE REGEX "^${base_path}[^/]*\\.mm$")
  159. if(module_mm)
  160. set(module_mm_replaced ${module_mm})
  161. list(TRANSFORM module_mm_replaced REPLACE "\\.mm$" ".cpp")
  162. list(REMOVE_ITEM module_cpp ${module_mm_replaced})
  163. endif()
  164. set(module_apple_files ${all_module_files})
  165. list(FILTER module_apple_files INCLUDE REGEX "${base_path}[^/]*\\.(m|mm|metal|r|swift)$")
  166. list(APPEND module_cpp ${module_apple_files})
  167. endif()
  168. set(headers ${all_module_files})
  169. set(module_files_to_build)
  170. foreach(filename IN LISTS module_cpp)
  171. _juce_should_build_module_source("${filename}" should_build_file)
  172. if(should_build_file)
  173. list(APPEND module_files_to_build "${filename}")
  174. endif()
  175. endforeach()
  176. if(NOT "${module_files_to_build}" STREQUAL "")
  177. list(REMOVE_ITEM headers ${module_files_to_build})
  178. endif()
  179. foreach(source_list IN ITEMS module_files_to_build headers)
  180. list(TRANSFORM ${source_list} PREPEND "${output_path}/")
  181. endforeach()
  182. set(${built_sources} ${module_files_to_build} PARENT_SCOPE)
  183. set(${other_sources} ${headers} PARENT_SCOPE)
  184. endfunction()
  185. # ==================================================================================================
  186. function(_juce_get_all_plugin_kinds out)
  187. set(${out} AU AUv3 AAX LV2 Standalone Unity VST VST3 PARENT_SCOPE)
  188. endfunction()
  189. function(_juce_get_platform_plugin_kinds out)
  190. set(result Standalone)
  191. if(APPLE AND (CMAKE_GENERATOR STREQUAL "Xcode"))
  192. list(APPEND result AUv3)
  193. endif()
  194. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  195. list(APPEND result AU)
  196. endif()
  197. if(NOT CMAKE_SYSTEM_NAME STREQUAL "iOS" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
  198. list(APPEND result VST LV2)
  199. if(NOT (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
  200. list(APPEND result Unity VST3)
  201. endif()
  202. endif()
  203. if((CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "Windows") AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
  204. list(APPEND result AAX)
  205. endif()
  206. set(${out} ${result} PARENT_SCOPE)
  207. endfunction()
  208. function(_juce_add_plugin_definitions target visibility)
  209. _juce_get_all_plugin_kinds(options)
  210. cmake_parse_arguments(JUCE_ARG "${options}" "" "" ${ARGN})
  211. foreach(opt IN LISTS options)
  212. set(flag_value 0)
  213. if(JUCE_ARG_${opt})
  214. set(flag_value 1)
  215. endif()
  216. target_compile_definitions(${target} ${visibility} "JucePlugin_Build_${opt}=${flag_value}")
  217. endforeach()
  218. endfunction()
  219. # ==================================================================================================
  220. # Takes a target, a link visibility, if it should be a weak link, and a variable-length list of
  221. # framework names. On macOS, for non-weak links, this finds the requested frameworks using
  222. # `find_library`.
  223. function(_juce_link_frameworks target visibility)
  224. set(options WEAK)
  225. cmake_parse_arguments(JUCE_LINK_FRAMEWORKS "${options}" "" "" ${ARGN})
  226. foreach(framework IN LISTS JUCE_LINK_FRAMEWORKS_UNPARSED_ARGUMENTS)
  227. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  228. if(JUCE_LINK_FRAMEWORKS_WEAK)
  229. set(framework_flags "-weak_framework ${framework}")
  230. else()
  231. find_library("juce_found_${framework}" "${framework}" REQUIRED)
  232. set(framework_flags "${juce_found_${framework}}")
  233. endif()
  234. elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
  235. # CoreServices is only available on iOS 12+, we must link it weakly on earlier platforms
  236. if(JUCE_LINK_FRAMEWORKS_WEAK OR ((framework STREQUAL "CoreServices") AND (CMAKE_OSX_DEPLOYMENT_TARGET LESS 12.0)))
  237. set(framework_flags "-weak_framework ${framework}")
  238. else()
  239. set(framework_flags "-framework ${framework}")
  240. endif()
  241. endif()
  242. if(NOT framework_flags STREQUAL "")
  243. target_link_libraries("${target}" "${visibility}" "${framework_flags}")
  244. endif()
  245. endforeach()
  246. endfunction()
  247. # ==================================================================================================
  248. function(_juce_add_plugin_wrapper_target format path out_path)
  249. _juce_module_sources("${path}" "${out_path}" out_var headers)
  250. list(FILTER out_var EXCLUDE REGEX "/juce_audio_plugin_client_utils.cpp$")
  251. set(target_name juce_audio_plugin_client_${format})
  252. _juce_add_interface_library("${target_name}" ${out_var})
  253. _juce_add_plugin_definitions("${target_name}" INTERFACE ${format})
  254. _juce_add_standard_defs("${target_name}")
  255. target_compile_features("${target_name}" INTERFACE cxx_std_17)
  256. add_library("juce::${target_name}" ALIAS "${target_name}")
  257. if(format STREQUAL "AUv3")
  258. _juce_link_frameworks("${target_name}" INTERFACE AVFoundation)
  259. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  260. _juce_link_frameworks("${target_name}" INTERFACE AudioUnit)
  261. endif()
  262. elseif(format STREQUAL "AU")
  263. target_include_directories("${target_name}" INTERFACE "${out_path}/juce_audio_plugin_client/AU")
  264. _juce_link_frameworks("${target_name}" INTERFACE AudioUnit CoreAudioKit)
  265. endif()
  266. endfunction()
  267. # ==================================================================================================
  268. function(_juce_link_libs_from_metadata module_name dict key)
  269. _juce_get_metadata("${dict}" "${key}" libs)
  270. if(libs)
  271. target_link_libraries(${module_name} INTERFACE ${libs})
  272. endif()
  273. endfunction()
  274. # ==================================================================================================
  275. function(_juce_create_pkgconfig_target name)
  276. if(TARGET juce::pkgconfig_${name})
  277. return()
  278. endif()
  279. find_package(PkgConfig REQUIRED)
  280. pkg_check_modules(${name} ${ARGN})
  281. add_library(pkgconfig_${name} INTERFACE)
  282. add_library(juce::pkgconfig_${name} ALIAS pkgconfig_${name})
  283. install(TARGETS pkgconfig_${name} EXPORT JUCE)
  284. set(pairs
  285. "INCLUDE_DIRECTORIES\;INCLUDE_DIRS"
  286. "LINK_LIBRARIES\;LINK_LIBRARIES"
  287. "LINK_OPTIONS\;LDFLAGS_OTHER"
  288. "COMPILE_OPTIONS\;CFLAGS_OTHER")
  289. foreach(pair IN LISTS pairs)
  290. list(GET pair 0 key)
  291. list(GET pair 1 value)
  292. if(${name}_${value})
  293. set_target_properties(pkgconfig_${name} PROPERTIES INTERFACE_${key} "${${name}_${value}}")
  294. endif()
  295. endforeach()
  296. endfunction()
  297. # ==================================================================================================
  298. function(_juce_add_library_path target path)
  299. if(EXISTS "${path}")
  300. target_link_directories(${target} INTERFACE ${path})
  301. endif()
  302. endfunction()
  303. function(_juce_add_module_staticlib_paths module_target module_path)
  304. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  305. _juce_add_library_path(${module_target} "${module_path}/libs/MacOSX")
  306. elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
  307. _juce_add_library_path(${module_target} "${module_path}/libs/iOS")
  308. elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
  309. _juce_add_library_path(${module_target} "${module_path}/libs/Linux/${JUCE_TARGET_ARCHITECTURE}")
  310. elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  311. if(CMAKE_GENERATOR MATCHES "Visual Studio [0-9]+ (20[0-9]+)")
  312. set(arch "$<IF:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>,x64,Win32>")
  313. if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "")
  314. set(arch ${CMAKE_GENERATOR_PLATFORM})
  315. endif()
  316. set(runtime_lib "$<GENEX_EVAL:$<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>>")
  317. set(subfolder "MDd")
  318. set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreadedDebug>,MTd,${subfolder}>")
  319. set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreadedDLL>,MD,${subfolder}>")
  320. set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreaded>,MT,${subfolder}>")
  321. target_link_directories(${module_target} INTERFACE
  322. "${module_path}/libs/VisualStudio${CMAKE_MATCH_1}/${arch}/${subfolder}")
  323. elseif(MSYS OR MINGW)
  324. _juce_add_library_path(${module_target} "${module_path}/libs/MinGW/${JUCE_TARGET_ARCHITECTURE}")
  325. endif()
  326. elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
  327. _juce_add_library_path(${module_target} "${module_path}/libs/Android/${CMAKE_ANDROID_ARCH_ABI}")
  328. endif()
  329. endfunction()
  330. # ==================================================================================================
  331. function(_juce_remove_empty_list_elements arg)
  332. list(FILTER ${arg} EXCLUDE REGEX "^$")
  333. set(${arg} ${${arg}} PARENT_SCOPE)
  334. endfunction()
  335. function(juce_add_module module_path)
  336. set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
  337. cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
  338. _juce_make_absolute(module_path)
  339. get_filename_component(module_name ${module_path} NAME)
  340. get_filename_component(module_parent_path ${module_path} DIRECTORY)
  341. set(module_header_name "${module_name}.h")
  342. if(NOT EXISTS "${module_path}/${module_header_name}")
  343. set(module_header_name "${module_header_name}pp")
  344. endif()
  345. if(NOT EXISTS "${module_path}/${module_header_name}")
  346. message(FATAL_ERROR "Could not locate module header for module '${module_path}'")
  347. endif()
  348. set(base_path "${module_parent_path}")
  349. _juce_module_sources("${module_path}" "${base_path}" globbed_sources headers)
  350. if(${module_name} STREQUAL "juce_audio_plugin_client")
  351. list(REMOVE_ITEM headers "${module_path}/LV2/juce_LV2TurtleDumpProgram.cpp")
  352. _juce_get_platform_plugin_kinds(plugin_kinds)
  353. foreach(kind IN LISTS plugin_kinds)
  354. _juce_add_plugin_wrapper_target(${kind} "${module_path}" "${base_path}")
  355. endforeach()
  356. set(utils_source
  357. "${base_path}/${module_name}/juce_audio_plugin_client_utils.cpp")
  358. add_library(juce_audio_plugin_client_utils INTERFACE)
  359. target_sources(juce_audio_plugin_client_utils INTERFACE "${utils_source}")
  360. if(JUCE_ARG_ALIAS_NAMESPACE)
  361. add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_audio_plugin_client_utils
  362. ALIAS juce_audio_plugin_client_utils)
  363. endif()
  364. file(GLOB_RECURSE all_module_files
  365. CONFIGURE_DEPENDS LIST_DIRECTORIES FALSE
  366. RELATIVE "${module_parent_path}"
  367. "${module_path}/*")
  368. else()
  369. list(APPEND all_module_sources ${globbed_sources})
  370. endif()
  371. _juce_add_interface_library(${module_name} ${all_module_sources})
  372. set_property(GLOBAL APPEND PROPERTY _juce_module_names ${module_name})
  373. set_target_properties(${module_name} PROPERTIES
  374. INTERFACE_JUCE_MODULE_SOURCES "${globbed_sources}"
  375. INTERFACE_JUCE_MODULE_HEADERS "${headers}"
  376. INTERFACE_JUCE_MODULE_PATH "${base_path}")
  377. if(JUCE_ENABLE_MODULE_SOURCE_GROUPS)
  378. target_sources(${module_name} INTERFACE ${headers})
  379. endif()
  380. if(${module_name} STREQUAL "juce_core")
  381. _juce_add_standard_defs(${module_name})
  382. target_link_libraries(juce_core INTERFACE juce::juce_atomic_wrapper)
  383. if(CMAKE_SYSTEM_NAME MATCHES ".*BSD")
  384. target_link_libraries(juce_core INTERFACE execinfo)
  385. elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
  386. target_sources(juce_core INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")
  387. target_include_directories(juce_core INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures")
  388. target_link_libraries(juce_core INTERFACE android log)
  389. endif()
  390. endif()
  391. if(${module_name} STREQUAL "juce_audio_processors")
  392. add_library(juce_vst3_headers INTERFACE)
  393. target_compile_definitions(juce_vst3_headers INTERFACE "$<$<TARGET_EXISTS:juce_vst3_sdk>:JUCE_CUSTOM_VST3_SDK=1>")
  394. target_include_directories(juce_vst3_headers INTERFACE
  395. "$<$<TARGET_EXISTS:juce_vst3_sdk>:$<TARGET_PROPERTY:juce_vst3_sdk,INTERFACE_INCLUDE_DIRECTORIES>>"
  396. "$<$<NOT:$<TARGET_EXISTS:juce_vst3_sdk>>:${base_path}/juce_audio_processors/format_types/VST3_SDK>")
  397. target_link_libraries(juce_audio_processors INTERFACE juce_vst3_headers)
  398. add_library(juce_lilv_headers INTERFACE)
  399. set(lv2_base_path "${base_path}/juce_audio_processors/format_types/LV2_SDK")
  400. target_include_directories(juce_lilv_headers INTERFACE
  401. "${lv2_base_path}"
  402. "${lv2_base_path}/lv2"
  403. "${lv2_base_path}/serd"
  404. "${lv2_base_path}/sord"
  405. "${lv2_base_path}/sord/src"
  406. "${lv2_base_path}/sratom"
  407. "${lv2_base_path}/lilv"
  408. "${lv2_base_path}/lilv/src")
  409. target_link_libraries(juce_audio_processors INTERFACE juce_lilv_headers)
  410. add_library(juce_ara_headers INTERFACE)
  411. target_include_directories(juce_ara_headers INTERFACE
  412. "$<$<TARGET_EXISTS:juce_ara_sdk>:$<TARGET_PROPERTY:juce_ara_sdk,INTERFACE_INCLUDE_DIRECTORIES>>")
  413. target_link_libraries(juce_audio_processors INTERFACE juce_ara_headers)
  414. if(JUCE_ARG_ALIAS_NAMESPACE)
  415. add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_vst3_headers ALIAS juce_vst3_headers)
  416. add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_lilv_headers ALIAS juce_lilv_headers)
  417. add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_ara_headers ALIAS juce_ara_headers)
  418. endif()
  419. endif()
  420. target_include_directories(${module_name} INTERFACE ${base_path})
  421. target_compile_definitions(${module_name} INTERFACE JUCE_MODULE_AVAILABLE_${module_name}=1)
  422. if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
  423. target_compile_definitions(${module_name} INTERFACE LINUX=1)
  424. endif()
  425. if((${module_name} STREQUAL "juce_audio_devices") AND (CMAKE_SYSTEM_NAME STREQUAL "Android"))
  426. add_subdirectory("${module_path}/native/oboe")
  427. target_link_libraries(${module_name} INTERFACE oboe)
  428. endif()
  429. if((${module_name} STREQUAL "juce_opengl") AND (CMAKE_SYSTEM_NAME STREQUAL "Android"))
  430. set(platform_supports_gl3 0)
  431. if(CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL 18)
  432. set(platform_supports_gl3 1)
  433. endif()
  434. if(platform_supports_gl3)
  435. target_compile_definitions(${module_name} INTERFACE JUCE_ANDROID_GL_ES_VERSION_3_0=1)
  436. endif()
  437. target_link_libraries(${module_name} INTERFACE EGL $<IF:${platform_supports_gl3},GLESv3,GLESv2>)
  438. endif()
  439. _juce_extract_metadata_block(JUCE_MODULE_DECLARATION "${module_path}/${module_header_name}" metadata_dict)
  440. _juce_get_metadata("${metadata_dict}" minimumCppStandard module_cpp_standard)
  441. if(module_cpp_standard)
  442. target_compile_features(${module_name} INTERFACE cxx_std_${module_cpp_standard})
  443. else()
  444. target_compile_features(${module_name} INTERFACE cxx_std_11)
  445. endif()
  446. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  447. _juce_get_metadata("${metadata_dict}" OSXFrameworks module_osxframeworks)
  448. _juce_remove_empty_list_elements(module_osxframeworks)
  449. foreach(module_framework IN LISTS module_osxframeworks)
  450. _juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
  451. endforeach()
  452. _juce_get_metadata("${metadata_dict}" WeakOSXFrameworks module_weakosxframeworks)
  453. _juce_remove_empty_list_elements(module_weakosxframeworks)
  454. foreach(module_framework IN LISTS module_weakosxframeworks)
  455. _juce_link_frameworks("${module_name}" INTERFACE WEAK "${module_framework}")
  456. endforeach()
  457. _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" OSXLibs)
  458. elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
  459. _juce_get_metadata("${metadata_dict}" iOSFrameworks module_iosframeworks)
  460. _juce_remove_empty_list_elements(module_iosframeworks)
  461. foreach(module_framework IN LISTS module_iosframeworks)
  462. _juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
  463. endforeach()
  464. _juce_get_metadata("${metadata_dict}" WeakiOSFrameworks module_weakiosframeworks)
  465. _juce_remove_empty_list_elements(module_weakiosframeworks)
  466. foreach(module_framework IN LISTS module_weakiosframeworks)
  467. _juce_link_frameworks("${module_name}" INTERFACE WEAK "${module_framework}")
  468. endforeach()
  469. _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" iOSLibs)
  470. elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
  471. _juce_get_metadata("${metadata_dict}" linuxPackages module_linuxpackages)
  472. if(module_linuxpackages)
  473. _juce_create_pkgconfig_target(${module_name}_LINUX_DEPS ${module_linuxpackages})
  474. target_link_libraries(${module_name} INTERFACE juce::pkgconfig_${module_name}_LINUX_DEPS)
  475. endif()
  476. _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" linuxLibs)
  477. elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  478. if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
  479. if(module_name STREQUAL "juce_gui_basics")
  480. target_compile_options(${module_name} INTERFACE /bigobj)
  481. endif()
  482. _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" windowsLibs)
  483. elseif(MSYS OR MINGW)
  484. if(module_name STREQUAL "juce_gui_basics")
  485. target_compile_options(${module_name} INTERFACE "-Wa,-mbig-obj")
  486. endif()
  487. _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" mingwLibs)
  488. endif()
  489. endif()
  490. _juce_get_metadata("${metadata_dict}" dependencies module_dependencies)
  491. target_link_libraries(${module_name} INTERFACE ${module_dependencies})
  492. _juce_get_metadata("${metadata_dict}" searchpaths module_searchpaths)
  493. if(NOT module_searchpaths STREQUAL "")
  494. foreach(module_searchpath IN LISTS module_searchpaths)
  495. target_include_directories(${module_name}
  496. INTERFACE "${module_path}/${module_searchpath}")
  497. endforeach()
  498. endif()
  499. _juce_add_module_staticlib_paths("${module_name}" "${module_path}")
  500. if(JUCE_ARG_INSTALL_PATH)
  501. install(DIRECTORY "${module_path}" DESTINATION "${JUCE_ARG_INSTALL_PATH}")
  502. endif()
  503. if(JUCE_ARG_ALIAS_NAMESPACE)
  504. add_library(${JUCE_ARG_ALIAS_NAMESPACE}::${module_name} ALIAS ${module_name})
  505. endif()
  506. endfunction()
  507. function(juce_add_modules)
  508. set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
  509. cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
  510. foreach(path IN LISTS JUCE_ARG_UNPARSED_ARGUMENTS)
  511. juce_add_module(${path}
  512. INSTALL_PATH "${JUCE_ARG_INSTALL_PATH}"
  513. ALIAS_NAMESPACE "${JUCE_ARG_ALIAS_NAMESPACE}")
  514. endforeach()
  515. endfunction()
  516. # When source groups are enabled, this function sets the HEADER_FILE_ONLY property on any module
  517. # source files that should not be built. This is called automatically by the juce_add_* functions.
  518. function(_juce_fixup_module_source_groups)
  519. if(JUCE_ENABLE_MODULE_SOURCE_GROUPS)
  520. get_property(all_modules GLOBAL PROPERTY _juce_module_names)
  521. foreach(module_name IN LISTS all_modules)
  522. get_target_property(path ${module_name} INTERFACE_JUCE_MODULE_PATH)
  523. get_target_property(header_files ${module_name} INTERFACE_JUCE_MODULE_HEADERS)
  524. get_target_property(source_files ${module_name} INTERFACE_JUCE_MODULE_SOURCES)
  525. source_group(TREE ${path} PREFIX "JUCE Modules" FILES ${header_files} ${source_files})
  526. set_source_files_properties(${header_files} PROPERTIES HEADER_FILE_ONLY TRUE)
  527. endforeach()
  528. endif()
  529. endfunction()