ObsHelpers.cmake 15 KB

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