diff options
Diffstat (limited to 'cmake/QtFrameworkHelpers.cmake')
-rw-r--r-- | cmake/QtFrameworkHelpers.cmake | 189 |
1 files changed, 146 insertions, 43 deletions
diff --git a/cmake/QtFrameworkHelpers.cmake b/cmake/QtFrameworkHelpers.cmake index 7a9cb6e75b..750caf2cb8 100644 --- a/cmake/QtFrameworkHelpers.cmake +++ b/cmake/QtFrameworkHelpers.cmake @@ -1,7 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + macro(qt_find_apple_system_frameworks) if(APPLE) qt_internal_find_apple_system_framework(FWAppKit AppKit) + qt_internal_find_apple_system_framework(FWCFNetwork CFNetwork) qt_internal_find_apple_system_framework(FWAssetsLibrary AssetsLibrary) + qt_internal_find_apple_system_framework(FWPhotos Photos) qt_internal_find_apple_system_framework(FWAudioToolbox AudioToolbox) qt_internal_find_apple_system_framework(FWApplicationServices ApplicationServices) qt_internal_find_apple_system_framework(FWCarbon Carbon) @@ -10,6 +15,7 @@ macro(qt_find_apple_system_frameworks) qt_internal_find_apple_system_framework(FWCoreGraphics CoreGraphics) qt_internal_find_apple_system_framework(FWCoreText CoreText) qt_internal_find_apple_system_framework(FWCoreVideo CoreVideo) + qt_internal_find_apple_system_framework(FWCryptoTokenKit CryptoTokenKit) qt_internal_find_apple_system_framework(FWDiskArbitration DiskArbitration) qt_internal_find_apple_system_framework(FWFoundation Foundation) qt_internal_find_apple_system_framework(FWIOBluetooth IOBluetooth) @@ -22,9 +28,16 @@ macro(qt_find_apple_system_frameworks) qt_internal_find_apple_system_framework(FWSecurity Security) qt_internal_find_apple_system_framework(FWSystemConfiguration SystemConfiguration) qt_internal_find_apple_system_framework(FWUIKit UIKit) - + qt_internal_find_apple_system_framework(FWCoreLocation CoreLocation) + qt_internal_find_apple_system_framework(FWCoreMotion CoreMotion) qt_internal_find_apple_system_framework(FWWatchKit WatchKit) qt_internal_find_apple_system_framework(FWGameController GameController) + qt_internal_find_apple_system_framework(FWCoreBluetooth CoreBluetooth) + qt_internal_find_apple_system_framework(FWAVFoundation AVFoundation) + qt_internal_find_apple_system_framework(FWContacts Contacts) + qt_internal_find_apple_system_framework(FWEventKit EventKit) + qt_internal_find_apple_system_framework(FWHealthKit HealthKit) + qt_internal_find_apple_system_framework(FWUniformTypeIdentifiers UniformTypeIdentifiers) endif() endmacro() @@ -47,7 +60,7 @@ function(qt_internal_find_apple_system_framework out_var framework_name) endif() endfunction() -# Copy header files to QtXYZ.framework/Versions/6/Headers/ +# Copy header files to the framework's Headers directory # Use this function for header files that # - are not added as source files to the target # - are not marked as PUBLIC_HEADER @@ -58,41 +71,92 @@ function(qt_copy_framework_headers target) return() endif() - set(options PUBLIC PRIVATE QPA) + set(options) set(oneValueArgs) - set(multiValueArgs) - cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - get_target_property(fw_version ${target} FRAMEWORK_VERSION) - get_target_property(fw_bundle_version ${target} MACOSX_FRAMEWORK_BUNDLE_VERSION) - get_target_property(fw_dir ${target} LIBRARY_OUTPUT_DIRECTORY) - get_target_property(fw_name ${target} OUTPUT_NAME) - set(fw_headers_dir ${fw_dir}/${fw_name}.framework/Versions/${fw_version}/Headers/) - if(ARG_PRIVATE) - string(APPEND fw_headers_dir "${fw_bundle_version}/Qt${target}/private/") - elseif(ARG_QPA) - string(APPEND fw_headers_dir "${fw_bundle_version}/Qt${target}/qpa/") - endif() + set(multiValueArgs PUBLIC PRIVATE QPA RHI SSG) + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - set(out_files) - foreach(hdr IN LISTS ARG_UNPARSED_ARGUMENTS) - get_filename_component(in_file_path ${hdr} ABSOLUTE) - get_filename_component(in_file_name ${hdr} NAME) - set(out_file_path ${fw_headers_dir}${in_file_name}) - add_custom_command( - OUTPUT ${out_file_path} - DEPENDS ${in_file_path} - COMMAND ${CMAKE_COMMAND} -E make_directory "${fw_headers_dir}" - COMMAND ${CMAKE_COMMAND} -E copy "${in_file_path}" "${fw_headers_dir}") - list(APPEND out_files ${out_file_path}) + qt_internal_get_framework_info(fw ${target}) + get_target_property(output_dir ${target} LIBRARY_OUTPUT_DIRECTORY) + set(output_dir_PUBLIC "${output_dir}/${fw_versioned_header_dir}") + set(output_dir_PRIVATE "${output_dir}/${fw_private_module_header_dir}/private") + set(output_dir_QPA "${output_dir}/${fw_private_module_header_dir}/qpa") + set(output_dir_RHI "${output_dir}/${fw_private_module_header_dir}/rhi") + set(output_dir_SSG "${output_dir}/${fw_private_module_header_dir}/ssg") + + qt_internal_module_info(module "${target}") + + set(out_files "") + set(in_files "") + set(out_dirs "") + set(copy_commands "") + foreach(type IN ITEMS PUBLIC PRIVATE QPA RHI SSG) + set(in_files_${type} "") + set(fw_output_header_dir "${output_dir_${type}}") + list(APPEND out_dirs "${fw_output_header_dir}") + foreach(hdr IN LISTS arg_${type}) + get_filename_component(in_file_path ${hdr} ABSOLUTE) + get_filename_component(in_file_name ${hdr} NAME) + set(out_file_path "${fw_output_header_dir}/${in_file_name}") + list(APPEND out_files ${out_file_path}) + list(APPEND in_files_${type} "${in_file_path}") + endforeach() + if(in_files_${type}) + list(APPEND copy_commands + COMMAND ${CMAKE_COMMAND} -E copy ${in_files_${type}} "${fw_output_header_dir}") + list(APPEND in_files ${in_files_${type}}) + endif() endforeach() - get_target_property(fw_copied_headers ${target} QT_COPIED_FRAMEWORK_HEADERS) - if(NOT fw_copied_headers) - set(fw_copied_headers "") + list(REMOVE_DUPLICATES out_files) + list(REMOVE_DUPLICATES in_files) + + set(copy_fw_sync_headers_command + "${CMAKE_COMMAND}" -E copy_directory + "${module_build_interface_include_dir}/.syncqt_staging" + "${output_dir}/${fw_versioned_header_dir}" + ) + + if(CMAKE_GENERATOR MATCHES "^Ninja") + add_custom_command( + OUTPUT "${output_dir}/${fw_versioned_header_dir}" + DEPENDS ${target}_sync_headers + COMMAND ${copy_fw_sync_headers_command} + VERBATIM + ) + add_custom_target(${target}_copy_fw_sync_headers + DEPENDS "${output_dir}/${fw_versioned_header_dir}") + else() + add_custom_target(${target}_copy_fw_sync_headers + COMMAND ${copy_fw_sync_headers_command}) + endif() + + if(out_files) + add_custom_command( + OUTPUT ${out_files} + DEPENDS ${target}_copy_fw_sync_headers ${in_files} + COMMAND + ${CMAKE_COMMAND} -E make_directory ${out_dirs} + ${copy_commands} + VERBATIM + COMMENT "Copy the ${target} header files to the framework directory" + ) + set_property(TARGET ${target} APPEND PROPERTY + QT_COPIED_FRAMEWORK_HEADERS "${out_files}") endif() - list(APPEND fw_copied_headers ${out_files}) - set_target_properties(${target} PROPERTIES QT_COPIED_FRAMEWORK_HEADERS "${fw_copied_headers}") +endfunction() + +function(qt_internal_generate_fake_framework_header target) + # Hack to create the "Headers" symlink in the framework: + # Create a fake header file and copy it into the framework by marking it as PUBLIC_HEADER. + # CMake now takes care of creating the symlink. + set(fake_header "${CMAKE_CURRENT_BINARY_DIR}/${target}_fake_header.h") + qt_internal_get_main_cmake_configuration(main_config) + file(GENERATE OUTPUT "${fake_header}" CONTENT "// ignore this file\n" + CONDITION "$<CONFIG:${main_config}>") + target_sources(${target} PRIVATE "${fake_header}") + set_source_files_properties("${fake_header}" PROPERTIES GENERATED ON) + set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER "${fake_header}") endfunction() function(qt_finalize_framework_headers_copy target) @@ -106,20 +170,59 @@ function(qt_finalize_framework_headers_copy target) endif() get_target_property(headers ${target} QT_COPIED_FRAMEWORK_HEADERS) if(headers) - # Hack to create the "Headers" symlink in the framework: - # Create a fake header file and copy it into the framework by marking it as PUBLIC_HEADER. - # CMake now takes care of creating the symlink. - set(fake_header ${target}_fake_header.h) - qt_get_main_cmake_configuration(main_config) - file(GENERATE OUTPUT ${fake_header} CONTENT "// ignore this file\n" - CONDITION "$<CONFIG:${main_config}>") - string(PREPEND fake_header "${CMAKE_CURRENT_BINARY_DIR}/") - target_sources(${target} PRIVATE ${fake_header}) - set_source_files_properties(${fake_header} PROPERTIES GENERATED ON) - set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER ${fake_header}) + qt_internal_generate_fake_framework_header(${target}) # Add a target, e.g. Core_framework_headers, that triggers the header copy. add_custom_target(${target}_framework_headers DEPENDS ${headers}) add_dependencies(${target} ${target}_framework_headers) endif() endfunction() + +# Collects the framework related information and paths from the target properties. +# Output variables: +# <out_var>_name framework base name, e.g. 'QtCore'. +# <out_var>_dir framework base directory, e.g. 'QtCore.framework'. +# <out_var>_version framework version, e.g. 'A', 'B' etc. +# <out_var>_bundle_version framework bundle version, same as the PROJECT_VERSION, e.g. '6.0.0'. +# <out_var>_header_dir top-level header directory, e.g. 'QtCore.framework/Headers'. +# <out_var>_versioned_header_dir header directory for specific framework version, +# e.g. 'QtCore.framework/Versions/A/Headers' +# <out_var>_private_header_dir header directory for the specific framework version and +# framework bundle version e.g. 'QtCore.framework/Versions/A/Headers/6.0.0' +# <out_var>_private_module_header_dir private header directory for the specific framework +# version, framework bundle version and tailing module name, e.g. +# 'QtCore.framework/Versions/A/Headers/6.0.0/Core' +function(qt_internal_get_framework_info out_var target) + get_target_property(${out_var}_version ${target} FRAMEWORK_VERSION) + get_target_property(${out_var}_bundle_version ${target} MACOSX_FRAMEWORK_BUNDLE_VERSION) + + # The module name might be different of the actual target name + # and we want to use the Qt'fied module name as a framework identifier. + get_target_property(module_interface_name ${target} _qt_module_interface_name) + if(module_interface_name) + qt_internal_qtfy_target(module ${module_interface_name}) + else() + qt_internal_qtfy_target(module ${target}) + endif() + + set(${out_var}_name "${module}") + set(${out_var}_dir "${${out_var}_name}.framework") + set(${out_var}_header_dir "${${out_var}_dir}/Headers") + if(UIKIT) + # iOS frameworks do not version their headers + set(${out_var}_versioned_header_dir "${${out_var}_header_dir}") + else() + set(${out_var}_versioned_header_dir "${${out_var}_dir}/Versions/${${out_var}_version}/Headers") + endif() + set(${out_var}_private_header_dir "${${out_var}_versioned_header_dir}/${${out_var}_bundle_version}") + set(${out_var}_private_module_header_dir "${${out_var}_private_header_dir}/${module}") + + set(${out_var}_name "${${out_var}_name}" PARENT_SCOPE) + set(${out_var}_dir "${${out_var}_dir}" PARENT_SCOPE) + set(${out_var}_header_dir "${${out_var}_header_dir}" PARENT_SCOPE) + set(${out_var}_version "${${out_var}_version}" PARENT_SCOPE) + set(${out_var}_bundle_version "${${out_var}_bundle_version}" PARENT_SCOPE) + set(${out_var}_versioned_header_dir "${${out_var}_versioned_header_dir}" PARENT_SCOPE) + set(${out_var}_private_header_dir "${${out_var}_private_header_dir}" PARENT_SCOPE) + set(${out_var}_private_module_header_dir "${${out_var}_private_module_header_dir}" PARENT_SCOPE) +endfunction() |