1
0

helpers.cmake 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. # OBS CMake macOS helper functions module
  2. include_guard(GLOBAL)
  3. include(helpers_common)
  4. # set_target_xcode_properties: Sets Xcode-specific target attributes
  5. function(set_target_xcode_properties target)
  6. set(options "")
  7. set(oneValueArgs "")
  8. set(multiValueArgs PROPERTIES)
  9. cmake_parse_arguments(PARSE_ARGV 0 _STXP "${options}" "${oneValueArgs}" "${multiValueArgs}")
  10. message(DEBUG "Setting Xcode properties for target ${target}...")
  11. while(_STXP_PROPERTIES)
  12. list(POP_FRONT _STXP_PROPERTIES key value)
  13. set_property(TARGET ${target} PROPERTY XCODE_ATTRIBUTE_${key} "${value}")
  14. endwhile()
  15. endfunction()
  16. # set_target_properties_obs: Set target properties for use in obs-studio
  17. function(set_target_properties_obs target)
  18. set(options "")
  19. set(oneValueArgs "")
  20. set(multiValueArgs PROPERTIES)
  21. cmake_parse_arguments(PARSE_ARGV 0 _STPO "${options}" "${oneValueArgs}" "${multiValueArgs}")
  22. message(DEBUG "Setting additional properties for target ${target}...")
  23. while(_STPO_PROPERTIES)
  24. list(POP_FRONT _STPO_PROPERTIES key value)
  25. set_property(TARGET ${target} PROPERTY ${key} "${value}")
  26. endwhile()
  27. get_target_property(target_type ${target} TYPE)
  28. string(TIMESTAMP CURRENT_YEAR "%Y")
  29. # Target is a GUI or CLI application
  30. if(target_type STREQUAL EXECUTABLE)
  31. if(target STREQUAL obs-studio)
  32. set_target_properties(
  33. ${target}
  34. PROPERTIES
  35. OUTPUT_NAME OBS
  36. MACOSX_BUNDLE TRUE
  37. MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Info.plist.in"
  38. XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY YES
  39. XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY YES
  40. XCODE_EMBED_PLUGINS_REMOVE_HEADERS_ON_COPY YES
  41. XCODE_EMBED_PLUGINS_CODE_SIGN_ON_COPY YES
  42. )
  43. set_target_xcode_properties(
  44. ${target}
  45. PROPERTIES PRODUCT_BUNDLE_IDENTIFIER com.obsproject.obs-studio
  46. PRODUCT_NAME OBS
  47. ASSETCATALOG_COMPILER_APPICON_NAME AppIcon
  48. CURRENT_PROJECT_VERSION ${OBS_BUILD_NUMBER}
  49. MARKETING_VERSION ${OBS_VERSION_CANONICAL}
  50. GENERATE_INFOPLIST_FILE YES
  51. COPY_PHASE_STRIP NO
  52. CLANG_ENABLE_OBJC_ARC YES
  53. SKIP_INSTALL NO
  54. INSTALL_PATH "$(LOCAL_APPS_DIR)"
  55. INFOPLIST_KEY_CFBundleDisplayName "OBS Studio"
  56. INFOPLIST_KEY_NSHumanReadableCopyright "(c) 2012-${CURRENT_YEAR} Lain Bailey"
  57. INFOPLIST_KEY_NSCameraUsageDescription "OBS needs to access the camera to enable camera sources to work."
  58. INFOPLIST_KEY_NSMicrophoneUsageDescription "OBS needs to access the microphone to enable audio input."
  59. INFOPLIST_KEY_NSAppleEventsUsageDescription "OBS needs to access background events to enable hotkeys while not in focus."
  60. )
  61. get_property(obs_dependencies GLOBAL PROPERTY _OBS_DEPENDENCIES)
  62. add_dependencies(${target} ${obs_dependencies})
  63. get_property(obs_frameworks GLOBAL PROPERTY _OBS_FRAMEWORKS)
  64. set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_FRAMEWORKS ${obs_frameworks})
  65. if(SPARKLE_APPCAST_URL AND SPARKLE_PUBLIC_KEY)
  66. set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_FRAMEWORKS ${SPARKLE})
  67. endif()
  68. if(TARGET mac-syphon)
  69. set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_FRAMEWORKS ${SYPHON})
  70. endif()
  71. get_property(obs_executables GLOBAL PROPERTY _OBS_EXECUTABLES)
  72. add_dependencies(${target} ${obs_executables})
  73. foreach(executable IN LISTS obs_executables)
  74. set_target_xcode_properties(${executable} PROPERTIES INSTALL_PATH
  75. "$(LOCAL_APPS_DIR)/$<TARGET_BUNDLE_DIR_NAME:${target}>/Contents/MacOS"
  76. )
  77. add_custom_command(
  78. TARGET ${target}
  79. POST_BUILD
  80. COMMAND
  81. "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${executable}>"
  82. "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/MacOS/"
  83. COMMENT "Copy ${executable} to application bundle"
  84. )
  85. endforeach()
  86. if(VIRTUALCAM_DEVICE_UUID AND VIRTUALCAM_SOURCE_UUID AND VIRTUALCAM_SINK_UUID)
  87. set(has_virtualcam_uuids TRUE)
  88. else()
  89. set(has_virtualcam_uuids FALSE)
  90. endif()
  91. if(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE STREQUAL Automatic)
  92. if(has_virtualcam_uuids)
  93. set(entitlements_file "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements-extension.plist")
  94. else()
  95. set(entitlements_file "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist")
  96. endif()
  97. else()
  98. if(has_virtualcam_uuids AND OBS_PROVISIONING_PROFILE)
  99. set(entitlements_file "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements-extension.plist")
  100. set_target_properties(
  101. ${target}
  102. PROPERTIES XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "${OBS_PROVISIONING_PROFILE}"
  103. )
  104. configure_file(cmake/macos/exportOptions-extension.plist.in ${CMAKE_BINARY_DIR}/exportOptions.plist)
  105. else()
  106. set(entitlements_file "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist")
  107. configure_file(cmake/macos/exportOptions.plist.in ${CMAKE_BINARY_DIR}/exportOptions.plist)
  108. endif()
  109. endif()
  110. if(NOT EXISTS "${entitlements_file}")
  111. message(FATAL_ERROR "Target ${target} is missing an entitlements file in its cmake directory.")
  112. endif()
  113. set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${entitlements_file}")
  114. add_custom_command(
  115. TARGET ${target}
  116. POST_BUILD
  117. COMMAND /bin/ln -fs obs-frontend-api.dylib libobs-frontend-api.1.dylib
  118. WORKING_DIRECTORY "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Frameworks"
  119. COMMENT "Create symlink for legacy obs-frontend-api"
  120. )
  121. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/qt.conf")
  122. target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/qt.conf")
  123. endif()
  124. target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/Assets.xcassets")
  125. target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/../AUTHORS")
  126. if(TARGET obs-dal-plugin)
  127. add_custom_command(
  128. TARGET ${target}
  129. POST_BUILD
  130. COMMAND
  131. "${CMAKE_COMMAND}" -E copy_directory "$<TARGET_BUNDLE_DIR:obs-dal-plugin>"
  132. "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Resources/$<TARGET_BUNDLE_DIR_NAME:obs-dal-plugin>"
  133. COMMENT "Add OBS DAL plugin to application bundle"
  134. )
  135. endif()
  136. if(TARGET obspython)
  137. add_custom_command(
  138. TARGET ${target}
  139. POST_BUILD
  140. COMMAND
  141. "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE_DIR:obspython>/obspython.py"
  142. "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Resources"
  143. COMMENT "Add OBS::python import module"
  144. )
  145. endif()
  146. if(
  147. TARGET mac-camera-extension
  148. AND (CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE STREQUAL Automatic OR OBS_PROVISIONING_PROFILE)
  149. )
  150. target_enable_feature(mac-camera-extension "macOS CMIO Camera Extension")
  151. add_custom_command(
  152. TARGET ${target}
  153. POST_BUILD
  154. COMMAND
  155. "${CMAKE_COMMAND}" -E copy_directory "$<TARGET_BUNDLE_DIR:mac-camera-extension>"
  156. "$<TARGET_BUNDLE_CONTENT_DIR:${target}>/Library/SystemExtensions/$<TARGET_BUNDLE_DIR_NAME:mac-camera-extension>"
  157. COMMENT "Add Camera Extension to application bundle"
  158. )
  159. else()
  160. target_disable_feature(mac-camera-extension "macOS CMIO Camera Extension")
  161. endif()
  162. _bundle_dependencies(${target})
  163. install(TARGETS ${target} BUNDLE DESTINATION "." COMPONENT Application)
  164. elseif(${target} STREQUAL mac-camera-extension)
  165. set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
  166. set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target})
  167. elseif(${target} STREQUAL obs-ffmpeg-mux)
  168. if(OBS_CODESIGN_IDENTITY STREQUAL "-")
  169. set_target_xcode_properties(${target} PROPERTIES ENABLE_HARDENED_RUNTIME NO)
  170. endif()
  171. set_target_xcode_properties(${target} PROPERTIES SKIP_INSTALL NO)
  172. set_property(GLOBAL APPEND PROPERTY _OBS_EXECUTABLES ${target})
  173. set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target})
  174. else()
  175. set_property(TARGET ${target} PROPERTY XCODE_ATTRIBUTE_SKIP_INSTALL NO)
  176. set_property(GLOBAL APPEND PROPERTY _OBS_EXECUTABLES ${target})
  177. set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target})
  178. _add_entitlements()
  179. endif()
  180. elseif(target_type STREQUAL SHARED_LIBRARY)
  181. set_target_properties(
  182. ${target}
  183. PROPERTIES
  184. NO_SONAME TRUE
  185. MACHO_COMPATIBILITY_VERSION 1.0
  186. MACHO_CURRENT_VERSION ${OBS_VERSION_MAJOR}
  187. SOVERSION 0
  188. VERSION 0
  189. )
  190. set_target_xcode_properties(
  191. ${target}
  192. PROPERTIES DYLIB_COMPATIBILITY_VERSION 1.0
  193. DYLIB_CURRENT_VERSION ${OBS_VERSION_MAJOR}
  194. PRODUCT_NAME ${target}
  195. PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}
  196. SKIP_INSTALL YES
  197. )
  198. get_target_property(is_framework ${target} FRAMEWORK)
  199. if(is_framework)
  200. set_target_properties(
  201. ${target}
  202. PROPERTIES FRAMEWORK_VERSION A MACOSX_FRAMEWORK_IDENTIFIER com.obsproject.${target}
  203. )
  204. set_target_xcode_properties(
  205. ${target}
  206. PROPERTIES CODE_SIGN_IDENTITY ""
  207. DEVELOPMENT_TEAM ""
  208. SKIP_INSTALL YES
  209. PRODUCT_NAME ${target}
  210. PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}
  211. CURRENT_PROJECT_VERSION ${OBS_BUILD_NUMBER}
  212. MARKETING_VERSION ${OBS_VERSION_CANONICAL}
  213. GENERATE_INFOPLIST_FILE YES
  214. INFOPLIST_FILE ""
  215. INFOPLIST_KEY_CFBundleDisplayName ${target}
  216. INFOPLIST_KEY_NSHumanReadableCopyright "(c) 2012-${CURRENT_YEAR} Lain Bailey"
  217. )
  218. endif()
  219. set_property(GLOBAL APPEND PROPERTY _OBS_FRAMEWORKS ${target})
  220. set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target})
  221. elseif(target_type STREQUAL MODULE_LIBRARY)
  222. if(target STREQUAL obspython)
  223. set_target_xcode_properties(
  224. ${target}
  225. PROPERTIES PRODUCT_NAME ${target}
  226. PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}
  227. )
  228. elseif(target STREQUAL obslua)
  229. set_target_xcode_properties(
  230. ${target}
  231. PROPERTIES PRODUCT_NAME ${target}
  232. PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}
  233. )
  234. elseif(target STREQUAL obs-dal-plugin)
  235. set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
  236. set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target})
  237. return()
  238. else()
  239. set_target_properties(${target} PROPERTIES BUNDLE TRUE BUNDLE_EXTENSION plugin)
  240. set_target_xcode_properties(
  241. ${target}
  242. PROPERTIES PRODUCT_NAME ${target}
  243. PRODUCT_BUNDLE_IDENTIFIER com.obsproject.${target}
  244. CURRENT_PROJECT_VERSION ${OBS_BUILD_NUMBER}
  245. MARKETING_VERSION ${OBS_VERSION_CANONICAL}
  246. GENERATE_INFOPLIST_FILE YES
  247. INFOPLIST_KEY_CFBundleDisplayName ${target}
  248. INFOPLIST_KEY_NSHumanReadableCopyright "(c) 2012-${CURRENT_YEAR} Lain Bailey"
  249. )
  250. if(target STREQUAL obs-browser)
  251. # Good-enough for now as there are no other variants - in _theory_ we should only add the appropriate variant,
  252. # but that is only known at project generation and not build system configuration.
  253. get_target_property(imported_location CEF::Library IMPORTED_LOCATION_RELEASE)
  254. if(imported_location)
  255. list(APPEND cef_items "${imported_location}")
  256. endif()
  257. foreach(helper IN ITEMS _gpu _plugin _renderer "")
  258. if(TARGET OBS::browser-helper${helper})
  259. set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES OBS::browser-helper${helper})
  260. list(APPEND cef_items OBS::browser-helper${helper})
  261. endif()
  262. endforeach()
  263. set_property(GLOBAL APPEND PROPERTY _OBS_FRAMEWORKS ${cef_items})
  264. endif()
  265. endif()
  266. set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target})
  267. set_property(GLOBAL APPEND PROPERTY _OBS_DEPENDENCIES ${target})
  268. endif()
  269. target_install_resources(${target})
  270. get_target_property(target_sources ${target} SOURCES)
  271. set(target_ui_files ${target_sources})
  272. list(FILTER target_ui_files INCLUDE REGEX ".+\\.(ui|qrc)")
  273. source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "UI Files" FILES ${target_ui_files})
  274. if(${target} STREQUAL libobs)
  275. set(target_source_files ${target_sources})
  276. set(target_header_files ${target_sources})
  277. list(FILTER target_source_files INCLUDE REGEX ".+\\.(m|c[cp]?p?|swift)")
  278. list(FILTER target_header_files INCLUDE REGEX ".+\\.h(pp)?")
  279. source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Source Files" FILES ${target_source_files})
  280. source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Header Files" FILES ${target_header_files})
  281. endif()
  282. endfunction()
  283. # _check_entitlements: Macro to check if project ships with entitlements plist
  284. macro(_check_entitlements)
  285. if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist")
  286. message(FATAL_ERROR "Target ${target} is missing an entitlements.plist in its cmake directory.")
  287. endif()
  288. endmacro()
  289. # _add_entitlements: Macro to add entitlements shipped with project
  290. macro(_add_entitlements)
  291. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist")
  292. set_target_xcode_properties(
  293. ${target}
  294. PROPERTIES CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist"
  295. )
  296. endif()
  297. endmacro()
  298. # target_export: Helper function to export target as CMake package
  299. function(target_export target)
  300. # Exclude CMake package from 'ALL' target
  301. set(exclude_variant EXCLUDE_FROM_ALL)
  302. _target_export(${target})
  303. endfunction()
  304. # target_install_resources: Helper function to add resources into bundle
  305. function(target_install_resources target)
  306. message(DEBUG "Installing resources for target ${target}...")
  307. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data")
  308. file(GLOB_RECURSE data_files "${CMAKE_CURRENT_SOURCE_DIR}/data/*")
  309. list(FILTER data_files EXCLUDE REGEX "\\.DS_Store$")
  310. foreach(data_file IN LISTS data_files)
  311. cmake_path(
  312. RELATIVE_PATH
  313. data_file
  314. BASE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/"
  315. OUTPUT_VARIABLE relative_path
  316. )
  317. cmake_path(GET relative_path PARENT_PATH relative_path)
  318. target_sources(${target} PRIVATE "${data_file}")
  319. set_property(SOURCE "${data_file}" PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${relative_path}")
  320. source_group("Resources/${relative_path}" FILES "${data_file}")
  321. endforeach()
  322. endif()
  323. endfunction()
  324. # target_add_resource: Helper function to add a specific resource to a bundle
  325. function(target_add_resource target resource)
  326. message(DEBUG "Add resource ${resource} to target ${target} at destination ${destination}...")
  327. target_sources(${target} PRIVATE "${resource}")
  328. set_property(SOURCE "${resource}" PROPERTY MACOSX_PACKAGE_LOCATION Resources)
  329. source_group("Resources" FILES "${resource}")
  330. endfunction()
  331. # _bundle_dependencies: Resolve 3rd party dependencies and add them to macOS app bundle
  332. function(_bundle_dependencies target)
  333. message(DEBUG "Discover dependencies of target ${target}...")
  334. set(found_dependencies)
  335. find_dependencies(TARGET ${target} FOUND_VAR found_dependencies)
  336. get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED)
  337. list(LENGTH obs_module_list num_modules)
  338. if(num_modules GREATER 0)
  339. add_dependencies(${target} ${obs_module_list})
  340. set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_PLUGINS ${obs_module_list})
  341. foreach(module IN LISTS obs_module_list)
  342. find_dependencies(TARGET ${module} FOUND_VAR found_dependencies)
  343. endforeach()
  344. endif()
  345. list(REMOVE_DUPLICATES found_dependencies)
  346. set(library_paths)
  347. set(plugins_list)
  348. file(GLOB sdk_library_paths /Applications/Xcode*.app)
  349. set(system_library_path "/usr/lib/")
  350. foreach(library IN LISTS found_dependencies)
  351. get_target_property(library_type ${library} TYPE)
  352. get_target_property(is_framework ${library} FRAMEWORK)
  353. get_target_property(is_imported ${library} IMPORTED)
  354. if(is_imported)
  355. get_target_property(imported_location ${library} LOCATION)
  356. if(NOT imported_location)
  357. continue()
  358. endif()
  359. set(is_xcode_framework FALSE)
  360. set(is_system_framework FALSE)
  361. foreach(sdk_library_path IN LISTS sdk_library_paths)
  362. if(is_xcode_framework)
  363. break()
  364. endif()
  365. cmake_path(IS_PREFIX sdk_library_path "${imported_location}" is_xcode_framework)
  366. endforeach()
  367. cmake_path(IS_PREFIX system_library_path "${imported_location}" is_system_framework)
  368. if(is_system_framework OR is_xcode_framework)
  369. continue()
  370. elseif(is_framework)
  371. file(REAL_PATH "../../.." library_location BASE_DIRECTORY "${imported_location}")
  372. elseif(NOT library_type STREQUAL "STATIC_LIBRARY")
  373. if(NOT imported_location MATCHES ".+\\.a")
  374. set(library_location "${imported_location}")
  375. else()
  376. continue()
  377. endif()
  378. else()
  379. continue()
  380. endif()
  381. if(library MATCHES "Qt6?::.+")
  382. find_qt_plugins(COMPONENT ${library} TARGET ${target} FOUND_VAR plugins_list)
  383. endif()
  384. list(APPEND library_paths ${library_location})
  385. elseif(NOT is_imported AND library_type STREQUAL "SHARED_LIBRARY")
  386. list(APPEND library_paths ${library})
  387. endif()
  388. endforeach()
  389. list(REMOVE_DUPLICATES plugins_list)
  390. foreach(plugin IN LISTS plugins_list)
  391. cmake_path(GET plugin PARENT_PATH plugin_path)
  392. set(plugin_base_dir "${plugin_path}/../")
  393. cmake_path(SET plugin_stem_dir NORMALIZE "${plugin_base_dir}")
  394. cmake_path(RELATIVE_PATH plugin_path BASE_DIRECTORY "${plugin_stem_dir}" OUTPUT_VARIABLE plugin_file_name)
  395. target_sources(${target} PRIVATE "${plugin}")
  396. set_source_files_properties(
  397. "${plugin}"
  398. PROPERTIES MACOSX_PACKAGE_LOCATION "plugins/${plugin_file_name}" XCODE_FILE_ATTRIBUTES "CodeSignOnCopy"
  399. )
  400. source_group("Qt plugins" FILES "${plugin}")
  401. endforeach()
  402. list(REMOVE_DUPLICATES library_paths)
  403. set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_FRAMEWORKS ${library_paths})
  404. endfunction()