helpers.cmake 21 KB

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