ObsHelpers.cmake 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. # Set OS-specific constants in non-deprecated way
  2. include(GNUInstallDirs)
  3. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
  4. include(ObsDefaults_macOS)
  5. set(OS_MACOS ON)
  6. set(OS_POSIX ON)
  7. elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD")
  8. include(ObsDefaults_Linux)
  9. set(OS_POSIX ON)
  10. string(TOUPPER "${CMAKE_SYSTEM_NAME}" _SYSTEM_NAME_U)
  11. set(OS_${_SYSTEM_NAME_U} ON)
  12. elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  13. include(ObsDefaults_Windows)
  14. set(OS_WINDOWS ON)
  15. set(OS_POSIX OFF)
  16. endif()
  17. # Create global property to hold list of activated modules
  18. set_property(GLOBAL PROPERTY OBS_MODULE_LIST "")
  19. # ######################################################################################################################
  20. # GLOBAL HELPER FUNCTIONS #
  21. # ######################################################################################################################
  22. # Helper function to set up runtime or library targets
  23. function(setup_binary_target target)
  24. # Set up installation paths for program install
  25. install(
  26. TARGETS ${target}
  27. RUNTIME DESTINATION ${OBS_EXECUTABLE_DESTINATION} COMPONENT ${target}_Runtime
  28. LIBRARY DESTINATION ${OBS_LIBRARY_DESTINATION}
  29. COMPONENT ${target}_Runtime
  30. NAMELINK_COMPONENT ${target}_Development
  31. ARCHIVE DESTINATION ${OBS_LIBRARY_DESTINATION} COMPONENT ${target}_Development
  32. PUBLIC_HEADER
  33. DESTINATION ${OBS_INCLUDE_DESTINATION}
  34. COMPONENT ${target}_Development
  35. EXCLUDE_FROM_ALL)
  36. # Set up installation paths for development rundir
  37. install(
  38. TARGETS ${target}
  39. RUNTIME DESTINATION ${OBS_EXECUTABLE_DESTINATION}
  40. COMPONENT obs_${target}
  41. EXCLUDE_FROM_ALL
  42. LIBRARY DESTINATION ${OBS_LIBRARY_DESTINATION}
  43. COMPONENT obs_${target}
  44. EXCLUDE_FROM_ALL
  45. PUBLIC_HEADER
  46. DESTINATION ${OBS_INCLUDE_DESTINATION}
  47. COMPONENT IGNORED
  48. EXCLUDE_FROM_ALL)
  49. add_custom_command(
  50. TARGET ${target}
  51. POST_BUILD
  52. COMMAND "${CMAKE_COMMAND}" -E env DESTDIR= "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  53. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${target} > "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  54. COMMENT "Installing OBS rundir"
  55. VERBATIM)
  56. endfunction()
  57. # Helper function to set up OBS plugin targets
  58. function(setup_plugin_target target)
  59. set_target_properties(${target} PROPERTIES PREFIX "")
  60. install(
  61. TARGETS ${target}
  62. RUNTIME DESTINATION ${OBS_PLUGIN_DESTINATION} COMPONENT ${target}_Runtime
  63. LIBRARY DESTINATION ${OBS_PLUGIN_DESTINATION}
  64. COMPONENT ${target}_Runtime
  65. NAMELINK_COMPONENT ${target}_Development)
  66. install(
  67. TARGETS ${target}
  68. RUNTIME DESTINATION ${OBS_PLUGIN_DESTINATION}
  69. COMPONENT obs_${target}
  70. EXCLUDE_FROM_ALL
  71. LIBRARY DESTINATION ${OBS_PLUGIN_DESTINATION}
  72. COMPONENT obs_${target}
  73. EXCLUDE_FROM_ALL)
  74. setup_target_resources("${target}" "obs-plugins/${target}")
  75. set_property(GLOBAL APPEND PROPERTY OBS_MODULE_LIST "${target}")
  76. add_custom_command(
  77. TARGET ${target}
  78. POST_BUILD
  79. COMMAND "${CMAKE_COMMAND}" -E env DESTDIR= "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  80. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${target} > "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  81. COMMENT "Installing ${target} to OBS rundir"
  82. VERBATIM)
  83. obs_status(ENABLED "${target}")
  84. endfunction()
  85. # Helper function to set up OBS scripting plugin targets
  86. function(setup_script_plugin_target target)
  87. install(
  88. TARGETS ${target}
  89. LIBRARY DESTINATION ${OBS_SCRIPT_PLUGIN_DESTINATION}
  90. COMPONENT ${target}_Runtime
  91. NAMELINK_COMPONENT ${target}_Development)
  92. install(
  93. TARGETS ${target}
  94. LIBRARY DESTINATION ${OBS_SCRIPT_PLUGIN_DESTINATION}
  95. COMPONENT obs_${target}
  96. EXCLUDE_FROM_ALL)
  97. if(${target} STREQUAL "obspython")
  98. install(
  99. FILES "$<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.py"
  100. DESTINATION ${OBS_SCRIPT_PLUGIN_DESTINATION}
  101. COMPONENT ${target}_Runtime)
  102. install(
  103. FILES "$<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_BASE_NAME:${target}>.py"
  104. DESTINATION ${OBS_SCRIPT_PLUGIN_DESTINATION}
  105. COMPONENT obs_${target}
  106. EXCLUDE_FROM_ALL)
  107. endif()
  108. set_property(GLOBAL APPEND PROPERTY OBS_SCRIPTING_MODULE_LIST "${target}")
  109. add_custom_command(
  110. TARGET ${target}
  111. POST_BUILD
  112. COMMAND "${CMAKE_COMMAND}" -E env DESTDIR= "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  113. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${target} > "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  114. COMMENT "Installing ${target} to OBS rundir"
  115. VERBATIM)
  116. obs_status(ENABLED "${target}")
  117. endfunction()
  118. # Helper function to set up target resources (e.g. L10N files)
  119. function(setup_target_resources target destination)
  120. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data")
  121. install(
  122. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/
  123. DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  124. USE_SOURCE_PERMISSIONS
  125. COMPONENT ${target}_Runtime)
  126. install(
  127. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/
  128. DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  129. USE_SOURCE_PERMISSIONS
  130. COMPONENT obs_${target}
  131. EXCLUDE_FROM_ALL)
  132. endif()
  133. endfunction()
  134. # Helper function to set up specific resource files for targets
  135. function(add_target_resource target resource destination)
  136. install(
  137. FILES ${resource}
  138. DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  139. COMPONENT ${target}_Runtime)
  140. install(
  141. FILES ${resource}
  142. DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  143. COMPONENT obs_${target}
  144. EXCLUDE_FROM_ALL)
  145. endfunction()
  146. # Helper function to set up OBS app target
  147. function(setup_obs_app target)
  148. setup_binary_target(${target})
  149. get_property(OBS_MODULE_LIST GLOBAL PROPERTY OBS_MODULE_LIST)
  150. list(LENGTH OBS_MODULE_LIST _LEN)
  151. if(_LEN GREATER 0)
  152. add_dependencies(${target} ${OBS_MODULE_LIST})
  153. endif()
  154. get_property(OBS_SCRIPTING_MODULE_LIST GLOBAL PROPERTY OBS_SCRIPTING_MODULE_LIST)
  155. list(LENGTH OBS_SCRIPTING_MODULE_LIST _LEN)
  156. if(_LEN GREATER 0)
  157. add_dependencies(${target} ${OBS_SCRIPTING_MODULE_LIST})
  158. endif()
  159. if(TARGET OBS::browser)
  160. setup_target_browser(${target})
  161. endif()
  162. if(TARGET OBS::ffmpeg-mux)
  163. add_dependencies(${target} OBS::ffmpeg-mux)
  164. endif()
  165. add_custom_command(
  166. TARGET ${target}
  167. POST_BUILD
  168. COMMAND "${CMAKE_COMMAND}" -E env DESTDIR= "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  169. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_rundir > "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  170. COMMENT "Installing OBS rundir"
  171. VERBATIM)
  172. endfunction()
  173. # Helper function to do additional setup for browser source plugin
  174. function(setup_target_browser target)
  175. install(
  176. DIRECTORY ${CEF_ROOT_DIR}/Resources/
  177. DESTINATION ${OBS_PLUGIN_DESTINATION}
  178. COMPONENT ${target}_Runtime)
  179. install(
  180. DIRECTORY ${CEF_ROOT_DIR}/Release/
  181. DESTINATION ${OBS_PLUGIN_DESTINATION}
  182. COMPONENT ${target}_Runtime)
  183. install(
  184. DIRECTORY ${CEF_ROOT_DIR}/Resources/
  185. DESTINATION ${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}
  186. COMPONENT obs_rundir
  187. EXCLUDE_FROM_ALL)
  188. install(
  189. DIRECTORY ${CEF_ROOT_DIR}/Release/
  190. DESTINATION ${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}
  191. COMPONENT obs_rundir
  192. EXCLUDE_FROM_ALL)
  193. endfunction()
  194. # Helper function to export target to build and install tree. Allows usage of `find_package(libobs)` by other build
  195. # trees
  196. function(export_target target)
  197. set(CMAKE_EXPORT_PACKAGE_REGISTRY OFF)
  198. if(OS_LINUX OR OS_FREEBSD)
  199. set(_EXCLUDE "")
  200. else()
  201. set(_EXCLUDE "EXCLUDE_FROM_ALL")
  202. endif()
  203. install(
  204. TARGETS ${target}
  205. EXPORT ${target}Targets
  206. RUNTIME DESTINATION ${OBS_EXECUTABLE_DESTINATION}
  207. COMPONENT obs_libraries
  208. ${_EXCLUDE}
  209. LIBRARY DESTINATION ${OBS_LIBRARY_DESTINATION}
  210. COMPONENT obs_libraries
  211. ${_EXCLUDE}
  212. ARCHIVE DESTINATION ${OBS_LIBRARY_DESTINATION}
  213. COMPONENT obs_libraries
  214. ${_EXCLUDE}
  215. INCLUDES
  216. DESTINATION ${OBS_INCLUDE_DESTINATION}
  217. PUBLIC_HEADER
  218. DESTINATION ${OBS_INCLUDE_DESTINATION}
  219. COMPONENT obs_libraries
  220. ${_EXCLUDE})
  221. include(GenerateExportHeader)
  222. generate_export_header(${target} EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/${target}_EXPORT.h)
  223. target_sources(${target} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${target}_EXPORT.h)
  224. set(TARGETS_EXPORT_NAME "${target}Targets")
  225. include(CMakePackageConfigHelpers)
  226. configure_package_config_file(
  227. ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${target}Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${target}Config.cmake
  228. INSTALL_DESTINATION ${OBS_CMAKE_DESTINATION}/${target}
  229. PATH_VARS OBS_PLUGIN_DESTINATION OBS_DATA_DESTINATION)
  230. write_basic_package_version_file(
  231. ${CMAKE_CURRENT_BINARY_DIR}/${target}ConfigVersion.cmake
  232. VERSION ${OBS_VERSION_CANONICAL}
  233. COMPATIBILITY SameMajorVersion)
  234. export(
  235. EXPORT ${target}Targets
  236. FILE ${CMAKE_CURRENT_BINARY_DIR}/${TARGETS_EXPORT_NAME}.cmake
  237. NAMESPACE OBS::)
  238. export(PACKAGE "${target}")
  239. install(
  240. EXPORT ${TARGETS_EXPORT_NAME}
  241. FILE ${TARGETS_EXPORT_NAME}.cmake
  242. NAMESPACE OBS::
  243. DESTINATION ${OBS_CMAKE_DESTINATION}/${target}
  244. COMPONENT obs_libraries
  245. ${_EXCLUDE})
  246. install(
  247. FILES ${CMAKE_CURRENT_BINARY_DIR}/${target}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${target}ConfigVersion.cmake
  248. DESTINATION ${OBS_CMAKE_DESTINATION}/${target}
  249. COMPONENT obs_libraries
  250. ${_EXCLUDE})
  251. endfunction()
  252. # Helper function to define available graphics modules for targets
  253. function(define_graphic_modules target)
  254. foreach(_GRAPHICS_API metal d3d11 opengl d3d9)
  255. string(TOUPPER ${_GRAPHICS_API} _GRAPHICS_API_u)
  256. if(TARGET OBS::libobs-${_GRAPHICS_API})
  257. if(OS_POSIX AND NOT LINUX_PORTABLE)
  258. target_compile_definitions(${target}
  259. PRIVATE DL_${_GRAPHICS_API_u}="$<TARGET_SONAME_FILE_NAME:libobs-${_GRAPHICS_API}>")
  260. else()
  261. target_compile_definitions(${target}
  262. PRIVATE DL_${_GRAPHICS_API_u}="$<TARGET_FILE_NAME:libobs-${_GRAPHICS_API}>")
  263. endif()
  264. add_dependencies(${target} OBS::libobs-${_GRAPHICS_API})
  265. else()
  266. target_compile_definitions(${target} PRIVATE DL_${_GRAPHICS_API_u}="")
  267. endif()
  268. endforeach()
  269. endfunction()
  270. macro(find_qt)
  271. set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX)
  272. cmake_parse_arguments(FIND_QT "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  273. set(QT_NO_CREATE_VERSIONLESS_TARGETS ON)
  274. find_package(
  275. Qt6
  276. COMPONENTS Core
  277. REQUIRED)
  278. set(QT_NO_CREATE_VERSIONLESS_TARGETS OFF)
  279. if(OS_WINDOWS)
  280. find_package(
  281. Qt6
  282. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_WIN}
  283. REQUIRED)
  284. elseif(OS_MACOS)
  285. find_package(
  286. Qt6
  287. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_MAC}
  288. REQUIRED)
  289. else()
  290. find_package(
  291. Qt6
  292. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_LINUX}
  293. REQUIRED)
  294. endif()
  295. list(APPEND FIND_QT_COMPONENTS "Core")
  296. if("Gui" IN_LIST FIND_QT_COMPONENTS_LINUX)
  297. list(APPEND FIND_QT_COMPONENTS_LINUX "GuiPrivate")
  298. endif()
  299. foreach(_COMPONENT IN LISTS FIND_QT_COMPONENTS FIND_QT_COMPONENTS_WIN FIND_QT_COMPONENTS_MAC FIND_QT_COMPONENTS_LINUX)
  300. if(NOT TARGET Qt::${_COMPONENT} AND TARGET Qt6::${_COMPONENT})
  301. add_library(Qt::${_COMPONENT} INTERFACE IMPORTED)
  302. set_target_properties(Qt::${_COMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES "Qt6::${_COMPONENT}")
  303. endif()
  304. endforeach()
  305. endmacro()
  306. # Idea adapted from: https://github.com/edsiper/cmake-options
  307. macro(set_option option value)
  308. set(${option}
  309. ${value}
  310. CACHE INTERNAL "")
  311. endmacro()
  312. function(obs_status status text)
  313. set(_OBS_STATUS_DISABLED "OBS: DISABLED ")
  314. set(_OBS_STATUS_ENABLED "OBS: ENABLED ")
  315. set(_OBS_STATUS "OBS: ")
  316. if(status STREQUAL "DISABLED")
  317. message(STATUS "${_OBS_STATUS_DISABLED}${text}")
  318. elseif(status STREQUAL "ENABLED")
  319. message(STATUS "${_OBS_STATUS_ENABLED}${text}")
  320. else()
  321. message(${status} "${_OBS_STATUS}${text}")
  322. endif()
  323. endfunction()
  324. if(OS_WINDOWS)
  325. include(ObsHelpers_Windows)
  326. elseif(OS_MACOS)
  327. include(ObsHelpers_macOS)
  328. elseif(OS_POSIX)
  329. include(ObsHelpers_Linux)
  330. endif()
  331. # ######################################################################################################################
  332. # LEGACY FALLBACKS #
  333. # ######################################################################################################################
  334. # Helper function to install OBS plugin with associated resource directory
  335. function(_install_obs_plugin_with_data target source)
  336. setup_plugin_target(${target})
  337. if(NOT ${source} STREQUAL "data"
  338. AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${source}"
  339. AND NOT OS_MACOS)
  340. install(
  341. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  342. DESTINATION ${OBS_DATA_DESTINATION}/obs-plugins/${target}
  343. USE_SOURCE_PERMISSIONS
  344. COMPONENT ${target}_Runtime)
  345. install(
  346. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  347. DESTINATION ${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_DATA_DESTINATION}/obs-plugins/${target}
  348. COMPONENT obs_${target}
  349. EXCLUDE_FROM_ALL)
  350. if(OS_WINDOWS AND DEFINED ENV{obsInstallerTempDir})
  351. install(
  352. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  353. DESTINATION $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/obs-plugins/${target}
  354. COMPONENT obs_${target}
  355. EXCLUDE_FROM_ALL)
  356. endif()
  357. endif()
  358. endfunction()
  359. # Helper function to install OBS plugin
  360. function(_install_obs_plugin target)
  361. setup_plugin_target(${target})
  362. endfunction()
  363. # Helper function to install data for a target only
  364. function(_install_obs_datatarget target destination)
  365. install(
  366. TARGETS ${target}
  367. LIBRARY DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  368. COMPONENT ${target}_Runtime
  369. NAMELINK_COMPONENT ${target}_Development
  370. RUNTIME DESTINATION ${OBS_DATA_DESTINATION}/${destination} COMPONENT ${target}_Runtime)
  371. install(
  372. TARGETS ${target}
  373. LIBRARY DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  374. COMPONENT obs_${target}
  375. EXCLUDE_FROM_ALL
  376. RUNTIME DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  377. COMPONENT obs_${target}
  378. EXCLUDE_FROM_ALL)
  379. if(OS_WINDOWS)
  380. if(MSVC)
  381. add_target_resource(${target} "$<TARGET_PDB_FILE:${target}>" "${destination}" OPTIONAL)
  382. endif()
  383. if(DEFINED ENV{obsInstallerTempDir})
  384. install(
  385. TARGETS ${target}
  386. RUNTIME
  387. DESTINATION $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${destination}/$<TARGET_FILE_NAME:${target}>
  388. COMPONENT obs_${target}
  389. EXCLUDE_FROM_ALL
  390. LIBRARY
  391. DESTINATION $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${destination}/$<TARGET_FILE_NAME:${target}>
  392. COMPONENT obs_${target}
  393. EXCLUDE_FROM_ALL)
  394. endif()
  395. endif()
  396. add_custom_command(
  397. TARGET ${target}
  398. POST_BUILD
  399. COMMAND "${CMAKE_COMMAND}" -E env DESTDIR= "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  400. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${target} > "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  401. COMMENT "Installing ${target} to OBS rundir"
  402. VERBATIM)
  403. endfunction()
  404. # legacy_check: Macro to check for CMake framework version and include legacy list file
  405. macro(legacy_check)
  406. if(OBS_CMAKE_VERSION VERSION_LESS 3.0.0)
  407. if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cmake/legacy.cmake)
  408. include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/legacy.cmake)
  409. endif()
  410. return()
  411. endif()
  412. endmacro()