helpers.cmake 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. # OBS CMake Windows helper functions module
  2. include_guard(GLOBAL)
  3. include(helpers_common)
  4. # set_target_properties_obs: Set target properties for use in obs-studio
  5. function(set_target_properties_obs target)
  6. set(options "")
  7. set(oneValueArgs "")
  8. set(multiValueArgs PROPERTIES)
  9. cmake_parse_arguments(PARSE_ARGV 0 _STPO "${options}" "${oneValueArgs}" "${multiValueArgs}")
  10. message(DEBUG "Setting additional properties for target ${target}...")
  11. while(_STPO_PROPERTIES)
  12. list(POP_FRONT _STPO_PROPERTIES key value)
  13. set_property(TARGET ${target} PROPERTY ${key} "${value}")
  14. endwhile()
  15. get_target_property(target_type ${target} TYPE)
  16. if(target_type STREQUAL EXECUTABLE)
  17. if(target STREQUAL obs-browser-helper)
  18. set(OBS_EXECUTABLE_DESTINATION "${OBS_PLUGIN_DESTINATION}")
  19. elseif(target STREQUAL inject-helper OR target STREQUAL get-graphics-offsets)
  20. set(OBS_EXECUTABLE_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture")
  21. _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} x86)
  22. if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64)
  23. _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} x64)
  24. endif()
  25. endif()
  26. _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION})
  27. if(target STREQUAL obs-studio)
  28. get_property(obs_executables GLOBAL PROPERTY _OBS_EXECUTABLES)
  29. get_property(obs_modules GLOBAL PROPERTY OBS_MODULES_ENABLED)
  30. add_dependencies(${target} ${obs_executables} ${obs_modules})
  31. _bundle_dependencies(${target})
  32. target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/../AUTHORS"
  33. "${OBS_DATA_DESTINATION}/obs-studio/authors"
  34. )
  35. elseif(target STREQUAL obs-browser-helper)
  36. set_property(GLOBAL APPEND PROPERTY _OBS_EXECUTABLES ${target})
  37. return()
  38. else()
  39. set_property(GLOBAL APPEND PROPERTY _OBS_EXECUTABLES ${target})
  40. endif()
  41. elseif(target_type STREQUAL SHARED_LIBRARY)
  42. set_target_properties(${target} PROPERTIES VERSION ${OBS_VERSION_MAJOR} SOVERSION ${OBS_VERSION_CANONICAL})
  43. _target_install_obs(
  44. ${target}
  45. DESTINATION "${OBS_EXECUTABLE_DESTINATION}"
  46. LIBRARY_DESTINATION "${OBS_LIBRARY_DESTINATION}"
  47. HEADER_DESTINATION "${OBS_INCLUDE_DESTINATION}"
  48. )
  49. elseif(target_type STREQUAL MODULE_LIBRARY)
  50. set_target_properties(${target} PROPERTIES VERSION 0 SOVERSION ${OBS_VERSION_CANONICAL})
  51. if(target STREQUAL libobs-d3d11 OR target STREQUAL libobs-opengl OR target STREQUAL libobs-winrt)
  52. set(target_destination "${OBS_EXECUTABLE_DESTINATION}")
  53. elseif(target STREQUAL "obspython" OR target STREQUAL "obslua")
  54. set(target_destination "${OBS_SCRIPT_PLUGIN_DESTINATION}")
  55. elseif(target STREQUAL graphics-hook)
  56. set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-capture")
  57. target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan64.json" "${target_destination}")
  58. target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan32.json" "${target_destination}")
  59. _target_install_obs(${target} DESTINATION ${target_destination} x86)
  60. if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64)
  61. _target_install_obs(${target} DESTINATION ${target_destination} x64)
  62. endif()
  63. elseif(target STREQUAL obs-virtualcam-module)
  64. set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow")
  65. _target_install_obs(${target} DESTINATION ${target_destination} x86)
  66. if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64)
  67. _target_install_obs(${target} DESTINATION ${target_destination} x64)
  68. endif()
  69. else()
  70. set(target_destination "${OBS_PLUGIN_DESTINATION}")
  71. endif()
  72. _target_install_obs(${target} DESTINATION ${target_destination})
  73. if(${target} STREQUAL obspython)
  74. add_custom_command(
  75. TARGET ${target}
  76. POST_BUILD
  77. COMMAND "${CMAKE_COMMAND}" -E echo "Add obspython import module"
  78. COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_SCRIPT_PLUGIN_DESTINATION}/"
  79. COMMAND
  80. "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE_DIR:obspython>/obspython.py"
  81. "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_SCRIPT_PLUGIN_DESTINATION}/"
  82. COMMENT ""
  83. )
  84. install(
  85. FILES "$<TARGET_FILE_DIR:obspython>/obspython.py"
  86. DESTINATION "${OBS_SCRIPT_PLUGIN_DESTINATION}"
  87. COMPONENT Runtime
  88. )
  89. elseif(${target} STREQUAL obs-browser)
  90. message(DEBUG "Add Chromium Embedded Framework to project for obs-browser plugin...")
  91. if(TARGET CEF::Library)
  92. get_target_property(imported_location CEF::Library IMPORTED_LOCATION_RELEASE)
  93. if(imported_location)
  94. cmake_path(GET imported_location PARENT_PATH cef_location)
  95. cmake_path(GET cef_location PARENT_PATH cef_root_location)
  96. add_custom_command(
  97. TARGET ${target}
  98. POST_BUILD
  99. COMMAND "${CMAKE_COMMAND}" -E echo "Add Chromium Embedded Framework to library directory"
  100. COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}"
  101. COMMAND
  102. "${CMAKE_COMMAND}" -E copy_if_different "${imported_location}" "${cef_location}/chrome_elf.dll"
  103. "${cef_location}/libEGL.dll" "${cef_location}/libGLESv2.dll" "${cef_location}/v8_context_snapshot.bin"
  104. "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}"
  105. COMMAND
  106. "${CMAKE_COMMAND}" -E copy_if_different "${cef_root_location}/Resources/chrome_100_percent.pak"
  107. "${cef_root_location}/Resources/chrome_200_percent.pak" "${cef_root_location}/Resources/icudtl.dat"
  108. "${cef_root_location}/Resources/resources.pak" "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}/"
  109. COMMAND
  110. "${CMAKE_COMMAND}" -E copy_directory "${cef_root_location}/Resources/locales"
  111. "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}/locales"
  112. COMMENT ""
  113. )
  114. install(
  115. FILES
  116. "${imported_location}"
  117. "${cef_location}/chrome_elf.dll"
  118. "${cef_location}/libEGL.dll"
  119. "${cef_location}/libGLESv2.dll"
  120. "${cef_location}/v8_context_snapshot.bin"
  121. "${cef_root_location}/Resources/chrome_100_percent.pak"
  122. "${cef_root_location}/Resources/chrome_200_percent.pak"
  123. "${cef_root_location}/Resources/icudtl.dat"
  124. "${cef_root_location}/Resources/resources.pak"
  125. DESTINATION "${target_destination}"
  126. COMPONENT Runtime
  127. )
  128. install(
  129. DIRECTORY "${cef_root_location}/Resources/locales"
  130. DESTINATION "${target_destination}"
  131. USE_SOURCE_PERMISSIONS
  132. COMPONENT Runtime
  133. )
  134. endif()
  135. endif()
  136. endif()
  137. set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target})
  138. endif()
  139. target_link_options(${target} PRIVATE "/PDBALTPATH:$<TARGET_PDB_FILE_NAME:${target}>")
  140. target_install_resources(${target})
  141. get_target_property(target_sources ${target} SOURCES)
  142. set(target_ui_files ${target_sources})
  143. list(FILTER target_ui_files INCLUDE REGEX ".+\\.(ui|qrc)")
  144. source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "UI Files" FILES ${target_ui_files})
  145. if(${target} STREQUAL libobs)
  146. set(target_source_files ${target_sources})
  147. set(target_header_files ${target_sources})
  148. list(FILTER target_source_files INCLUDE REGEX ".+\\.(m|c[cp]?p?|swift)")
  149. list(FILTER target_header_files INCLUDE REGEX ".+\\.h(pp)?")
  150. source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Source Files" FILES ${target_source_files})
  151. source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Header Files" FILES ${target_header_files})
  152. endif()
  153. endfunction()
  154. # _target_install_obs: Helper function to install build artifacts to rundir and install location
  155. function(_target_install_obs target)
  156. set(options "x86" "x64")
  157. set(oneValueArgs "DESTINATION" "LIBRARY_DESTINATION" "HEADER_DESTINATION")
  158. set(multiValueArgs "")
  159. cmake_parse_arguments(PARSE_ARGV 0 _TIO "${options}" "${oneValueArgs}" "${multiValueArgs}")
  160. if(_TIO_x86)
  161. get_target_property(target_type ${target} TYPE)
  162. if(target_type STREQUAL EXECUTABLE)
  163. set(suffix exe)
  164. else()
  165. set(suffix dll)
  166. endif()
  167. cmake_path(RELATIVE_PATH CMAKE_CURRENT_SOURCE_DIR BASE_DIRECTORY "${OBS_SOURCE_DIR}" OUTPUT_VARIABLE project_path)
  168. set(32bit_project_path "${OBS_SOURCE_DIR}/build_x86/${project_path}")
  169. set(target_file "${32bit_project_path}/$<CONFIG>/${target}32.${suffix}")
  170. set(target_pdb_file "${32bit_project_path}/$<CONFIG>/${target}32.pdb")
  171. set(comment "Copy ${target} (x86) to destination")
  172. install(
  173. FILES "${32bit_project_path}/$<CONFIG>/${target}32.${suffix}"
  174. DESTINATION "${_TIO_DESTINATION}"
  175. COMPONENT Runtime
  176. OPTIONAL
  177. )
  178. elseif(_TIO_x64)
  179. get_target_property(target_type ${target} TYPE)
  180. if(target_type STREQUAL EXECUTABLE)
  181. set(suffix exe)
  182. else()
  183. set(suffix dll)
  184. endif()
  185. cmake_path(RELATIVE_PATH CMAKE_CURRENT_SOURCE_DIR BASE_DIRECTORY "${OBS_SOURCE_DIR}" OUTPUT_VARIABLE project_path)
  186. set(64bit_project_path "${OBS_SOURCE_DIR}/build_x64/${project_path}")
  187. set(target_file "${64bit_project_path}/$<CONFIG>/${target}64.${suffix}")
  188. set(target_pdb_file "${64bit_project_path}/$<CONFIG>/${target}64.pdb")
  189. set(comment "Copy ${target} (x64) to destination")
  190. install(
  191. FILES "${64bit_project_path}/$<CONFIG>/${target}64.${suffix}"
  192. DESTINATION "${_TIO_DESTINATION}"
  193. COMPONENT Runtime
  194. OPTIONAL
  195. )
  196. else()
  197. set(target_file "$<TARGET_FILE:${target}>")
  198. set(target_pdb_file "$<TARGET_PDB_FILE:${target}>")
  199. set(comment "Copy ${target} to destination")
  200. get_target_property(target_type ${target} TYPE)
  201. if(target_type STREQUAL EXECUTABLE)
  202. install(TARGETS ${target} RUNTIME DESTINATION "${_TIO_DESTINATION}" COMPONENT Runtime)
  203. elseif(target_type STREQUAL SHARED_LIBRARY)
  204. if(NOT _TIO_LIBRARY_DESTINATION)
  205. set(_TIO_LIBRARY_DESTINATION ${_TIO_DESTINATION})
  206. endif()
  207. if(NOT _TIO_HEADER_DESTINATION)
  208. set(_TIO_HEADER_DESTINATION include)
  209. endif()
  210. install(
  211. TARGETS ${target}
  212. RUNTIME DESTINATION "${_TIO_DESTINATION}"
  213. LIBRARY DESTINATION "${_TIO_LIBRARY_DESTINATION}" COMPONENT Runtime EXCLUDE_FROM_ALL
  214. PUBLIC_HEADER DESTINATION "${_TIO_HEADER_DESTINATION}" COMPONENT Development EXCLUDE_FROM_ALL
  215. )
  216. elseif(target_type STREQUAL MODULE_LIBRARY)
  217. install(
  218. TARGETS ${target}
  219. LIBRARY DESTINATION "${_TIO_DESTINATION}" COMPONENT Runtime NAMELINK_COMPONENT Development
  220. )
  221. endif()
  222. endif()
  223. add_custom_command(
  224. TARGET ${target}
  225. POST_BUILD
  226. COMMAND "${CMAKE_COMMAND}" -E echo "${comment}"
  227. COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${_TIO_DESTINATION}"
  228. COMMAND "${CMAKE_COMMAND}" -E copy ${target_file} "${OBS_OUTPUT_DIR}/$<CONFIG>/${_TIO_DESTINATION}"
  229. COMMAND
  230. "${CMAKE_COMMAND}" -E $<IF:$<CONFIG:Debug,RelWithDebInfo,Release>,copy,true> ${target_pdb_file}
  231. "${OBS_OUTPUT_DIR}/$<CONFIG>/${_TIO_DESTINATION}"
  232. COMMENT ""
  233. VERBATIM
  234. )
  235. install(
  236. FILES ${target_pdb_file}
  237. CONFIGURATIONS RelWithDebInfo Debug Release
  238. DESTINATION "${_TIO_DESTINATION}"
  239. COMPONENT Runtime
  240. OPTIONAL
  241. )
  242. endfunction()
  243. # target_export: Helper function to export target as CMake package
  244. function(target_export target)
  245. # Exclude CMake package from 'ALL' target
  246. set(exclude_variant EXCLUDE_FROM_ALL)
  247. _target_export(${target})
  248. get_target_property(target_type ${target} TYPE)
  249. if(NOT target_type STREQUAL INTERFACE_LIBRARY)
  250. install(
  251. FILES "$<TARGET_PDB_FILE:${target}>"
  252. CONFIGURATIONS RelWithDebInfo Debug Release
  253. DESTINATION "${OBS_EXECUTABLE_DESTINATION}"
  254. COMPONENT Development
  255. OPTIONAL
  256. )
  257. endif()
  258. endfunction()
  259. # Helper function to add resources into bundle
  260. function(target_install_resources target)
  261. message(DEBUG "Installing resources for target ${target}...")
  262. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data")
  263. file(GLOB_RECURSE data_files "${CMAKE_CURRENT_SOURCE_DIR}/data/*")
  264. foreach(data_file IN LISTS data_files)
  265. cmake_path(
  266. RELATIVE_PATH
  267. data_file
  268. BASE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/"
  269. OUTPUT_VARIABLE relative_path
  270. )
  271. cmake_path(GET relative_path PARENT_PATH relative_path)
  272. target_sources(${target} PRIVATE "${data_file}")
  273. source_group("Resources/${relative_path}" FILES "${data_file}")
  274. endforeach()
  275. get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED)
  276. if(target IN_LIST obs_module_list)
  277. set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}")
  278. elseif(target STREQUAL obs-studio)
  279. set(target_destination "${OBS_DATA_DESTINATION}/obs-studio")
  280. else()
  281. set(target_destination "${OBS_DATA_DESTINATION}/${target}")
  282. endif()
  283. install(
  284. DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/"
  285. DESTINATION "${target_destination}"
  286. USE_SOURCE_PERMISSIONS
  287. COMPONENT Runtime
  288. )
  289. add_custom_command(
  290. TARGET ${target}
  291. POST_BUILD
  292. COMMAND "${CMAKE_COMMAND}" -E echo "Copy ${target} resources to data directory"
  293. COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}"
  294. COMMAND
  295. "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/data"
  296. "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}"
  297. COMMENT ""
  298. VERBATIM
  299. )
  300. endif()
  301. endfunction()
  302. # Helper function to add a specific resource to a bundle
  303. function(target_add_resource target resource)
  304. get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED)
  305. if(ARGN)
  306. set(target_destination "${ARGN}")
  307. elseif(${target} IN_LIST obs_module_list)
  308. set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}")
  309. elseif(target STREQUAL obs-studio)
  310. set(target_destination "${OBS_DATA_DESTINATION}/obs-studio")
  311. else()
  312. set(target_destination "${OBS_DATA_DESTINATION}/${target}")
  313. endif()
  314. message(DEBUG "Add resource '${resource}' to target ${target} at destination '${target_destination}'...")
  315. install(FILES "${resource}" DESTINATION "${target_destination}" COMPONENT Runtime)
  316. add_custom_command(
  317. TARGET ${target}
  318. POST_BUILD
  319. COMMAND "${CMAKE_COMMAND}" -E echo "Copy ${target} resource ${resource} to library directory"
  320. COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}/"
  321. COMMAND "${CMAKE_COMMAND}" -E copy "${resource}" "${OBS_OUTPUT_DIR}/$<CONFIG>/${target_destination}/"
  322. COMMENT ""
  323. VERBATIM
  324. )
  325. source_group("Resources" FILES "${resource}")
  326. endfunction()
  327. # _bundle_dependencies: Resolve third party dependencies and add them to Windows binary directory
  328. function(_bundle_dependencies target)
  329. message(DEBUG "Discover dependencies of target ${target}...")
  330. set(found_dependencies)
  331. find_dependencies(TARGET ${target} FOUND_VAR found_dependencies)
  332. get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED)
  333. list(LENGTH obs_module_list num_modules)
  334. if(num_modules GREATER 0)
  335. add_dependencies(${target} ${obs_module_list})
  336. foreach(module IN LISTS obs_module_list)
  337. find_dependencies(TARGET ${module} FOUND_VAR found_dependencies)
  338. endforeach()
  339. endif()
  340. list(REMOVE_DUPLICATES found_dependencies)
  341. set(library_paths_DEBUG)
  342. set(library_paths_RELWITHDEBINFO)
  343. set(library_paths_RELEASE)
  344. set(library_paths_MINSIZEREL)
  345. set(plugins_list)
  346. foreach(library IN LISTS found_dependencies)
  347. # CEF needs to be placed in obs-plugins directory on Windows, which is handled already
  348. if(${library} STREQUAL CEF::Library)
  349. continue()
  350. endif()
  351. get_target_property(library_type ${library} TYPE)
  352. get_target_property(is_imported ${library} IMPORTED)
  353. if(is_imported)
  354. get_target_property(imported_location ${library} IMPORTED_LOCATION)
  355. foreach(config IN ITEMS RELEASE RELWITHDEBINFO MINSIZEREL DEBUG)
  356. get_target_property(imported_location_${config} ${library} IMPORTED_LOCATION_${config})
  357. if(imported_location_${config})
  358. _check_library_location(${imported_location_${config}})
  359. elseif(NOT imported_location_${config} AND imported_location_RELEASE)
  360. _check_library_location(${imported_location_RELEASE})
  361. else()
  362. _check_library_location(${imported_location})
  363. endif()
  364. endforeach()
  365. if(library MATCHES "Qt6?::.+")
  366. find_qt_plugins(COMPONENT ${library} TARGET ${target} FOUND_VAR plugins_list)
  367. endif()
  368. endif()
  369. endforeach()
  370. foreach(config IN ITEMS DEBUG RELWITHDEBINFO RELEASE MINSIZEREL)
  371. list(REMOVE_DUPLICATES library_paths_${config})
  372. endforeach()
  373. add_custom_command(
  374. TARGET ${target}
  375. POST_BUILD
  376. COMMAND "${CMAKE_COMMAND}" -E echo "Copy dependencies to binary directory (${OBS_EXECUTABLE_DESTINATION})..."
  377. COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}"
  378. COMMAND
  379. "${CMAKE_COMMAND}" -E "$<IF:$<CONFIG:Debug>,copy_if_different,true>" "$<$<CONFIG:Debug>:${library_paths_DEBUG}>"
  380. "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}"
  381. COMMAND
  382. "${CMAKE_COMMAND}" -E "$<IF:$<CONFIG:RelWithDebInfo>,copy_if_different,true>"
  383. "$<$<CONFIG:RelWithDebInfo>:${library_paths_RELWITHDEBINFO}>"
  384. "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}"
  385. COMMAND
  386. "${CMAKE_COMMAND}" -E "$<IF:$<CONFIG:Release>,copy_if_different,true>"
  387. "$<$<CONFIG:Release>:${library_paths_RELEASE}>" "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}"
  388. COMMAND
  389. "${CMAKE_COMMAND}" -E "$<IF:$<CONFIG:MinSizeRel>,copy_if_different,true>"
  390. "$<$<CONFIG:MinSizeRel>:${library_paths_MINSIZEREL}>" "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}"
  391. COMMENT "."
  392. VERBATIM
  393. COMMAND_EXPAND_LISTS
  394. )
  395. install(
  396. FILES ${library_paths_DEBUG}
  397. CONFIGURATIONS Debug
  398. DESTINATION "${OBS_EXECUTABLE_DESTINATION}"
  399. COMPONENT Runtime
  400. )
  401. install(
  402. FILES ${library_paths_RELWITHDEBINFO}
  403. CONFIGURATIONS RelWithDebInfo
  404. DESTINATION "${OBS_EXECUTABLE_DESTINATION}"
  405. COMPONENT Runtime
  406. )
  407. install(
  408. FILES ${library_paths_RELEASE}
  409. CONFIGURATIONS Release
  410. DESTINATION "${OBS_EXECUTABLE_DESTINATION}"
  411. COMPONENT Runtime
  412. )
  413. install(
  414. FILES ${library_paths_MINSIZEREL}
  415. CONFIGURATIONS MinSizeRel
  416. DESTINATION "${OBS_EXECUTABLE_DESTINATION}"
  417. COMPONENT Runtime
  418. )
  419. set(debug_dll_exceptions qdirect2d qcertonlybackend qopensslbackend qschannelbackend)
  420. list(REMOVE_DUPLICATES plugins_list)
  421. foreach(plugin IN LISTS plugins_list)
  422. message(TRACE "Adding Qt plugin ${plugin}...")
  423. cmake_path(GET plugin PARENT_PATH plugin_path)
  424. cmake_path(GET plugin_path STEM plugin_stem)
  425. list(APPEND plugin_stems ${plugin_stem})
  426. if(plugin MATCHES "(.+d)\\.dll$" AND CMAKE_MATCH_COUNT EQUAL 1 AND NOT CMAKE_MATCH_1 IN_LIST debug_dll_exceptions)
  427. list(APPEND plugin_${plugin_stem}_debug ${plugin})
  428. else()
  429. list(APPEND plugin_${plugin_stem} ${plugin})
  430. endif()
  431. endforeach()
  432. unset(debug_exceptions)
  433. list(REMOVE_DUPLICATES plugin_stems)
  434. foreach(stem IN LISTS plugin_stems)
  435. set(plugin_list ${plugin_${stem}})
  436. set(plugin_list_debug ${plugin_${stem}_debug})
  437. add_custom_command(
  438. TARGET ${target}
  439. POST_BUILD
  440. COMMAND
  441. "${CMAKE_COMMAND}" -E echo "Copy Qt plugins ${stem} to binary directory (${OBS_EXECUTABLE_DESTINATION}/${stem})"
  442. COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}/${stem}"
  443. COMMAND
  444. "${CMAKE_COMMAND}" -E "$<IF:$<CONFIG:Debug>,copy_if_different,true>" "${plugin_list_debug}"
  445. "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}/${stem}"
  446. COMMAND
  447. "${CMAKE_COMMAND}" -E "$<IF:$<CONFIG:Debug>,true,copy_if_different>" "${plugin_list}"
  448. "${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_EXECUTABLE_DESTINATION}/${stem}"
  449. COMMENT ""
  450. VERBATIM
  451. COMMAND_EXPAND_LISTS
  452. )
  453. install(
  454. FILES ${plugin_list_debug}
  455. CONFIGURATIONS Debug
  456. DESTINATION "${OBS_EXECUTABLE_DESTINATION}/${stem}"
  457. COMPONENT Runtime
  458. )
  459. install(
  460. FILES ${plugin_list}
  461. CONFIGURATIONS RelWithDebInfo Release MinSizeRel
  462. DESTINATION "${OBS_EXECUTABLE_DESTINATION}/${stem}"
  463. COMPONENT Runtime
  464. )
  465. endforeach()
  466. endfunction()
  467. # _check_library_location: Check for corresponding DLL given an import library path
  468. macro(_check_library_location location)
  469. if(library_type STREQUAL "SHARED_LIBRARY")
  470. set(library_location "${location}")
  471. else()
  472. string(STRIP "${location}" location)
  473. if(location MATCHES ".+lib$")
  474. cmake_path(GET location FILENAME _dll_name)
  475. cmake_path(GET location PARENT_PATH _implib_path)
  476. cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin")
  477. string(REPLACE ".lib" ".dll" _dll_name "${_dll_name}")
  478. string(REPLACE ".dll" ".pdb" _pdb_name "${_dll_name}")
  479. find_program(_dll_path NAMES "${_dll_name}" HINTS ${_implib_path} ${_bin_path} NO_CACHE NO_DEFAULT_PATH)
  480. find_program(_pdb_path NAMES "${_pdb_name}" HINTS ${_implib_path} ${_bin_path} NO_CACHE NO_DEFAULT_PATH)
  481. if(_dll_path)
  482. set(library_location "${_dll_path}")
  483. set(library_pdb_location "${_pdb_path}")
  484. else()
  485. unset(library_location)
  486. unset(library_pdb_location)
  487. endif()
  488. unset(_dll_path)
  489. unset(_pdb_path)
  490. unset(_bin_path)
  491. unset(_implib_path)
  492. unset(_dll_name)
  493. unset(_pdb_name)
  494. else()
  495. unset(library_location)
  496. unset(library_pdb_location)
  497. endif()
  498. endif()
  499. if(library_location)
  500. list(APPEND library_paths_${config} ${library_location})
  501. endif()
  502. if(library_pdb_location)
  503. list(APPEND library_paths_${config} ${library_pdb_location})
  504. endif()
  505. unset(location)
  506. unset(library_location)
  507. unset(library_pdb_location)
  508. endmacro()