ObsHelpers.cmake 15 KB

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