diff options
author | Leander Beernaert <leander.beernaert@qt.io> | 2020-04-17 14:36:09 +0200 |
---|---|---|
committer | Leander Beernaert <leander.beernaert@qt.io> | 2020-04-20 13:38:53 +0200 |
commit | dc4e5af752810d4f02b0485ecef2f1247b22beaa (patch) | |
tree | 7eae0b7b1b923d864e78515168b76a9944fb0e42 | |
parent | dac9548a67364eb1edd9ed6805369deac67ab9b1 (diff) |
CMake: Move Resources API into Qt6CoreMacros
Move QT6_ADD_RESOURCE to Qt6CoreMacros in order to avoid the extra
config file step.
Change-Id: Ib445ca35c648cf344ee8795de8bdddc0f0758972
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r-- | cmake/QtBaseGlobalTargets.cmake | 10 | ||||
-rw-r--r-- | cmake/QtResource.cmake.in | 187 | ||||
-rw-r--r-- | src/corelib/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/corelib/Qt6CoreMacros.cmake | 184 |
4 files changed, 184 insertions, 202 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index ddee9c63c2..a64a91a193 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -331,13 +331,3 @@ if(MACOS) DESTINATION "${__GlobalConfig_install_dir}/macos" ) endif() - -# Generate the new resource API -set(QT_CORE_RESOURCE_GENERATED_FILE_NAME "${INSTALL_CMAKE_NAMESPACE}CoreResource.cmake" CACHE INTERNAL "") -set(QT_CORE_RESOURCE_GENERATED_FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${QT_CORE_RESOURCE_GENERATED_FILE_NAME}" CACHE INTERNAL "") -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtResource.cmake.in" - "${QT_CORE_RESOURCE_GENERATED_FILE_PATH}" - @ONLY -) -include(${QT_CORE_RESOURCE_GENERATED_FILE_PATH}) diff --git a/cmake/QtResource.cmake.in b/cmake/QtResource.cmake.in deleted file mode 100644 index 23c085bc63..0000000000 --- a/cmake/QtResource.cmake.in +++ /dev/null @@ -1,187 +0,0 @@ -# -# All things resource related -# - -function(__qt_get_relative_resource_path_for_file output_alias file) - get_property(alias SOURCE ${file} PROPERTY QT_RESOURCE_ALIAS) - if (NOT alias) - set(alias "${file}") - endif() - set(${output_alias} ${alias} PARENT_SCOPE) -endfunction() - -function(__qt_propagate_generated_resource target resource_name generated_source_code output_generated_target) - get_target_property(type ${target} TYPE) - if(type STREQUAL STATIC_LIBRARY) - set(resource_target "${target}_resources_${resourceName}") - add_library("${resource_target}" OBJECT "${generated_source_code}") - - # Use TARGET_NAME genex to map to the correct prefixed target name when it is exported - # via qt_install(EXPORT), so that the consumers of the target can find the object library - # as well. - target_link_libraries(${target} INTERFACE - "$<TARGET_OBJECTS:$<TARGET_NAME:${resource_target}>>") - set(${output_generated_target} "${resource_target}" PARENT_SCOPE) - else() - set(${output_generated_target} "" PARENT_SCOPE) - target_sources(${target} PRIVATE ${generated_source_code}) - endif() -endfunction() - - -# -# Process resources via file path instead of QRC files. Behind the -# scnenes, it will generate a qrc file and apply post processing steps -# when applicable. (e.g.: QtQuickCompiler) -# -# The QRC Prefix is set via the PREFIX parameter. -# -# Alias settings for files need to be set via the QT_RESOURCE_ALIAS property -# via the set_soure_files_properties() command. -# -# When using this command with static libraries, one or more special targets -# will be generated. Should you wish to perform additional processing on these -# targets pass a value to the OUTPUT_TARGETS parameter. -# -function(QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE target resourceName) - - cmake_parse_arguments(rcc "" "PREFIX;LANG;BASE;OUTPUT_TARGETS" "FILES;OPTIONS" ${ARGN}) - - string(REPLACE "/" "_" resourceName ${resourceName}) - string(REPLACE "." "_" resourceName ${resourceName}) - - set(output_targets "") - # Apply base to all files - if (rcc_BASE) - foreach(file IN LISTS rcc_FILES) - set(resource_file "${rcc_BASE}/${file}") - __qt_get_relative_resource_path_for_file(alias ${resource_file}) - # Handle case where resources were generated from a directory - # different than the one where the main .pro file resides. - # Unless otherwise specified, we should use the original file path - # as alias. - if (alias STREQUAL resource_file) - set_source_files_properties(${resource_file} PROPERTIES QT_RESOURCE_ALIAS ${file}) - endif() - file(TO_CMAKE_PATH ${resource_file} resource_file) - list(APPEND resource_files ${resource_file}) - endforeach() - else() - set(resource_files ${rcc_FILES}) - endif() - - if(NOT rcc_PREFIX) - get_target_property(rcc_PREFIX ${target} QT_RESOURCE_PREFIX) - if (NOT rcc_PREFIX) - message(FATAL_ERROR "QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE() was called without a PREFIX and the target does not provide QT_RESOURCE_PREFIX. Please either add a PREFIX or make the target ${target} provide a default.") - endif() - endif() - - # Apply quick compiler pass. This is only enabled when Qt6QmlMacros is - # parsed. - if (QT6_ADD_RESOURCE_DECLARATIVE_EXTENSIONS) - qt6_quick_compiler_process_resources(${target} ${resourceName} - FILES ${resource_files} - PREFIX ${rcc_PREFIX} - OUTPUT_REMAINING_RESOURCES resources - OUTPUT_RESOURCE_NAME newResourceName - OUTPUT_GENERATED_TARGET output_target_quick - ) - else() - set(newResourceName ${resourceName}) - set(resources ${resource_files}) - endif() - - if (NOT resources) - if (rcc_OUTPUT_TARGETS) - set(${rcc_OUTPUT_TARGETS} "${output_target_quick}" PARENT_SCOPE) - endif() - return() - endif() - list(APPEND output_targets ${output_target_quick}) - set(generatedResourceFile "${CMAKE_CURRENT_BINARY_DIR}/.rcc/generated_${newResourceName}.qrc") - set(generatedSourceCode "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qrc_${newResourceName}.cpp") - - # Generate .qrc file: - - # <RCC><qresource ...> - set(qrcContents "<RCC>\n <qresource") - if (rcc_PREFIX) - string(APPEND qrcContents " prefix=\"${rcc_PREFIX}\"") - endif() - if (rcc_LANG) - string(APPEND qrcContents " lang=\"${rcc_LANG}\"") - endif() - string(APPEND qrcContents ">\n") - - set(resource_dependencies) - foreach(file IN LISTS resources) - __qt_get_relative_resource_path_for_file(file_resource_path ${file}) - - if (NOT IS_ABSOLUTE ${file}) - set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}") - endif() - - ### FIXME: escape file paths to be XML conform - # <file ...>...</file> - string(APPEND qrcContents " <file alias=\"${file_resource_path}\">") - string(APPEND qrcContents "${file}</file>\n") - list(APPEND files "${file}") - - get_source_file_property(target_dependency ${file} QT_RESOURCE_TARGET_DEPENDENCY) - if (NOT target_dependency) - list(APPEND resource_dependencies ${file}) - else() - if (NOT TARGET ${target_dependency}) - message(FATAL_ERROR "Target dependency on resource file ${file} is not a cmake target.") - endif() - list(APPEND resource_dependencies ${target_dependency}) - endif() - endforeach() - - # </qresource></RCC> - string(APPEND qrcContents " </qresource>\n</RCC>\n") - - file(GENERATE OUTPUT "${generatedResourceFile}" CONTENT "${qrcContents}") - - set(rccArgs --name "${newResourceName}" - --output "${generatedSourceCode}" "${generatedResourceFile}") - if(rcc_OPTIONS) - list(APPEND rccArgs ${rcc_OPTIONS}) - endif() - - # When cross-building, we use host tools to generate target code. If the host rcc was compiled - # with zstd support, it expects the target QtCore to be able to decompress zstd compressed - # content. This might be true with qmake where host tools are built as part of the - # cross-compiled Qt, but with CMake we build tools separate from the cross-compiled Qt. - # If the target does not support zstd (feature is disabled), tell rcc not to generate - # zstd related code. - if(NOT QT_FEATURE_zstd) - list(APPEND rccArgs "--no-zstd") - endif() - - # Process .qrc file: - add_custom_command(OUTPUT "${generatedSourceCode}" - COMMAND "@QT_CMAKE_EXPORT_NAMESPACE@::rcc" - ARGS ${rccArgs} - DEPENDS - ${resource_dependencies} - ${generatedResourceFile} - "@QT_CMAKE_EXPORT_NAMESPACE@::rcc" - COMMENT "RCC ${newResourceName}" - VERBATIM) - - get_target_property(type "${target}" TYPE) - # Only do this if newResourceName is the same as resourceName, since - # the resource will be chainloaded by the qt quickcompiler - # qml cache loader - if(newResourceName STREQUAL resourceName) - __qt_propagate_generated_resource(${target} ${resourceName} "${generatedSourceCode}" output_target) - list(APPEND output_targets ${output_target}) - else() - target_sources(${target} PRIVATE "${generatedSourceCode}") - endif() - if (rcc_OUTPUT_TARGETS) - set(${rcc_OUTPUT_TARGETS} "${output_targets}" PARENT_SCOPE) - endif() -endfunction() diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index e71c8c8c2d..911772faca 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -253,11 +253,6 @@ qt_add_module(Core Threads::Threads # special case PUBLIC_LIBRARIES # special case: Qt::Platform # special case: - # special case begin - # Generated in QtBaseGlobalTargets - EXTRA_CMAKE_FILES ${QT_CORE_RESOURCE_GENERATED_FILE_PATH} - EXTRA_CMAKE_INCLUDES ${QT_CORE_RESOURCE_GENERATED_FILE_NAME} - # special case end ) # special case begin diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index 8e9721ef66..29b3239215 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -951,3 +951,187 @@ END target_sources(${target} PRIVATE ${target_rc_file}) endfunction() + +function(__qt_get_relative_resource_path_for_file output_alias file) + get_property(alias SOURCE ${file} PROPERTY QT_RESOURCE_ALIAS) + if (NOT alias) + set(alias "${file}") + endif() + set(${output_alias} ${alias} PARENT_SCOPE) +endfunction() + +function(__qt_propagate_generated_resource target resource_name generated_source_code output_generated_target) + get_target_property(type ${target} TYPE) + if(type STREQUAL STATIC_LIBRARY) + set(resource_target "${target}_resources_${resourceName}") + add_library("${resource_target}" OBJECT "${generated_source_code}") + + # Use TARGET_NAME genex to map to the correct prefixed target name when it is exported + # via qt_install(EXPORT), so that the consumers of the target can find the object library + # as well. + target_link_libraries(${target} INTERFACE + "$<TARGET_OBJECTS:$<TARGET_NAME:${resource_target}>>") + set(${output_generated_target} "${resource_target}" PARENT_SCOPE) + else() + set(${output_generated_target} "" PARENT_SCOPE) + target_sources(${target} PRIVATE ${generated_source_code}) + endif() +endfunction() + + +# +# Process resources via file path instead of QRC files. Behind the +# scnenes, it will generate a qrc file and apply post processing steps +# when applicable. (e.g.: QtQuickCompiler) +# +# The QRC Prefix is set via the PREFIX parameter. +# +# Alias settings for files need to be set via the QT_RESOURCE_ALIAS property +# via the set_soure_files_properties() command. +# +# When using this command with static libraries, one or more special targets +# will be generated. Should you wish to perform additional processing on these +# targets pass a value to the OUTPUT_TARGETS parameter. +# +function(QT6_PROCESS_RESOURCE target resourceName) + + cmake_parse_arguments(rcc "" "PREFIX;LANG;BASE;OUTPUT_TARGETS" "FILES;OPTIONS" ${ARGN}) + + string(REPLACE "/" "_" resourceName ${resourceName}) + string(REPLACE "." "_" resourceName ${resourceName}) + + set(output_targets "") + # Apply base to all files + if (rcc_BASE) + foreach(file IN LISTS rcc_FILES) + set(resource_file "${rcc_BASE}/${file}") + __qt_get_relative_resource_path_for_file(alias ${resource_file}) + # Handle case where resources were generated from a directory + # different than the one where the main .pro file resides. + # Unless otherwise specified, we should use the original file path + # as alias. + if (alias STREQUAL resource_file) + set_source_files_properties(${resource_file} PROPERTIES QT_RESOURCE_ALIAS ${file}) + endif() + file(TO_CMAKE_PATH ${resource_file} resource_file) + list(APPEND resource_files ${resource_file}) + endforeach() + else() + set(resource_files ${rcc_FILES}) + endif() + + if(NOT rcc_PREFIX) + get_target_property(rcc_PREFIX ${target} QT_RESOURCE_PREFIX) + if (NOT rcc_PREFIX) + message(FATAL_ERROR "QT6_PROCESS_RESOURCE() was called without a PREFIX and the target does not provide QT_RESOURCE_PREFIX. Please either add a PREFIX or make the target ${target} provide a default.") + endif() + endif() + + # Apply quick compiler pass. This is only enabled when Qt6QmlMacros is + # parsed. + if (QT6_ADD_RESOURCE_DECLARATIVE_EXTENSIONS) + qt6_quick_compiler_process_resources(${target} ${resourceName} + FILES ${resource_files} + PREFIX ${rcc_PREFIX} + OUTPUT_REMAINING_RESOURCES resources + OUTPUT_RESOURCE_NAME newResourceName + OUTPUT_GENERATED_TARGET output_target_quick + ) + else() + set(newResourceName ${resourceName}) + set(resources ${resource_files}) + endif() + + if (NOT resources) + if (rcc_OUTPUT_TARGETS) + set(${rcc_OUTPUT_TARGETS} "${output_target_quick}" PARENT_SCOPE) + endif() + return() + endif() + list(APPEND output_targets ${output_target_quick}) + set(generatedResourceFile "${CMAKE_CURRENT_BINARY_DIR}/.rcc/generated_${newResourceName}.qrc") + set(generatedSourceCode "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qrc_${newResourceName}.cpp") + + # Generate .qrc file: + + # <RCC><qresource ...> + set(qrcContents "<RCC>\n <qresource") + if (rcc_PREFIX) + string(APPEND qrcContents " prefix=\"${rcc_PREFIX}\"") + endif() + if (rcc_LANG) + string(APPEND qrcContents " lang=\"${rcc_LANG}\"") + endif() + string(APPEND qrcContents ">\n") + + set(resource_dependencies) + foreach(file IN LISTS resources) + __qt_get_relative_resource_path_for_file(file_resource_path ${file}) + + if (NOT IS_ABSOLUTE ${file}) + set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}") + endif() + + ### FIXME: escape file paths to be XML conform + # <file ...>...</file> + string(APPEND qrcContents " <file alias=\"${file_resource_path}\">") + string(APPEND qrcContents "${file}</file>\n") + list(APPEND files "${file}") + + get_source_file_property(target_dependency ${file} QT_RESOURCE_TARGET_DEPENDENCY) + if (NOT target_dependency) + list(APPEND resource_dependencies ${file}) + else() + if (NOT TARGET ${target_dependency}) + message(FATAL_ERROR "Target dependency on resource file ${file} is not a cmake target.") + endif() + list(APPEND resource_dependencies ${target_dependency}) + endif() + endforeach() + + # </qresource></RCC> + string(APPEND qrcContents " </qresource>\n</RCC>\n") + + file(GENERATE OUTPUT "${generatedResourceFile}" CONTENT "${qrcContents}") + + set(rccArgs --name "${newResourceName}" + --output "${generatedSourceCode}" "${generatedResourceFile}") + if(rcc_OPTIONS) + list(APPEND rccArgs ${rcc_OPTIONS}) + endif() + + # When cross-building, we use host tools to generate target code. If the host rcc was compiled + # with zstd support, it expects the target QtCore to be able to decompress zstd compressed + # content. This might be true with qmake where host tools are built as part of the + # cross-compiled Qt, but with CMake we build tools separate from the cross-compiled Qt. + # If the target does not support zstd (feature is disabled), tell rcc not to generate + # zstd related code. + if(NOT QT_FEATURE_zstd) + list(APPEND rccArgs "--no-zstd") + endif() + + # Process .qrc file: + add_custom_command(OUTPUT "${generatedSourceCode}" + COMMAND "${QT_CMAKE_EXPORT_NAMESPACE}::rcc" + ARGS ${rccArgs} + DEPENDS + ${resource_dependencies} + ${generatedResourceFile} + "${QT_CMAKE_EXPORT_NAMESPACE}::rcc" + COMMENT "RCC ${newResourceName}" + VERBATIM) + + get_target_property(type "${target}" TYPE) + # Only do this if newResourceName is the same as resourceName, since + # the resource will be chainloaded by the qt quickcompiler + # qml cache loader + if(newResourceName STREQUAL resourceName) + __qt_propagate_generated_resource(${target} ${resourceName} "${generatedSourceCode}" output_target) + list(APPEND output_targets ${output_target}) + else() + target_sources(${target} PRIVATE "${generatedSourceCode}") + endif() + if (rcc_OUTPUT_TARGETS) + set(${rcc_OUTPUT_TARGETS} "${output_targets}" PARENT_SCOPE) + endif() +endfunction() |