ObsPluginHelpers.cmake 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. if(POLICY CMP0087)
  2. cmake_policy(SET CMP0087 NEW)
  3. endif()
  4. set(OBS_STANDALONE_PLUGIN_DIR "${CMAKE_SOURCE_DIR}/release")
  5. include(GNUInstallDirs)
  6. if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
  7. set(OS_MACOS ON)
  8. set(OS_POSIX ON)
  9. elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux|FreeBSD|OpenBSD")
  10. set(OS_POSIX ON)
  11. string(TOUPPER "${CMAKE_SYSTEM_NAME}" _SYSTEM_NAME_U)
  12. set(OS_${_SYSTEM_NAME_U} ON)
  13. elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  14. set(OS_WINDOWS ON)
  15. set(OS_POSIX OFF)
  16. endif()
  17. # Old-Style plugin detected, find "modern" libobs variant instead and set global
  18. # include directories to fix "bad" plugin behavior
  19. if(DEFINED LIBOBS_INCLUDE_DIR AND NOT TARGET OBS::libobs)
  20. message(
  21. DEPRECATION
  22. "You are using an outdated method of adding 'libobs' to your project. Refer to the updated wiki on how to build and export 'libobs' and use it in your plugin projects."
  23. )
  24. find_package(libobs REQUIRED)
  25. if(TARGET OBS::libobs)
  26. set_target_properties(OBS::libobs PROPERTIES IMPORTED_GLOBAL TRUE)
  27. message(STATUS "OBS: Using modern libobs target")
  28. add_library(libobs ALIAS OBS::libobs)
  29. if(OS_WINDOWS)
  30. add_library(w32-pthreads ALIAS OBS::w32-pthreads)
  31. endif()
  32. endif()
  33. endif()
  34. if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND (OS_WINDOWS OR OS_MACOS))
  35. set(CMAKE_INSTALL_PREFIX
  36. "${OBS_STANDALONE_PLUGIN_DIR}"
  37. CACHE STRING "Directory to install OBS plugin after building" FORCE)
  38. endif()
  39. if(NOT CMAKE_BUILD_TYPE)
  40. set(CMAKE_BUILD_TYPE
  41. "RelWithDebInfo"
  42. CACHE STRING
  43. "OBS build type [Release, RelWithDebInfo, Debug, MinSizeRel]" FORCE)
  44. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Release RelWithDebInfo
  45. Debug MinSizeRel)
  46. endif()
  47. file(RELATIVE_PATH RELATIVE_INSTALL_PATH "${CMAKE_SOURCE_DIR}"
  48. "${CMAKE_INSTALL_PREFIX}")
  49. file(RELATIVE_PATH RELATIVE_BUILD_PATH "${CMAKE_SOURCE_DIR}"
  50. "${CMAKE_BINARY_DIR}")
  51. # Set up OS-specific environment and helper functions
  52. if(OS_MACOS)
  53. if(NOT CMAKE_OSX_ARCHITECTURES)
  54. set(CMAKE_OSX_ARCHITECTURES
  55. "x86_64"
  56. CACHE
  57. STRING
  58. "OBS plugin build architecture for macOS - x86_64 required at least"
  59. FORCE)
  60. endif()
  61. if(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
  62. set(CMAKE_OSX_DEPLOYMENT_TARGET
  63. "10.13"
  64. CACHE STRING "OBS plugin deployment target for macOS - 10.13+ required"
  65. FORCE)
  66. endif()
  67. if(NOT DEFINED OBS_CODESIGN_LINKER)
  68. set(OBS_CODESIGN_LINKER
  69. ON
  70. CACHE BOOL "Enable linker code-signing on macOS (macOS 11+ required"
  71. FORCE)
  72. endif()
  73. if(NOT DEFINED OBS_BUNDLE_CODESIGN_IDENTITY)
  74. set(OBS_BUNDLE_CODESIGN_IDENTITY
  75. "-"
  76. CACHE STRING "Codesign identity for macOS" FORCE)
  77. endif()
  78. # Xcode configuration
  79. if(XCODE)
  80. # Tell Xcode to pretend the linker signed binaries so that editing with
  81. # install_name_tool preserves ad-hoc signatures. This option is supported by
  82. # `codesign` on macOS 11 or higher.
  83. #
  84. # See CMake Issue 21854:
  85. # (https://gitlab.kitware.com/cmake/cmake/-/issues/21854).
  86. set(CMAKE_XCODE_GENERATE_SCHEME ON)
  87. if(OBS_CODESIGN_LINKER)
  88. set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "-o linker-signed")
  89. endif()
  90. endif()
  91. # Set default options for bundling on macOS
  92. set(CMAKE_MACOSX_RPATH ON)
  93. set(CMAKE_SKIP_BUILD_RPATH OFF)
  94. set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
  95. set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks/")
  96. set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF)
  97. function(setup_plugin_target target)
  98. if(NOT DEFINED MACOSX_PLUGIN_GUI_IDENTIFIER)
  99. message(
  100. FATAL_ERROR
  101. "No 'MACOSX_PLUGIN_GUI_IDENTIFIER' set, but is required to build plugin bundles on macOS - example: 'com.yourname.pluginname'"
  102. )
  103. endif()
  104. if(NOT DEFINED MACOSX_PLUGIN_BUNDLE_VERSION)
  105. message(
  106. FATAL_ERROR
  107. "No 'MACOSX_PLUGIN_BUNDLE_VERSION' set, but is required to build plugin bundles on macOS - example: '25'"
  108. )
  109. endif()
  110. if(NOT DEFINED MACOSX_PLUGIN_SHORT_VERSION_STRING)
  111. message(
  112. FATAL_ERROR
  113. "No 'MACOSX_PLUGIN_SHORT_VERSION_STRING' set, but is required to build plugin bundles on macOS - example: '1.0.2'"
  114. )
  115. endif()
  116. set(MACOSX_PLUGIN_BUNDLE_NAME
  117. "${target}"
  118. PARENT_SCOPE)
  119. set(MACOSX_PLUGIN_BUNDLE_VERSION
  120. "${MACOSX_BUNDLE_BUNDLE_VERSION}"
  121. PARENT_SCOPE)
  122. set(MACOSX_PLUGIN_SHORT_VERSION_STRING
  123. "${MACOSX_BUNDLE_SHORT_VERSION_STRING}"
  124. PARENT_SCOPE)
  125. set(MACOSX_PLUGIN_EXECUTABLE_NAME
  126. "${target}"
  127. PARENT_SCOPE)
  128. set(MACOSX_PLUGIN_BUNDLE_TYPE
  129. "BNDL"
  130. PARENT_SCOPE)
  131. install(
  132. TARGETS ${target}
  133. LIBRARY DESTINATION "."
  134. COMPONENT obs_plugins
  135. NAMELINK_COMPONENT ${target}_Development)
  136. set(_COMMAND
  137. "${CMAKE_INSTALL_NAME_TOOL} \\
  138. -change ${CMAKE_PREFIX_PATH}/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets \\
  139. -change ${CMAKE_PREFIX_PATH}/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore \\
  140. -change ${CMAKE_PREFIX_PATH}/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui \\
  141. \\\"\${CMAKE_INSTALL_PREFIX}/${target}.plugin/Contents/MacOS/${target}\\\""
  142. )
  143. install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")"
  144. COMPONENT obs_plugins)
  145. if(NOT XCODE)
  146. set(_COMMAND
  147. "/usr/bin/codesign --force \\
  148. --sign \\\"${OBS_BUNDLE_CODESIGN_IDENTITY}\\\" \\
  149. --options runtime \\
  150. --entitlements \\\"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../bundle/macOS/entitlements.plist\\\" \\
  151. \\\"${CMAKE_INSTALL_PREFIX}/${target}.plugin\\\"")
  152. install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")"
  153. COMPONENT obs_plugins)
  154. endif()
  155. set_target_properties(
  156. ${target}
  157. PROPERTIES
  158. BUNDLE ON
  159. BUNDLE_EXTENSION "plugin"
  160. OUTPUT_NAME ${target}
  161. MACOSX_BUNDLE_INFO_PLIST
  162. "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../bundle/macOS/Plugin-Info.plist.in"
  163. XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER
  164. "${MACOSX_PLUGIN_GUI_IDENTIFIER}"
  165. XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${OBS_BUNDLE_CODESIGN_IDENTITY}"
  166. XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS
  167. "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../bundle/macOS/entitlements.plist")
  168. add_custom_command(
  169. TARGET ${target}
  170. POST_BUILD
  171. COMMAND
  172. /bin/sh -c
  173. "codesign --force --sign \"-\" $<$<BOOL:${OBS_CODESIGN_LINKER}>:--options linker-signed >\"$<TARGET_BUNDLE_DIR:${target}>\""
  174. COMMENT "Codesigning ${target}"
  175. VERBATIM)
  176. install_bundle_resources(${target})
  177. endfunction()
  178. function(install_bundle_resources target)
  179. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data")
  180. file(GLOB_RECURSE _DATA_FILES "${CMAKE_CURRENT_SOURCE_DIR}/data/*")
  181. foreach(_DATA_FILE IN LISTS _DATA_FILES)
  182. file(RELATIVE_PATH _RELATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/data/
  183. ${_DATA_FILE})
  184. get_filename_component(_RELATIVE_PATH "${_RELATIVE_PATH}" PATH)
  185. target_sources(${target} PRIVATE ${_DATA_FILE})
  186. set_source_files_properties(
  187. ${_DATA_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION
  188. "Resources/${_RELATIVE_PATH}")
  189. string(REPLACE "\\" "\\\\" _GROUP_NAME "${_RELATIVE_PATH}")
  190. source_group("Resources\\${_GROUP_NAME}" FILES ${_DATA_FILE})
  191. endforeach()
  192. endif()
  193. endfunction()
  194. else()
  195. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  196. set(_ARCH_SUFFIX 64)
  197. else()
  198. set(_ARCH_SUFFIX 32)
  199. endif()
  200. set(OBS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/rundir")
  201. if(OS_POSIX)
  202. option(LINUX_PORTABLE "Build portable version (Linux)" OFF)
  203. if(NOT LINUX_PORTABLE)
  204. set(OBS_LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}")
  205. set(OBS_PLUGIN_DESTINATION "${OBS_LIBRARY_DESTINATION}/obs-plugins")
  206. set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
  207. set(OBS_DATA_DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/obs")
  208. else()
  209. set(OBS_LIBRARY_DESTINATION "bin/${_ARCH_SUFFIX}bit")
  210. set(OBS_PLUGIN_DESTINATION "obs-plugins/${_ARCH_SUFFIX}bit")
  211. set(CMAKE_INSTALL_RPATH
  212. "$ORIGIN/" "${CMAKE_INSTALL_PREFIX}/${OBS_LIBRARY_DESTINATION}")
  213. set(OBS_DATA_DESTINATION "data")
  214. endif()
  215. if(OS_LINUX)
  216. set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
  217. set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${LINUX_MAINTAINER_EMAIL}")
  218. set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}")
  219. set(CPACK_GENERATOR "DEB")
  220. set(CPACK_DEBIAN_PACKAGE_DEPENDS
  221. "obs-studio (>= 27.0.0), libqt5core5a (>= 5.9.0~beta), libqt5gui5 (>= 5.3.0), libqt5widgets5 (>= 5.7.0)"
  222. )
  223. if(NOT LINUX_PORTABLE)
  224. set(CPACK_SET_DESTDIR ON)
  225. endif()
  226. include(CPack)
  227. endif()
  228. else()
  229. set(OBS_LIBRARY_DESTINATION "bin/${_ARCH_SUFFIX}bit")
  230. set(OBS_LIBRARY32_DESTINATION "bin/32bit")
  231. set(OBS_LIBRARY64_DESTINATION "bin/64bit")
  232. set(OBS_PLUGIN_DESTINATION "obs-plugins/${_ARCH_SUFFIX}bit")
  233. set(OBS_PLUGIN32_DESTINATION "obs-plugins/32bit")
  234. set(OBS_PLUGIN64_DESTINATION "obs-plugins/64bit")
  235. set(OBS_DATA_DESTINATION "data")
  236. endif()
  237. function(setup_plugin_target target)
  238. set_target_properties(${target} PROPERTIES PREFIX "")
  239. install(
  240. TARGETS ${target}
  241. RUNTIME DESTINATION "${OBS_PLUGIN_DESTINATION}"
  242. COMPONENT ${target}_Runtime
  243. LIBRARY DESTINATION "${OBS_PLUGIN_DESTINATION}"
  244. COMPONENT ${target}_Runtime
  245. NAMELINK_COMPONENT ${target}_Development)
  246. install(
  247. FILES "$<TARGET_FILE:${target}>"
  248. DESTINATION "$<CONFIG>/${OBS_PLUGIN_DESTINATION}"
  249. COMPONENT obs_rundir
  250. EXCLUDE_FROM_ALL)
  251. if(OS_WINDOWS)
  252. install(
  253. FILES "$<TARGET_PDB_FILE:${target}>"
  254. CONFIGURATIONS "RelWithDebInfo" "Debug"
  255. DESTINATION "$<CONFIG>/${OBS_PLUGIN_DESTINATION}"
  256. COMPONENT obs_rundir
  257. OPTIONAL EXCLUDE_FROM_ALL)
  258. endif()
  259. if(MSVC)
  260. target_link_options(
  261. ${target}
  262. PRIVATE
  263. "LINKER:/OPT:REF"
  264. "$<$<NOT:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>>:LINKER\:/SAFESEH\:NO>"
  265. "$<$<CONFIG:DEBUG>:LINKER\:/INCREMENTAL:NO>"
  266. "$<$<CONFIG:RELWITHDEBINFO>:LINKER\:/INCREMENTAL:NO>")
  267. endif()
  268. setup_target_resources("${target}" "obs-plugins/${target}")
  269. if(OS_WINDOWS AND DEFINED OBS_BUILD_DIR)
  270. setup_target_for_testing(${target})
  271. endif()
  272. add_custom_command(
  273. TARGET ${target}
  274. POST_BUILD
  275. COMMAND
  276. "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_OUTPUT_DIR}
  277. -DCMAKE_INSTALL_COMPONENT=obs_rundir
  278. -DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
  279. ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
  280. COMMENT "Installing to plugin rundir"
  281. VERBATIM)
  282. endfunction()
  283. function(setup_target_resources target destination)
  284. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data")
  285. install(
  286. DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/"
  287. DESTINATION "${OBS_DATA_DESTINATION}/${destination}"
  288. USE_SOURCE_PERMISSIONS
  289. COMPONENT obs_plugins)
  290. install(
  291. DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data"
  292. DESTINATION "$<CONFIG>/${OBS_DATA_DESTINATION}/${destination}"
  293. USE_SOURCE_PERMISSIONS
  294. COMPONENT obs_rundir
  295. EXCLUDE_FROM_ALL)
  296. endif()
  297. endfunction()
  298. if(OS_WINDOWS)
  299. function(setup_target_for_testing target)
  300. install(
  301. FILES "$<TARGET_FILE:${target}>"
  302. DESTINATION "$<CONFIG>/${OBS_PLUGIN_DESTINATION}"
  303. COMPONENT obs_testing
  304. EXCLUDE_FROM_ALL)
  305. install(
  306. FILES "$<TARGET_PDB_FILE:${target}>"
  307. CONFIGURATIONS "RelWithDebInfo" "Debug"
  308. DESTINATION "$<CONFIG>/${OBS_PLUGIN_DESTINATION}"
  309. COMPONENT obs_testing
  310. OPTIONAL EXCLUDE_FROM_ALL)
  311. install(
  312. DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data"
  313. DESTINATION "$<CONFIG>/${OBS_DATA_DESTINATION}/${destination}"
  314. USE_SOURCE_PERMISSIONS
  315. COMPONENT obs_testing
  316. EXCLUDE_FROM_ALL)
  317. add_custom_command(
  318. TARGET ${target}
  319. POST_BUILD
  320. COMMAND
  321. "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_BUILD_DIR}/rundir
  322. -DCMAKE_INSTALL_COMPONENT=obs_testing
  323. -DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
  324. ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
  325. COMMENT "Installing to OBS test directory"
  326. VERBATIM)
  327. endfunction()
  328. endif()
  329. endif()