ObsHelpers.cmake 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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. get_target_property(target_type ${target} TYPE)
  222. if(NOT target_type STREQUAL INTERFACE_LIBRARY)
  223. include(GenerateExportHeader)
  224. generate_export_header(${target} EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/${target}_EXPORT.h)
  225. target_sources(${target} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${target}_EXPORT.h)
  226. endif()
  227. set(TARGETS_EXPORT_NAME "${target}Targets")
  228. include(CMakePackageConfigHelpers)
  229. configure_package_config_file(
  230. ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${target}Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${target}Config.cmake
  231. INSTALL_DESTINATION ${OBS_CMAKE_DESTINATION}/${target}
  232. PATH_VARS OBS_PLUGIN_DESTINATION OBS_DATA_DESTINATION)
  233. write_basic_package_version_file(
  234. ${CMAKE_CURRENT_BINARY_DIR}/${target}ConfigVersion.cmake
  235. VERSION ${OBS_VERSION_CANONICAL}
  236. COMPATIBILITY SameMajorVersion)
  237. export(
  238. EXPORT ${target}Targets
  239. FILE ${CMAKE_CURRENT_BINARY_DIR}/${TARGETS_EXPORT_NAME}.cmake
  240. NAMESPACE OBS::)
  241. export(PACKAGE "${target}")
  242. install(
  243. EXPORT ${TARGETS_EXPORT_NAME}
  244. FILE ${TARGETS_EXPORT_NAME}.cmake
  245. NAMESPACE OBS::
  246. DESTINATION ${OBS_CMAKE_DESTINATION}/${target}
  247. COMPONENT obs_libraries
  248. ${_EXCLUDE})
  249. install(
  250. FILES ${CMAKE_CURRENT_BINARY_DIR}/${target}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${target}ConfigVersion.cmake
  251. DESTINATION ${OBS_CMAKE_DESTINATION}/${target}
  252. COMPONENT obs_libraries
  253. ${_EXCLUDE})
  254. endfunction()
  255. # Helper function to define available graphics modules for targets
  256. function(define_graphic_modules target)
  257. foreach(_GRAPHICS_API metal d3d11 opengl d3d9)
  258. string(TOUPPER ${_GRAPHICS_API} _GRAPHICS_API_u)
  259. if(TARGET OBS::libobs-${_GRAPHICS_API})
  260. if(OS_POSIX AND NOT LINUX_PORTABLE)
  261. target_compile_definitions(${target}
  262. PRIVATE DL_${_GRAPHICS_API_u}="$<TARGET_SONAME_FILE_NAME:libobs-${_GRAPHICS_API}>")
  263. else()
  264. target_compile_definitions(${target}
  265. PRIVATE DL_${_GRAPHICS_API_u}="$<TARGET_FILE_NAME:libobs-${_GRAPHICS_API}>")
  266. endif()
  267. add_dependencies(${target} OBS::libobs-${_GRAPHICS_API})
  268. else()
  269. target_compile_definitions(${target} PRIVATE DL_${_GRAPHICS_API_u}="")
  270. endif()
  271. endforeach()
  272. endfunction()
  273. macro(find_qt)
  274. set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX)
  275. cmake_parse_arguments(FIND_QT "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  276. set(QT_NO_CREATE_VERSIONLESS_TARGETS ON)
  277. find_package(
  278. Qt6
  279. COMPONENTS Core
  280. REQUIRED)
  281. set(QT_NO_CREATE_VERSIONLESS_TARGETS OFF)
  282. if(OS_WINDOWS)
  283. find_package(
  284. Qt6
  285. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_WIN}
  286. REQUIRED)
  287. elseif(OS_MACOS)
  288. find_package(
  289. Qt6
  290. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_MAC}
  291. REQUIRED)
  292. else()
  293. find_package(
  294. Qt6
  295. COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_LINUX}
  296. REQUIRED)
  297. endif()
  298. list(APPEND FIND_QT_COMPONENTS "Core")
  299. if("Gui" IN_LIST FIND_QT_COMPONENTS_LINUX)
  300. list(APPEND FIND_QT_COMPONENTS_LINUX "GuiPrivate")
  301. endif()
  302. foreach(_COMPONENT IN LISTS FIND_QT_COMPONENTS FIND_QT_COMPONENTS_WIN FIND_QT_COMPONENTS_MAC FIND_QT_COMPONENTS_LINUX)
  303. if(NOT TARGET Qt::${_COMPONENT} AND TARGET Qt6::${_COMPONENT})
  304. add_library(Qt::${_COMPONENT} INTERFACE IMPORTED)
  305. set_target_properties(Qt::${_COMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES "Qt6::${_COMPONENT}")
  306. endif()
  307. endforeach()
  308. endmacro()
  309. # Idea adapted from: https://github.com/edsiper/cmake-options
  310. macro(set_option option value)
  311. set(${option}
  312. ${value}
  313. CACHE INTERNAL "")
  314. endmacro()
  315. function(obs_status status text)
  316. set(_OBS_STATUS_DISABLED "OBS: DISABLED ")
  317. set(_OBS_STATUS_ENABLED "OBS: ENABLED ")
  318. set(_OBS_STATUS "OBS: ")
  319. if(status STREQUAL "DISABLED")
  320. message(STATUS "${_OBS_STATUS_DISABLED}${text}")
  321. elseif(status STREQUAL "ENABLED")
  322. message(STATUS "${_OBS_STATUS_ENABLED}${text}")
  323. else()
  324. message(${status} "${_OBS_STATUS}${text}")
  325. endif()
  326. endfunction()
  327. if(OS_WINDOWS)
  328. include(ObsHelpers_Windows)
  329. elseif(OS_MACOS)
  330. include(ObsHelpers_macOS)
  331. elseif(OS_POSIX)
  332. include(ObsHelpers_Linux)
  333. endif()
  334. # ######################################################################################################################
  335. # LEGACY FALLBACKS #
  336. # ######################################################################################################################
  337. # Helper function to install OBS plugin with associated resource directory
  338. function(_install_obs_plugin_with_data target source)
  339. setup_plugin_target(${target})
  340. if(NOT ${source} STREQUAL "data"
  341. AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${source}"
  342. AND NOT OS_MACOS)
  343. install(
  344. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  345. DESTINATION ${OBS_DATA_DESTINATION}/obs-plugins/${target}
  346. USE_SOURCE_PERMISSIONS
  347. COMPONENT ${target}_Runtime)
  348. install(
  349. DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${source}/
  350. DESTINATION ${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 $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/obs-plugins/${target}
  357. COMPONENT obs_${target}
  358. EXCLUDE_FROM_ALL)
  359. endif()
  360. endif()
  361. endfunction()
  362. # Helper function to install OBS plugin
  363. function(_install_obs_plugin target)
  364. setup_plugin_target(${target})
  365. endfunction()
  366. # Helper function to install data for a target only
  367. function(_install_obs_datatarget target destination)
  368. install(
  369. TARGETS ${target}
  370. LIBRARY DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  371. COMPONENT ${target}_Runtime
  372. NAMELINK_COMPONENT ${target}_Development
  373. RUNTIME DESTINATION ${OBS_DATA_DESTINATION}/${destination} COMPONENT ${target}_Runtime)
  374. install(
  375. TARGETS ${target}
  376. LIBRARY DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  377. COMPONENT obs_${target}
  378. EXCLUDE_FROM_ALL
  379. RUNTIME DESTINATION ${OBS_DATA_DESTINATION}/${destination}
  380. COMPONENT obs_${target}
  381. EXCLUDE_FROM_ALL)
  382. if(OS_WINDOWS)
  383. if(MSVC)
  384. add_target_resource(${target} "$<TARGET_PDB_FILE:${target}>" "${destination}" OPTIONAL)
  385. endif()
  386. if(DEFINED ENV{obsInstallerTempDir})
  387. install(
  388. TARGETS ${target}
  389. RUNTIME
  390. DESTINATION $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${destination}/$<TARGET_FILE_NAME:${target}>
  391. COMPONENT obs_${target}
  392. EXCLUDE_FROM_ALL
  393. LIBRARY
  394. DESTINATION $ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${destination}/$<TARGET_FILE_NAME:${target}>
  395. COMPONENT obs_${target}
  396. EXCLUDE_FROM_ALL)
  397. endif()
  398. endif()
  399. add_custom_command(
  400. TARGET ${target}
  401. POST_BUILD
  402. COMMAND "${CMAKE_COMMAND}" -E env DESTDIR= "${CMAKE_COMMAND}" --install .. --config $<CONFIG> --prefix
  403. ${OBS_OUTPUT_DIR}/$<CONFIG> --component obs_${target} > "$<IF:$<PLATFORM_ID:Windows>,nul,/dev/null>"
  404. COMMENT "Installing ${target} to OBS rundir"
  405. VERBATIM)
  406. endfunction()
  407. # legacy_check: Macro to check for CMake framework version and include legacy list file
  408. macro(legacy_check)
  409. if(OBS_CMAKE_VERSION VERSION_LESS 3.0.0)
  410. if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cmake/legacy.cmake)
  411. include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/legacy.cmake)
  412. endif()
  413. return()
  414. endif()
  415. endmacro()