summaryrefslogtreecommitdiffstats
path: root/cmake/QtResource.cmake.in
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtResource.cmake.in')
-rw-r--r--cmake/QtResource.cmake.in299
1 files changed, 299 insertions, 0 deletions
diff --git a/cmake/QtResource.cmake.in b/cmake/QtResource.cmake.in
new file mode 100644
index 0000000000..bef47707ea
--- /dev/null
+++ b/cmake/QtResource.cmake.in
@@ -0,0 +1,299 @@
+#
+# 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()
+
+# Inspect all files passed to a call to qt_add_resource. If there are any
+# files present, invoke the quick compiler and return the remaining resource
+# files that have not been processed in OUTPUT_REMAINING_RESOURCES as well as the new
+# name for the resource in OUTPUT_RESOURCE_NAME.
+function(__qt_quick_compiler_process_resources target resource_name)
+
+ cmake_parse_arguments(arg
+ "" "PREFIX;OUTPUT_REMAINING_RESOURCES;OUTPUT_RESOURCE_NAME;OUTPUT_GENERATED_TARGET" "FILES" ${ARGN}
+ )
+
+ set(qml_files)
+ set(resource_files)
+ # scan for qml files
+ foreach(file IN LISTS arg_FILES)
+ # check whether this resource should not be processed by the qt quick
+ # compiler
+ get_source_file_property(skip_compiler_check ${file} QT_SKIP_QUICKCOMPILER)
+ if (skip_compiler_check)
+ list(APPEND resource_files ${file})
+ continue()
+ endif()
+
+ if (${file} MATCHES "\.js$"
+ OR ${file} MATCHES "\.mjs$"
+ OR ${file} MATCHES "\.qml$")
+ list(APPEND qml_files ${file})
+ endif()
+ list(APPEND resource_files ${file})
+ endforeach()
+ if (NOT TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files)
+ message(WARNING "QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE: Qml files were detected but the qmlcachgen target is not defined. Consider adding QmlTools to your find_package command.")
+ endif()
+
+ if (TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files)
+ # Enable qt quick compiler support
+ set(qml_resource_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/${resource_name}.qrc")
+ if (resource_files)
+ set(chained_resource_name "${resource_name}_qmlcache")
+ endif()
+
+ foreach(file IN LISTS qml_files)
+ get_filename_component(file_absolute ${file} ABSOLUTE)
+ file(RELATIVE_PATH file_relative ${CMAKE_CURRENT_SOURCE_DIR} ${file_absolute})
+ __qt_get_relative_resource_path_for_file(file_resource_path ${file})
+ if (arg_PREFIX STREQUAL "/")
+ # TO_CMAKE_PATH does not clean up cases such as //Foo
+ set(file_resource_path "/${file_resource_path}")
+ else()
+ set(file_resource_path "${arg_PREFIX}/${file_resource_path}")
+ endif()
+ file(TO_CMAKE_PATH ${file_resource_path} file_resource_path)
+ list(APPEND file_resource_paths ${file_resource_path})
+ string(REGEX REPLACE "\.js$" "_js" compiled_file ${file_relative})
+ string(REGEX REPLACE "\.mjs$" "_mjs" compiled_file ${compiled_file})
+ string(REGEX REPLACE "\.qml$" "_qml" compiled_file ${compiled_file})
+ string(REGEX REPLACE "[\$#\?]+" "_" compiled_file ${compiled_file})
+ set(compiled_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/${compiled_file}.cpp")
+ get_filename_component(out_dir ${compiled_file} DIRECTORY)
+ if(NOT EXISTS ${out_dir})
+ file(MAKE_DIRECTORY ${out_dir})
+ endif()
+ add_custom_command(
+ OUTPUT ${compiled_file}
+ ${QT_TOOL_PATH_SETUP_COMMAND}
+ COMMAND
+ @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen
+ --resource-path "${file_resource_path}"
+ -o "${compiled_file}"
+ "${file_absolute}"
+ DEPENDS
+ $<TARGET_FILE:@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen>
+ "${file_absolute}"
+ )
+ target_sources(${target} PRIVATE ${compiled_file})
+ endforeach()
+
+ set(qmlcache_loader_list "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qml_loader_file_list.rsp")
+ file(GENERATE
+ OUTPUT ${qmlcache_loader_list}
+ CONTENT "$<JOIN:${file_resource_paths},\n>"
+ )
+
+ set(qmlcache_loader_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qmlcache_loader.cpp")
+ set(resource_name_arg "${resource_name}.qrc")
+ if (chained_resource_name)
+ set(resource_name_arg "${resource_name_arg}=${chained_resource_name}")
+ endif()
+
+ add_custom_command(
+ OUTPUT ${qmlcache_loader_file}
+ ${QT_TOOL_PATH_SETUP_COMMAND}
+ COMMAND
+ @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen
+ --resource-name "${resource_name_arg}"
+ -o "${qmlcache_loader_file}"
+ "@${qmlcache_loader_list}"
+ DEPENDS
+ $<TARGET_FILE:@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen>
+ "${qmlcache_loader_list}"
+ )
+
+ __qt_propagate_generated_resource(${target}
+ ${resource_name}
+ ${qmlcache_loader_file}
+ output_target)
+
+ set(${arg_OUTPUT_GENERATED_TARGET} "${output_target}" PARENT_SCOPE)
+
+ if (resource_files)
+ set(resource_name ${chained_resource_name})
+ endif()
+
+ # The generated qmlcache_loader source file uses private headers of Qml, so make sure
+ # if the object library was created, it depends on the Qml target. If there's no target,
+ # that means the target is a shared library and the sources are directly added to the target
+ # via target_sources, so add dependency in that case as well.
+ set(chosen_target "target") # shared library case
+ if(output_target)
+ set(chosen_target "output_target") # static library case.
+ endif()
+ target_link_libraries(${${chosen_target}} PRIVATE @QT_CMAKE_EXPORT_NAMESPACE@::Qml)
+ else()
+ set(resource_files ${arg_FILES})
+ endif()
+
+ set(${arg_OUTPUT_REMAINING_RESOURCES} ${resource_files} PARENT_SCOPE)
+ set(${arg_OUTPUT_RESOURCE_NAME} ${resource_name} PARENT_SCOPE)
+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
+ __qt_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
+ )
+
+ 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()
+
+ # 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()