aboutsummaryrefslogtreecommitdiffstats
path: root/cmake/QtTopLevelHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtTopLevelHelpers.cmake')
-rw-r--r--cmake/QtTopLevelHelpers.cmake514
1 files changed, 444 insertions, 70 deletions
diff --git a/cmake/QtTopLevelHelpers.cmake b/cmake/QtTopLevelHelpers.cmake
index 2d06a8fd..7fe21e4f 100644
--- a/cmake/QtTopLevelHelpers.cmake
+++ b/cmake/QtTopLevelHelpers.cmake
@@ -1,3 +1,62 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+macro(qt_tl_include_all_helpers)
+ include(QtIRHelpers)
+ qt_ir_include_all_helpers()
+endmacro()
+
+function(qt_tl_run_toplevel_configure top_level_src_path)
+ cmake_parse_arguments(arg "ALREADY_INITIALIZED" "" "" ${ARGV})
+
+ qt_ir_get_cmake_flag(ALREADY_INITIALIZED arg_ALREADY_INITIALIZED)
+
+ # Filter out init-repository specific arguments before passing them to
+ # configure.
+ qt_ir_get_args_from_optfile_configure_filtered("${OPTFILE}" configure_args
+ ${arg_ALREADY_INITIALIZED})
+ # Get the path to the qtbase configure script.
+ set(qtbase_dir_name "qtbase")
+ set(configure_path "${top_level_src_path}/${qtbase_dir_name}/configure")
+ if(CMAKE_HOST_WIN32)
+ string(APPEND configure_path ".bat")
+ endif()
+
+ if(NOT EXISTS "${configure_path}")
+ message(FATAL_ERROR
+ "The required qtbase/configure script was not found: ${configure_path}\n"
+ "Try re-running configure with --init-submodules")
+ endif()
+
+ # Make a build directory for qtbase in the current build directory.
+ set(qtbase_build_dir "${CMAKE_CURRENT_BINARY_DIR}/${qtbase_dir_name}")
+ file(MAKE_DIRECTORY "${qtbase_build_dir}")
+
+ qt_ir_execute_process_and_log_and_handle_error(
+ COMMAND_ARGS "${configure_path}" -top-level ${configure_args}
+ WORKING_DIRECTORY "${qtbase_build_dir}"
+ FORCE_VERBOSE
+ )
+endfunction()
+
+function(qt_tl_run_main_script)
+ if(NOT TOP_LEVEL_SRC_PATH)
+ message(FATAL_ERROR "Assertion: configure TOP_LEVEL_SRC_PATH is not set")
+ endif()
+
+ # Tell init-repository it is called from configure.
+ qt_ir_set_option_value(from-configure TRUE)
+
+ # Run init-repository in-process.
+ qt_ir_run_main_script("${TOP_LEVEL_SRC_PATH}" exit_reason)
+ if(exit_reason AND NOT exit_reason STREQUAL "ALREADY_INITIALIZED")
+ return()
+ endif()
+
+ # Then run configure out-of-process.
+ qt_tl_run_toplevel_configure("${TOP_LEVEL_SRC_PATH}" ${exit_reason})
+endfunction()
+
# Populates $out_module_list with all subdirectories that have a CMakeLists.txt file
function(qt_internal_find_modules out_module_list)
set(module_list "")
@@ -14,8 +73,8 @@ endfunction()
# poor man's yaml parser, populating $out_dependencies with all dependencies
# in the $depends_file
-# Each entry will be in the format dependency/sha1
-function(qt_internal_parse_dependencies depends_file out_dependencies)
+# Each entry will be in the format dependency/sha1/required
+function(qt_internal_parse_dependencies_yaml depends_file out_dependencies)
file(STRINGS "${depends_file}" lines)
set(eof_marker "---EOF---")
list(APPEND lines "${eof_marker}")
@@ -47,91 +106,276 @@ function(qt_internal_parse_dependencies depends_file out_dependencies)
string(TOUPPER "${CMAKE_MATCH_1}" required)
endif()
endforeach()
- message(DEBUG "qt_internal_parse_dependencies for ${depends_file}: ${dependencies} ${revisions}")
+ message(DEBUG
+ "qt_internal_parse_dependencies_yaml for ${depends_file}\n dependencies: ${dependencies}")
set(${out_dependencies} "${dependencies}" PARENT_SCOPE)
endfunction()
-# Load $module and populate $out_ordered with the submodules based on their dependencies
-# $ordered carries already sorted dependencies; $out_has_dependencies is left empty
-# if there are no dependencies, otherwise set to 1; Save list of dependencies for $module into
-# $out_module_dependencies. List may contain duplicates, since function checks max depth
-# dependencies.
-# Function calls itself recursively if a dependency is found that is not yet in $ordered.
-function(qt_internal_add_module_dependencies module ordered out_ordered out_has_dependencies
- out_module_dependencies out_revisions)
- set(depends_file "${CMAKE_CURRENT_SOURCE_DIR}/${module}/dependencies.yaml")
- if(NOT EXISTS "${depends_file}")
- set(${out_has_dependencies} "" PARENT_SCOPE)
+# Helper macro for qt_internal_resolve_module_dependencies.
+macro(qt_internal_resolve_module_dependencies_set_skipped value)
+ if(DEFINED arg_SKIPPED_VAR)
+ set(${arg_SKIPPED_VAR} ${value} PARENT_SCOPE)
+ endif()
+endmacro()
+
+# Strips tqtc- prefix from a repo name.
+function(qt_internal_normalize_repo_name repo_name out_var)
+ string(REGEX REPLACE "^tqtc-" "" normalized "${repo_name}")
+ set(${out_var} "${normalized}" PARENT_SCOPE)
+endfunction()
+
+# Checks if a directory with the given repo name exists in the current
+# source / working directory. If it doesn't, it strips the tqtc- prefix.
+function(qt_internal_use_normalized_repo_name_if_needed repo_name out_var)
+ set(base_dir "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(repo_dir "${base_dir}/${repo_name}")
+ if(NOT IS_DIRECTORY "${repo_dir}")
+ qt_internal_normalize_repo_name("${repo_name}" repo_name)
+ endif()
+ set(${out_var} "${repo_name}" PARENT_SCOPE)
+endfunction()
+
+
+# Resolve the dependencies of the given module.
+# "Module" in the sense of Qt repository.
+#
+# Side effects: Sets the global properties QT_DEPS_FOR_${module} and QT_REQUIRED_DEPS_FOR_${module}
+# with the direct (required) dependencies of module.
+#
+#
+# Positional arguments:
+#
+# module is the Qt repository.
+#
+# out_ordered is where the result is stored. This is a list of all dependencies, including
+# transitive ones, in topologically sorted order. Note that ${module} itself is also part of
+# out_ordered.
+#
+# out_revisions is a list of git commit IDs for each of the dependencies in ${out_ordered}. This
+# list has the same length as ${out_ordered}.
+#
+#
+# Keyword arguments:
+#
+# PARSED_DEPENDENCIES is a list of dependencies of module in the format that
+# qt_internal_parse_dependencies_yaml returns.
+# If this argument is not provided, either a module's dependencies.yaml or .gitmodules file is
+# used as the source of dependencies, depending on whether PARSE_GITMODULES option is enabled.
+#
+# PARSE_GITMODULES is a boolean that controls whether the .gitmodules or the dependencies.yaml
+# file of the repo are used for extracting dependencies. Defaults to FALSE, so uses
+# dependencies.yaml by default.
+#
+# EXCLUDE_OPTIONAL_DEPS is a boolean that controls whether optional dependencies are excluded from
+# the final result.
+#
+# GITMODULES_PREFIX_VAR is the prefix of all the variables containing dependencies for the
+# PARSE_GITMODULES mode.
+# The function expects the following variables to be set in the parent scope
+# ${arg_GITMODULES_PREFIX_VAR}_${submodule_name}_depends
+# ${arg_GITMODULES_PREFIX_VAR}_${submodule_name}_recommends
+#
+# IN_RECURSION is an internal option that is set when the function is in recursion.
+#
+# REVISION is an internal value with the git commit ID that belongs to ${module}.
+#
+# SKIPPED_VAR is an output variable name that is set to TRUE if the module was skipped, to FALSE
+# otherwise.
+#
+# NORMALIZE_REPO_NAME_IF_NEEDED Will remove 'tqtc-' from the beginning of submodule dependencies
+# if a tqtc- named directory does not exist.
+#
+# SKIP_MODULES Modules that should be skipped from evaluation completely.
+function(qt_internal_resolve_module_dependencies module out_ordered out_revisions)
+ set(options IN_RECURSION NORMALIZE_REPO_NAME_IF_NEEDED PARSE_GITMODULES
+ EXCLUDE_OPTIONAL_DEPS)
+ set(oneValueArgs REVISION SKIPPED_VAR GITMODULES_PREFIX_VAR)
+ set(multiValueArgs PARSED_DEPENDENCIES SKIP_MODULES)
+ cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ # Clear the property that stores the repositories we've already seen.
+ if(NOT arg_IN_RECURSION)
+ set_property(GLOBAL PROPERTY _qt_internal_seen_repos)
+ endif()
+
+ # Bail out if we've seen the module already or it was skipped explicitly from command line.
+ qt_internal_resolve_module_dependencies_set_skipped(FALSE)
+ get_property(seen GLOBAL PROPERTY _qt_internal_seen_repos)
+ if(module IN_LIST seen OR module IN_LIST arg_SKIP_MODULES)
+ qt_internal_resolve_module_dependencies_set_skipped(TRUE)
return()
endif()
- set(${out_has_dependencies} "1" PARENT_SCOPE)
- set(dependencies "")
- qt_internal_parse_dependencies("${depends_file}" dependencies)
- # module hasn't been seen yet, append it
- list(FIND ordered "${module}" pindex)
- if (pindex EQUAL -1)
- list(LENGTH ordered pindex)
- list(APPEND ordered "${module}")
- list(APPEND revisions "HEAD")
+
+ set_property(GLOBAL APPEND PROPERTY _qt_internal_seen_repos ${module})
+
+ # Set a default REVISION.
+ if("${arg_REVISION}" STREQUAL "")
+ set(arg_REVISION HEAD)
endif()
- set(modules_dependencies "")
+
+ # Retrieve the dependencies.
+ if(DEFINED arg_PARSED_DEPENDENCIES)
+ set(dependencies "${arg_PARSED_DEPENDENCIES}")
+ else()
+ set(dependencies "")
+
+ if(NOT arg_PARSE_GITMODULES)
+ set(depends_file "${CMAKE_CURRENT_SOURCE_DIR}/${module}/dependencies.yaml")
+ if(EXISTS "${depends_file}")
+ qt_internal_parse_dependencies_yaml("${depends_file}" dependencies)
+
+ if(arg_EXCLUDE_OPTIONAL_DEPS)
+ set(filtered_dependencies "")
+ foreach(dependency IN LISTS dependencies)
+ string(REPLACE "/" ";" dependency_split "${dependency}")
+ list(GET dependency_split 2 required)
+ if(required)
+ list(APPEND filtered_dependencies "${dependency}")
+ endif()
+ endforeach()
+ set(dependencies "${filtered_dependencies}")
+ endif()
+ endif()
+ else()
+ set(depends "${${arg_GITMODULES_PREFIX_VAR}_${dependency}_depends}")
+ foreach(dependency IN LISTS depends)
+ if(dependency)
+ # The HEAD value is not really used, but we need to add something.
+ list(APPEND dependencies "${dependency}/HEAD/TRUE")
+ endif()
+ endforeach()
+
+ set(recommends "${${arg_GITMODULES_PREFIX_VAR}_${dependency}_recommends}")
+ if(NOT arg_EXCLUDE_OPTIONAL_DEPS)
+ foreach(dependency IN LISTS recommends)
+ if(dependency)
+ list(APPEND dependencies "${dependency}/HEAD/FALSE")
+ endif()
+ endforeach()
+ endif()
+ endif()
+ endif()
+
+ # Traverse the dependencies.
+ set(ordered)
+ set(revisions)
foreach(dependency IN LISTS dependencies)
if(dependency MATCHES "(.*)/([^/]+)/([^/]+)")
set(dependency "${CMAKE_MATCH_1}")
set(revision "${CMAKE_MATCH_2}")
set(required "${CMAKE_MATCH_3}")
- if(required)
- set_property(GLOBAL APPEND PROPERTY QT_REQUIRED_DEPS_FOR_${module} ${dependency})
- endif()
else()
message(FATAL_ERROR "Internal Error: wrong dependency format ${dependency}")
endif()
- list(APPEND modules_dependencies "${dependency}")
- list(FIND ordered "${dependency}" dindex)
- if (dindex EQUAL -1)
- # dependency hasnt' been seen yet - load it
- list(INSERT ordered ${pindex} "${dependency}")
- list(INSERT revisions ${pindex} "${revision}")
- qt_internal_add_module_dependencies(${dependency} "${ordered}" ordered has_dependency
- "${out_module_dependencies}" revisions)
- elseif(dindex GREATER pindex)
- # otherwise, make sure it is before module
- list(REMOVE_AT ordered ${dindex})
- list(REMOVE_AT revisions ${dindex})
- list(INSERT ordered ${pindex} "${dependency}")
- list(INSERT revisions ${pindex} "${revision}")
+
+ set(normalize_arg "")
+ if(arg_NORMALIZE_REPO_NAME_IF_NEEDED)
+ qt_internal_use_normalized_repo_name_if_needed("${dependency}" dependency)
+ set(normalize_arg "NORMALIZE_REPO_NAME_IF_NEEDED")
+ endif()
+
+ set_property(GLOBAL APPEND PROPERTY QT_DEPS_FOR_${module} ${dependency})
+ if(required)
+ set_property(GLOBAL APPEND PROPERTY QT_REQUIRED_DEPS_FOR_${module} ${dependency})
+ endif()
+
+ set(parse_gitmodules "")
+ if(arg_PARSE_GITMODULES)
+ set(parse_gitmodules "PARSE_GITMODULES")
+ endif()
+
+ set(exclude_optional_deps "")
+ if(arg_EXCLUDE_OPTIONAL_DEPS)
+ set(exclude_optional_deps "EXCLUDE_OPTIONAL_DEPS")
+ endif()
+
+ set(extra_options "")
+ if(arg_SKIP_MODULES)
+ list(APPEND extra_options SKIP_MODULES ${arg_SKIP_MODULES})
+ endif()
+
+ qt_internal_resolve_module_dependencies(${dependency} dep_ordered dep_revisions
+ REVISION "${revision}"
+ SKIPPED_VAR skipped
+ IN_RECURSION
+ ${normalize_arg}
+ ${parse_gitmodules}
+ ${exclude_optional_deps}
+ GITMODULES_PREFIX_VAR ${arg_GITMODULES_PREFIX_VAR}
+ ${extra_options}
+ )
+ if(NOT skipped)
+ list(APPEND ordered ${dep_ordered})
+ list(APPEND revisions ${dep_revisions})
endif()
endforeach()
+
+ list(APPEND ordered ${module})
+ list(APPEND revisions ${arg_REVISION})
set(${out_ordered} "${ordered}" PARENT_SCOPE)
- set(${out_module_dependencies} ${${out_module_dependencies}} ${modules_dependencies} PARENT_SCOPE)
set(${out_revisions} "${revisions}" PARENT_SCOPE)
endfunction()
-# populates $out_all_ordered with the sequence of the modules that need
-# to be built in order to build $modules; dependencies for each module are populated
-# in variables with specified in $dependencies_map_prefix prefix
-function(qt_internal_sort_module_dependencies modules out_all_ordered dependencies_map_prefix)
- set(ordered "")
+# Resolves the dependencies of the given modules.
+# "Module" is here used in the sense of Qt repository.
+#
+# Returns all dependencies, including transitive ones, in topologically sorted order.
+#
+# Arguments:
+# modules is the initial list of repos.
+# out_all_ordered is the variable name where the result is stored.
+# PARSE_GITMODULES and GITMODULES_PREFIX_VAR are keyowrd arguments that change the
+# source of dependencies parsing from dependencies.yaml to .gitmodules.
+# EXCLUDE_OPTIONAL_DEPS is a keyword argument that excludes optional dependencies from the result.
+# See qt_internal_resolve_module_dependencies for details.
+#
+# SKIP_MODULES Modules that should be skipped from evaluation completely.
+#
+# See qt_internal_resolve_module_dependencies for side effects.
+function(qt_internal_sort_module_dependencies modules out_all_ordered)
+ set(options PARSE_GITMODULES EXCLUDE_OPTIONAL_DEPS)
+ set(oneValueArgs GITMODULES_PREFIX_VAR)
+ set(multiValueArgs SKIP_MODULES)
+ cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ set(parse_gitmodules "")
+ if(arg_PARSE_GITMODULES)
+ set(parse_gitmodules "PARSE_GITMODULES")
+ endif()
+
+ set(exclude_optional_deps "")
+ if(arg_EXCLUDE_OPTIONAL_DEPS)
+ set(exclude_optional_deps "EXCLUDE_OPTIONAL_DEPS")
+ endif()
+
+ # Create a fake repository "all_selected_repos" that has all repositories from the input as
+ # required dependency. The format must match what qt_internal_parse_dependencies_yaml produces.
+ set(all_selected_repos_as_parsed_dependencies)
foreach(module IN LISTS modules)
- set(out_ordered "")
- if(NOT dependencies_map_prefix)
- message(FATAL_ERROR "dependencies_map_prefix is not provided")
- endif()
- set(module_dependencies_list_var_name "${dependencies_map_prefix}${module}")
- qt_internal_add_module_dependencies(${module} "${ordered}" out_ordered module_depends
- "${module_dependencies_list_var_name}" revisions)
- set(${module_dependencies_list_var_name}
- "${${module_dependencies_list_var_name}}" PARENT_SCOPE)
- if(NOT module_depends)
- list(APPEND no_dependencies "${module}")
- else()
- set(ordered "${out_ordered}")
- endif()
+ list(APPEND all_selected_repos_as_parsed_dependencies "${module}/HEAD/FALSE")
endforeach()
- if (no_dependencies)
- list(APPEND ordered "${no_dependencies}")
+
+ set(extra_args "")
+ if(arg_SKIP_MODULES)
+ set(extra_args SKIP_MODULES ${arg_SKIP_MODULES})
endif()
- message(DEBUG "qt_internal_parse_dependencies sorted ${modules}: ${ordered}")
+
+ qt_internal_resolve_module_dependencies(all_selected_repos ordered unused_revisions
+ PARSED_DEPENDENCIES ${all_selected_repos_as_parsed_dependencies}
+ NORMALIZE_REPO_NAME_IF_NEEDED
+ ${exclude_optional_deps}
+ ${parse_gitmodules}
+ GITMODULES_PREFIX_VAR ${arg_GITMODULES_PREFIX_VAR}
+ ${extra_args}
+ )
+
+ # Drop "all_selected_repos" from the output. It depends on all selected repos, thus it must be
+ # the last element in the topologically sorted list.
+ list(REMOVE_AT ordered -1)
+
+ message(DEBUG
+ "qt_internal_sort_module_dependencies
+ input modules: ${modules}\n topo-sorted: ${ordered}")
set(${out_all_ordered} "${ordered}" PARENT_SCOPE)
endfunction()
@@ -268,6 +512,17 @@ function(qt_internal_sync_to module)
endif()
qt_internal_checkout("${module}" "${revision}")
+ qt_internal_resolve_module_dependencies(${module} initial_dependencies initial_revisions)
+ if(initial_dependencies)
+ foreach(dependency ${initial_dependencies})
+ if(dependency MATCHES "^tqtc-")
+ message(WARNING
+ "Handling of tqtc- repos will likely fail. Fixing this is non-trivial.")
+ break()
+ endif()
+ endforeach()
+ endif()
+
set(revision "")
set(checkedout "1")
# Load all dependencies for $module, then iterate over the dependencies in reverse order,
@@ -275,19 +530,16 @@ function(qt_internal_sync_to module)
# Repeat everything (we need to reload dependencies after each checkout) until no more checkouts
# are done.
while(${checkedout})
- set(dependencies "")
- set(revisions "")
- set(prefix "")
- qt_internal_add_module_dependencies(${module} "${dependencies}" dependencies has_dependencies prefix revisions)
+ qt_internal_resolve_module_dependencies(${module} dependencies revisions)
message(DEBUG "${module} dependencies: ${dependencies}")
message(DEBUG "${module} revisions : ${revisions}")
- if (NOT has_dependencies)
+ list(LENGTH dependencies count)
+ if (count EQUAL "0")
message(NOTICE "Module ${module} has no dependencies")
return()
endif()
- list(LENGTH dependencies count)
math(EXPR count "${count} - 1")
set(checkedout 0)
foreach(i RANGE ${count} 0 -1 )
@@ -325,3 +577,125 @@ function(qt_internal_sync_to module)
endforeach()
endwhile()
endfunction()
+
+# Runs user specified command for all qt repositories in qt directory.
+# Similar to git submodule foreach, except without relying on .gitmodules existing.
+# Useful for worktree checkouts.
+function(qt_internal_foreach_repo_run)
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ ""
+ ""
+ "ARGS"
+ )
+ if(NOT arg_ARGS)
+ message(FATAL_ERROR "No arguments specified to qt_internal_foreach_repo_run")
+ endif()
+ separate_arguments(args NATIVE_COMMAND "${arg_ARGS}")
+
+ # Find the qt repos
+ qt_internal_find_modules(modules)
+
+ # Hack to support color output on unix systems
+ # https://stackoverflow.com/questions/18968979/how-to-make-colorized-message-with-cmake
+ execute_process(COMMAND
+ /usr/bin/tty
+ OUTPUT_VARIABLE tty_name
+ RESULT_VARIABLE tty_exit_code
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ set(color_supported FALSE)
+ set(output_goes_where "")
+ if(NOT tty_exit_CODE AND tty_name)
+ set(color_supported TRUE)
+ set(output_goes_where "OUTPUT_FILE" "${tty_name}")
+ endif()
+
+ # Count successes and failures.
+ set(count_success "0")
+ set(count_failure "0")
+
+ # Show colored error markers.
+ set(color "--normal")
+ if(color_supported)
+ set(color "--red")
+ endif()
+
+ foreach(module IN LISTS modules)
+ message("Entering '${module}'")
+ execute_process(
+ COMMAND ${args}
+ WORKING_DIRECTORY "${module}"
+ ${output_goes_where}
+ RESULT_VARIABLE cmd_result
+ )
+ if(cmd_result)
+ math(EXPR count_failure "${count_failure}+1")
+ # cmake_echo_color is undocumented, but lets us output colors and control newlines.
+ execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E env CLICOLOR_FORCE=1
+ ${CMAKE_COMMAND} -E cmake_echo_color "${color}"
+ "Process execution failed here ^^^^^^^^^^^^^^^^^^^^"
+ )
+ else()
+ math(EXPR count_success "${count_success}+1")
+ endif()
+ endforeach()
+
+ # Show summary with colors.
+ set(color "--normal")
+ if(count_failure AND color_supported)
+ set(color "--red")
+ endif()
+
+ message("\nSummary\n=======\n")
+ execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E cmake_echo_color --normal --no-newline "Failures: "
+ )
+ execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E env CLICOLOR_FORCE=1
+ ${CMAKE_COMMAND} -E cmake_echo_color "${color}" "${count_failure}"
+ )
+ message("Successes: ${count_success}")
+endfunction()
+
+# The function collects repos and dependencies that are required to build
+# repos listed in ARGN. If the BUILD_<repo> is defined the 'repo' will be
+# excluded from the list.
+function(qt_internal_collect_modules_only out_repos)
+ set(initial_modules "${ARGN}")
+ get_filename_component(qt5_repo_dir "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
+
+ # Overriding CMAKE_CURRENT_SOURCE_DIR is ugly but works
+ set(CMAKE_CURRENT_SOURCE_DIR "${qt5_repo_dir}")
+ if(NOT initial_modules)
+ qt_internal_find_modules(initial_modules)
+ endif()
+
+ qt_internal_sort_module_dependencies("${initial_modules}" ${out_repos})
+ foreach(module IN LISTS ${out_repos})
+ # Check for unmet dependencies
+ if(DEFINED BUILD_${module} AND NOT BUILD_${module})
+ list(REMOVE_ITEM ${out_repos} ${module})
+ continue()
+ endif()
+ get_property(required_deps GLOBAL PROPERTY QT_REQUIRED_DEPS_FOR_${module})
+ get_property(dependencies GLOBAL PROPERTY QT_DEPS_FOR_${module})
+ foreach(dep IN LISTS dependencies)
+ set(required FALSE)
+ if(dep IN_LIST required_deps)
+ set(required TRUE)
+ endif()
+ if(required AND DEFINED BUILD_${dep} AND NOT BUILD_${dep})
+ set(BUILD_${module} FALSE)
+ list(REMOVE_ITEM ${out_repos} ${module})
+ break()
+ endif()
+ endforeach()
+ endforeach()
+
+ set(${out_repos} "${${out_repos}}" PARENT_SCOPE)
+endfunction()