diff options
Diffstat (limited to 'cmake/QtToolHelpers.cmake')
| -rw-r--r-- | cmake/QtToolHelpers.cmake | 336 |
1 files changed, 281 insertions, 55 deletions
diff --git a/cmake/QtToolHelpers.cmake b/cmake/QtToolHelpers.cmake index fe568d09ee6..5d531818ebd 100644 --- a/cmake/QtToolHelpers.cmake +++ b/cmake/QtToolHelpers.cmake @@ -360,21 +360,181 @@ echo. > ${target_bin_dir}/${target}_try_run_passed" DEPENDS ${target_bin_dir}/${target}_try_run_passed) endfunction() +# Create a standalone FooTools package, similar to the ones automatically generated by +# qt_internal_add_module, e.g. Core -> CoreTools. +# +# A standalone tools package can be useful when one wants to associate some special targets and +# cmake scripts to a package that is not associated with any Qt module, and is not architecture +# dependent (e.g. java binaries). +# +# Arguments +# PACKAGE_BASE_NAME - base name of the package, e.g. for a value of Foo, it will create a +# Qt6FooToolsConfig.cmake file. +# +# PACKAGE_VERSION - version to use for the package, defaults to PROJECT_VERSION. +# +# EXTRA_CMAKE_FILES - list of additional cmake files to install alongside the package +# +# EXTRA_CMAKE_INCLUDES - list of cmake files to include in the package config file +# +# EXTRA_CMAKE_STATEMENTS - list of additional cmake statements (strings) to append to the end of +# the package config file. +# +# TOOL_TARGETS - list of add_executable targets that should be install(EXPORT)ed for this package. +# It can NOT take imported targets or custom targets. +# +# TOOL_PACKAGE_DEPENDENCIES - list of other Qt Tools package dependencies that should be +# find_package'd when using this Tools package. +function(qt_internal_add_tools_package) + set(opt_args "") + set(single_args + PACKAGE_BASE_NAME + PACKAGE_VERSION + ) + set(multi_args + EXTRA_CMAKE_FILES + EXTRA_CMAKE_INCLUDES + EXTRA_CMAKE_STATEMENTS + TOOL_TARGETS + TOOL_PACKAGE_DEPENDENCIES + ) + cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}") + _qt_internal_validate_all_args_are_parsed(arg) + + if(NOT arg_PACKAGE_BASE_NAME) + message(FATAL_ERROR "Missing PACKAGE_BASE_NAME value") + endif() + + if(arg_PACKAGE_VERSION) + set(tools_package_version "${arg_PACKAGE_VERSION}") + else() + set(tools_package_version "${PROJECT_VERSION}") + endif() + + set(id "${arg_PACKAGE_BASE_NAME}") + _qt_internal_append_to_cmake_property_without_duplicates(_qt_standalone_tool_packages "${id}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_package_base_name "${id}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_version + "${tools_package_version}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_list_dir + "${CMAKE_CURRENT_LIST_DIR}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_extra_cmake_files + "${arg_EXTRA_CMAKE_FILES}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_extra_cmake_includes + "${arg_EXTRA_CMAKE_INCLUDES}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_extra_cmake_statements + "${arg_EXTRA_CMAKE_STATEMENTS}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_tool_targets + "${arg_TOOL_TARGETS}") + + set_property(GLOBAL PROPERTY _qt_standalone_tool_package_${id}_tool_package_dependencies + "${arg_TOOL_PACKAGE_DEPENDENCIES}") +endfunction() + +# Creates a FooTools package with information about tool targets. +# The source of information for the created package is taken either from a Qt module and its +# tool targets, or from global properties associated with a standalone tools package. function(qt_export_tools module_name) + set(opt_args "") + set(single_args + MODULE_NAME + PACKAGE_BASE_NAME + ) + set(multi_args "") + cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}") + _qt_internal_validate_all_args_are_parsed(arg) + # Bail out when not building tools. if(NOT QT_WILL_BUILD_TOOLS) return() endif() - # If no tools were defined belonging to this module, don't create a config and targets file. - if(NOT "${module_name}" IN_LIST QT_KNOWN_MODULES_WITH_TOOLS) - return() + if(NOT arg_MODULE_NAME AND NOT arg_PACKAGE_BASE_NAME) + message(FATAL_ERROR "Either MODULE_NAME or PACKAGE_BASE_NAME must be specified") endif() - # The tools target name. For example: CoreTools - set(target "${module_name}Tools") + # Qt module case. + if(arg_MODULE_NAME) + # The tools package name. For example: CoreTools + set(module_name "${arg_MODULE_NAME}") + + # If no tools were defined belonging to this module, don't create a config and targets file. + if(NOT "${module_name}" IN_LIST QT_KNOWN_MODULES_WITH_TOOLS) + return() + endif() + + set(package_name "${module_name}Tools") + set(known_tools ${QT_KNOWN_MODULE_${module_name}_TOOLS}) + endif() + + # Standalone package case. + if(arg_PACKAGE_BASE_NAME) + set(package_name "${arg_PACKAGE_BASE_NAME}Tools") + + set(id "${arg_PACKAGE_BASE_NAME}") + + get_cmake_property(standalone_tools_package_version + _qt_standalone_tool_package_${id}_version) + if(NOT standalone_tools_package_version) + message(FATAL_ERROR "Missing version for standalone tools package ${id}") + endif() + + get_cmake_property(standalone_tools_list_dir + _qt_standalone_tool_package_${id}_list_dir) + if(NOT standalone_tools_list_dir) + set(standalone_tools_list_dir "") + endif() + + get_cmake_property(package_extra_cmake_files + _qt_standalone_tool_package_${id}_extra_cmake_files) + if(NOT package_extra_cmake_files) + set(package_extra_cmake_files "") + endif() - set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}") + get_cmake_property(package_extra_cmake_includes + _qt_standalone_tool_package_${id}_extra_cmake_includes) + if(NOT package_extra_cmake_includes) + set(package_extra_cmake_includes "") + endif() + + get_cmake_property(package_extra_cmake_statements + _qt_standalone_tool_package_${id}_extra_cmake_statements) + if(NOT package_extra_cmake_statements) + set(package_extra_cmake_statements "") + endif() + + get_cmake_property(known_tools _qt_standalone_tool_package_${id}_tool_targets) + if(NOT known_tools) + set(known_tools "") + endif() + + get_cmake_property(tool_package_dependencies + _qt_standalone_tool_package_${id}_tool_package_dependencies) + if(NOT tool_package_dependencies) + set(tool_package_dependencies "") + endif() + + get_cmake_property(third_party_package_dependencies + _qt_standalone_tool_package_${id}_third_party_dependencies) + if(NOT third_party_package_dependencies) + set(third_party_package_dependencies "") + endif() + + unset(id) + endif() + + # This is used as a substitution variable, ala @target@ in the config / dependencies / + # etc files. + set(target ${package_name}) + + set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${package_name}") qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix}) qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix}) @@ -395,7 +555,16 @@ function(qt_export_tools module_name) set(first_tool_package_version "") - set(known_tools ${QT_KNOWN_MODULE_${module_name}_TOOLS}) + if(package_extra_cmake_files) + list(APPEND extra_cmake_files ${package_extra_cmake_files}) + foreach(cmake_file ${package_extra_cmake_files}) + file(COPY "${cmake_file}" DESTINATION "${config_build_dir}") + endforeach() + endif() + + if(package_extra_cmake_includes) + list(APPEND extra_cmake_includes ${package_extra_cmake_includes}) + endif() foreach(tool_name IN LISTS known_tools) # Specific tools can have package dependencies. @@ -429,9 +598,10 @@ function(qt_export_tools module_name) if (QT_WILL_RENAME_TOOL_TARGETS) string(REGEX REPLACE "_native$" "" tool_name ${tool_name}) endif() - # `__qt_${target}_targets_file_included` is defined in the QtModuleToolsConfig.cmake.in + # `__qt_${package_name}_targets_file_included` is defined in the + # QtModuleToolsConfig.cmake.in set(extra_cmake_statements "${extra_cmake_statements} -if(__qt_${target}_targets_file_included AND ${INSTALL_CMAKE_NAMESPACE}${target}_FOUND) +if(__qt_${package_name}_targets_file_included AND ${INSTALL_CMAKE_NAMESPACE}${package_name}_FOUND) __qt_internal_promote_target_to_global(${INSTALL_CMAKE_NAMESPACE}::${tool_name}) endif() ") @@ -446,29 +616,64 @@ endif() endif() endforeach() - string(APPEND extra_cmake_statements -"set(${QT_CMAKE_EXPORT_NAMESPACE}${module_name}Tools_TARGETS \"${tool_targets}\")") + if(tool_targets) + string(APPEND extra_cmake_statements +"set(${QT_CMAKE_EXPORT_NAMESPACE}${package_name}Tools_TARGETS \"${tool_targets}\")") + endif() + + if(package_extra_cmake_statements) + foreach(statement ${package_extra_cmake_statements}) + string(APPEND extra_cmake_statements "\n${statement}") + endforeach() + endif() # Extract package dependencies that were determined in QtPostProcess, but only if ${module_name} # is an actual target. # module_name can be a non-existent target, if the tool doesn't have an existing associated # module, e.g. qtwaylandscanner. - if(TARGET "${module_name}") + if(module_name AND TARGET "${module_name}") get_target_property(module_package_deps "${module_name}" _qt_tools_package_deps) if(module_package_deps) list(APPEND package_deps "${module_package_deps}") endif() endif() - # Configure and install dependencies file for the ${module_name}Tools package. + if(tool_package_dependencies) + list(APPEND package_deps "${tool_package_dependencies}") + endif() + + if(third_party_package_dependencies) + foreach(third_party_dep IN LISTS third_party_package_dependencies) + list(GET third_party_dep 0 third_party_dep_name) + list(GET third_party_dep 1 third_party_dep_version) + + # Assume that all tool thirdparty deps are mandatory. + # TODO: Components are not supported + list(APPEND third_party_deps + "${third_party_dep_name}\\\;FALSE\\\;${third_party_dep_version}\\\;\\\;") + endforeach() + endif() + + # Generate ConfigExtras.cmake if a template exists. Include it first. + set(config_extras_path_in + "${standalone_tools_list_dir}/${path_suffix}ConfigExtras.cmake.in") + if(EXISTS "${config_extras_path_in}") + configure_file("${config_extras_path_in}" + "${config_build_dir}/${path_suffix}ConfigExtras.cmake" + @ONLY) + list(PREPEND extra_cmake_files "${config_build_dir}/${path_suffix}ConfigExtras.cmake") + list(PREPEND extra_cmake_includes "${path_suffix}ConfigExtras.cmake") + endif() + + # Configure and install dependencies file for the ${package_name}Tools package. configure_file( "${QT_CMAKE_DIR}/QtModuleToolsDependencies.cmake.in" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Dependencies.cmake" @ONLY ) qt_install(FILES - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Dependencies.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) @@ -481,29 +686,43 @@ endif() ) endif() - # Configure and install the ${module_name}Tools package Config file. + # Used in the template. + set(QT_SHOULD_INCLUDE_TARGETS_CODE FALSE) + if(known_tools) + set(QT_SHOULD_INCLUDE_TARGETS_CODE TRUE) + endif() + + # Configure and install the ${package_name}Tools package Config file. qt_internal_get_min_new_policy_cmake_version(min_new_policy_version) qt_internal_get_max_new_policy_cmake_version(max_new_policy_version) configure_package_config_file( "${QT_CMAKE_DIR}/QtModuleToolsConfig.cmake.in" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Config.cmake" INSTALL_DESTINATION "${config_install_dir}" ) - qt_configure_file( - OUTPUT "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" - CONTENT + if(known_tools) + qt_configure_file( + OUTPUT + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}TargetsPrecheck.cmake" + CONTENT "_qt_internal_should_include_targets( TARGETS ${known_tools} NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: - OUT_VAR_SHOULD_SKIP __qt_${target}_skip_include_targets_file + OUT_VAR_SHOULD_SKIP __qt_${package_name}_skip_include_targets_file ) ") + endif() - # There might be Tools packages which don't have a corresponding real module_name target, like - # WaylandScannerTools. - # In that case we'll use the package version of the first tool that belongs to that package. - if(TARGET "${module_name}") + # There are multiple sources where a tools' package version can come from. + # For a standalone tools package, it is explicitly given. + # For a package associated with a Qt module, it comes from a module. + # For a package without a Qt module, like WaylandScannerTools, + # we'll use the package version of the first tool that belongs to that package. + if(standalone_tools_package_version) + # Use the explicitly given package version. + set(tools_package_version "${standalone_tools_package_version}") + elseif(TARGET "${module_name}") qt_internal_get_package_version_of_target("${module_name}" tools_package_version) elseif(first_tool_package_version) set(tools_package_version "${first_tool_package_version}") @@ -513,56 +732,63 @@ endif() set(tools_package_version "${PROJECT_VERSION}") if(FEATURE_developer_build) message(WARNING - "Could not determine package version of tools package ${module_name}. " + "Could not determine package version of tools package ${package_name}. " "Defaulting to project version ${PROJECT_VERSION}.") endif() endif() message(TRACE - "Exporting tools package ${module_name}Tools with package version ${tools_package_version}" + "Exporting tools package ${package_name}Tools with package version ${tools_package_version}" "\n included targets: ${tool_targets_non_prefixed}") write_basic_package_version_file( - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersionImpl.cmake" VERSION "${tools_package_version}" COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT ) qt_internal_write_qt_package_version_file( - "${INSTALL_CMAKE_NAMESPACE}${target}" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + "${INSTALL_CMAKE_NAMESPACE}${package_name}" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersion.cmake" ) qt_install(FILES - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}Config.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersion.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}ConfigVersionImpl.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) - set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets") - qt_install(EXPORT "${export_name}" - NAMESPACE "${QT_CMAKE_EXPORT_NAMESPACE}::" - DESTINATION "${config_install_dir}") - - qt_internal_export_additional_targets_file( - TARGETS ${QT_KNOWN_MODULE_${module_name}_TOOLS} - TARGET_EXPORT_NAMES ${tool_targets} - EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} - CONFIG_INSTALL_DIR "${config_install_dir}") + if(known_tools) + qt_install(FILES + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}TargetsPrecheck.cmake" + DESTINATION "${config_install_dir}" + COMPONENT Devel + ) - # Create versionless targets file. - configure_file( - "${QT_CMAKE_DIR}/QtModuleToolsVersionlessTargets.cmake.in" - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}VersionlessTargets.cmake" - @ONLY - ) + set(export_name "${INSTALL_CMAKE_NAMESPACE}${package_name}Targets") + qt_install(EXPORT "${export_name}" + NAMESPACE "${QT_CMAKE_EXPORT_NAMESPACE}::" + DESTINATION "${config_install_dir}") + + qt_internal_export_additional_targets_file( + TARGETS ${known_tools} + TARGET_EXPORT_NAMES ${tool_targets} + EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${package_name} + CONFIG_INSTALL_DIR "${config_install_dir}") + + # Create versionless targets file. + configure_file( + "${QT_CMAKE_DIR}/QtModuleToolsVersionlessTargets.cmake.in" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}VersionlessTargets.cmake" + @ONLY + ) - qt_install(FILES - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}VersionlessTargets.cmake" - DESTINATION "${config_install_dir}" - COMPONENT Devel - ) + qt_install(FILES + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${package_name}VersionlessTargets.cmake" + DESTINATION "${config_install_dir}" + COMPONENT Devel + ) + endif() endfunction() # Returns the target name for the tool with the given name. |
