ObsHelpers.cmake 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  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 ${OBS_DATA_DESTINATION}/${destination}
  140. COMPONENT obs_${target}
  141. EXCLUDE_FROM_ALL)
  142. endfunction()
  143. # Helper function to set up OBS app target
  144. function(setup_obs_app target)
  145. setup_binary_target(${target})
  146. get_property(OBS_MODULE_LIST GLOBAL PROPERTY OBS_MODULE_LIST)
  147. list(LENGTH OBS_MODULE_LIST _LEN)
  148. if(_LEN GREATER 0)
  149. add_dependencies(${target} ${OBS_MODULE_LIST})
  150. endif()
  151. get_property(OBS_SCRIPTING_MODULE_LIST GLOBAL
  152. PROPERTY OBS_SCRIPTING_MODULE_LIST)
  153. list(LENGTH OBS_SCRIPTING_MODULE_LIST _LEN)
  154. if(_LEN GREATER 0)
  155. add_dependencies(${target} ${OBS_SCRIPTING_MODULE_LIST})
  156. endif()
  157. # detect outdated obs-browser submodule
  158. if(NOT TARGET OBS::browser AND TARGET obs-browser)
  159. target_compile_features(obs-browser-page PRIVATE cxx_std_17)
  160. add_library(OBS::browser ALIAS obs-browser)
  161. if(NOT TARGET OBS::browser-panels AND BROWSER_PANEL_SUPPORT_ENABLED)
  162. add_library(OBS::browser-panels ALIAS obs-browser)
  163. endif()
  164. endif()
  165. if(TARGET OBS::browser)
  166. setup_target_browser(${target})
  167. endif()
  168. if(TARGET OBS::ffmpeg-mux)
  169. add_dependencies(${target} OBS::ffmpeg-mux)
  170. endif()
  171. add_custom_command(
  172. TARGET ${target}
  173. POST_BUILD
  174. COMMAND
  175. "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  176. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_rundir >
  177. "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  178. COMMENT "Installing OBS rundir"
  179. VERBATIM)
  180. endfunction()
  181. # Helper function to do additional setup for browser source plugin
  182. function(setup_target_browser target)
  183. install(
  184. DIRECTORY ${CEF_ROOT_DIR}/Resources/
  185. DESTINATION ${OBS_PLUGIN_DESTINATION}
  186. COMPONENT ${target}_Runtime)
  187. install(
  188. DIRECTORY ${CEF_ROOT_DIR}/Release/
  189. DESTINATION ${OBS_PLUGIN_DESTINATION}
  190. COMPONENT ${target}_Runtime)
  191. install(
  192. DIRECTORY ${CEF_ROOT_DIR}/Resources/
  193. DESTINATION ${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}
  194. COMPONENT obs_rundir
  195. EXCLUDE_FROM_ALL)
  196. install(
  197. DIRECTORY ${CEF_ROOT_DIR}/Release/
  198. DESTINATION ${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}
  199. COMPONENT obs_rundir
  200. EXCLUDE_FROM_ALL)
  201. endfunction()
  202. # Helper function to export target to build and install tree. Allows usage of
  203. # `find_package(libobs)` by other build trees
  204. function(export_target target)
  205. set(CMAKE_EXPORT_PACKAGE_REGISTRY OFF)
  206. install(
  207. TARGETS ${target}
  208. EXPORT ${target}Targets
  209. RUNTIME DESTINATION ${OBS_EXECUTABLE_DESTINATION} COMPONENT obs_libraries
  210. LIBRARY DESTINATION ${OBS_LIBRARY_DESTINATION} COMPONENT obs_libraries
  211. ARCHIVE DESTINATION ${OBS_LIBRARY_DESTINATION} COMPONENT obs_libraries
  212. INCLUDES
  213. DESTINATION ${OBS_INCLUDE_DESTINATION}
  214. PUBLIC_HEADER
  215. DESTINATION ${OBS_INCLUDE_DESTINATION}
  216. COMPONENT obs_libraries
  217. EXCLUDE_FROM_ALL)
  218. include(GenerateExportHeader)
  219. generate_export_header(${target} EXPORT_FILE_NAME
  220. ${CMAKE_CURRENT_BINARY_DIR}/${target}_EXPORT.h)
  221. target_sources(${target}
  222. PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${target}_EXPORT.h)
  223. set(TARGETS_EXPORT_NAME "${target}Targets")
  224. include(CMakePackageConfigHelpers)
  225. configure_package_config_file(
  226. ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${target}Config.cmake.in
  227. ${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_FROM_ALL)
  246. install(
  247. FILES ${CMAKE_CURRENT_BINARY_DIR}/${target}Config.cmake
  248. ${CMAKE_CURRENT_BINARY_DIR}/${target}ConfigVersion.cmake
  249. DESTINATION ${OBS_CMAKE_DESTINATION}/${target}
  250. COMPONENT obs_libraries
  251. EXCLUDE_FROM_ALL)
  252. endfunction()
  253. # Helper function to define available graphics modules for targets
  254. function(define_graphic_modules target)
  255. foreach(_GRAPHICS_API metal d3d11 opengl d3d9)
  256. string(TOUPPER ${_GRAPHICS_API} _GRAPHICS_API_u)
  257. if(TARGET OBS::libobs-${_GRAPHICS_API})
  258. if(OS_POSIX AND NOT LINUX_PORTABLE)
  259. target_compile_definitions(
  260. ${target}
  261. PRIVATE
  262. DL_${_GRAPHICS_API_u}="$<TARGET_SONAME_FILE_NAME:libobs-${_GRAPHICS_API}>"
  263. )
  264. else()
  265. target_compile_definitions(
  266. ${target}
  267. PRIVATE
  268. DL_${_GRAPHICS_API_u}="$<TARGET_FILE_NAME:libobs-${_GRAPHICS_API}>")
  269. endif()
  270. add_dependencies(${target} OBS::libobs-${_GRAPHICS_API})
  271. else()
  272. target_compile_definitions(${target} PRIVATE DL_${_GRAPHICS_API_u}="")
  273. endif()
  274. endforeach()
  275. endfunction()
  276. macro(find_qt)
  277. set(oneValueArgs VERSION)
  278. set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX)
  279. cmake_parse_arguments(FIND_QT "" "${oneValueArgs}" "${multiValueArgs}"
  280. ${ARGN})
  281. if(OS_WINDOWS)
  282. find_package(
  283. Qt${FIND_QT_VERSION}
  284. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_WIN}
  285. REQUIRED)
  286. elseif(OS_MACOS)
  287. find_package(
  288. Qt${FIND_QT_VERSION}
  289. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_MAC}
  290. REQUIRED)
  291. else()
  292. find_package(
  293. Qt${FIND_QT_VERSION}
  294. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_LINUX}
  295. REQUIRED)
  296. endif()
  297. foreach(_COMPONENT IN LISTS FIND_QT_COMPONENTS FIND_QT_COMPONENTS_WIN
  298. FIND_QT_COMPONENTS_MAC FIND_QT_COMPONENTS_LINUX)
  299. if(NOT TARGET Qt::${_COMPONENT} AND TARGET
  300. Qt${FIND_QT_VERSION}::${_COMPONENT})
  301. add_library(Qt::${_COMPONENT} INTERFACE IMPORTED)
  302. set_target_properties(
  303. Qt::${_COMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES
  304. "Qt${FIND_QT_VERSION}::${_COMPONENT}")
  305. endif()
  306. endforeach()
  307. endmacro()
  308. # Idea adapted from: https://github.com/edsiper/cmake-options
  309. macro(set_option option value)
  310. set(${option}
  311. ${value}
  312. CACHE INTERNAL "")
  313. endmacro()
  314. function(obs_status status text)
  315. set(_OBS_STATUS_DISABLED "OBS: DISABLED ")
  316. set(_OBS_STATUS_ENABLED "OBS: ENABLED ")
  317. set(_OBS_STATUS "OBS: ")
  318. if(status STREQUAL "DISABLED")
  319. message(STATUS "${_OBS_STATUS_DISABLED}${text}")
  320. elseif(status STREQUAL "ENABLED")
  321. message(STATUS "${_OBS_STATUS_ENABLED}${text}")
  322. else()
  323. message(${status} "${_OBS_STATUS}${text}")
  324. endif()
  325. endfunction()
  326. if(OS_WINDOWS)
  327. include(ObsHelpers_Windows)
  328. elseif(OS_MACOS)
  329. include(ObsHelpers_macOS)
  330. elseif(OS_POSIX)
  331. include(ObsHelpers_Linux)
  332. endif()
  333. # ##############################################################################
  334. # LEGACY FALLBACKS #
  335. # ##############################################################################
  336. # Helper function to install OBS plugin with associated resource directory
  337. function(_install_obs_plugin_with_data target source)
  338. setup_plugin_target(${target})
  339. if(NOT ${source} STREQUAL "data"
  340. AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${source}"
  341. AND NOT OS_MACOS)
  342. install(
  343. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  344. DESTINATION ${OBS_DATA_DESTINATION}/obs-plugins/${target}
  345. USE_SOURCE_PERMISSIONS
  346. COMPONENT ${target}_Runtime)
  347. install(
  348. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  349. DESTINATION
  350. ${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_DATA_DESTINATION}/obs-plugins/${target}
  351. COMPONENT obs_${target}
  352. EXCLUDE_FROM_ALL)
  353. if(OS_WINDOWS AND DEFINED ENV{obsInstallerTempDir})
  354. install(
  355. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  356. DESTINATION
  357. $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/obs-plugins/${target}
  358. COMPONENT obs_${target}
  359. EXCLUDE_FROM_ALL)
  360. endif()
  361. endif()
  362. endfunction()
  363. # Helper function to install OBS plugin
  364. function(_install_obs_plugin target)
  365. setup_plugin_target(${target})
  366. endfunction()
  367. # Helper function to install data for a target only
  368. function(_install_obs_datatarget target destination)
  369. install(
  370. TARGETS ${target}
  371. LIBRARY DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  372. COMPONENT ${target}_Runtime
  373. NAMELINK_COMPONENT ${target}_Development
  374. RUNTIME DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  375. COMPONENT ${target}_Runtime)
  376. install(
  377. TARGETS ${target}
  378. LIBRARY DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  379. COMPONENT obs_${target}
  380. RUNTIME DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  381. COMPONENT obs_${target}
  382. EXCLUDE_FROM_ALL)
  383. if(OS_WINDOWS)
  384. if(MSVC)
  385. add_target_resource(${target} "$<TARGET_PDB_FILE:${target}>"
  386. "${destination}" OPTIONAL)
  387. endif()
  388. if(DEFINED ENV{obsInstallerTempDir})
  389. install(
  390. TARGETS ${target}
  391. RUNTIME
  392. DESTINATION
  393. $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${destination}/$<TARGET_FILE_NAME:${target}>
  394. LIBRARY
  395. DESTINATION
  396. $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${destination}/$<TARGET_FILE_NAME:${target}>
  397. COMPONENT obs_${target}
  398. EXCLUDE_FROM_ALL)
  399. endif()
  400. endif()
  401. add_custom_command(
  402. TARGET ${target}
  403. POST_BUILD
  404. COMMAND
  405. "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  406. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${target} >
  407. "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  408. COMMENT "Installing ${target} to OBS rundir"
  409. VERBATIM)
  410. endfunction()