CMake: Fix dependency handling when module is skipped

Put dependencies of all modules to top-level variables and
check for unmet dependencies before module configuring.

Fixes: QTBUG-88214
Change-Id: I089feb474687652f3f8fd1bb1959179ea1114983
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Alexey Edelev
2020-11-13 13:42:42 +01:00
parent 4e2e65c7f1
commit a2683113e2
2 changed files with 42 additions and 26 deletions

View File

@@ -42,10 +42,32 @@ if (NOT BUILD_SUBMODULES)
qt_internal_find_modules(BUILD_SUBMODULES)
endif()
qt_internal_sort_module_dependencies("${BUILD_SUBMODULES}" BUILD_SUBMODULES)
set(qt_module_dependency_map_prefix "__qt_module_dependencies_")
qt_internal_sort_module_dependencies("${BUILD_SUBMODULES}" BUILD_SUBMODULES
"${qt_module_dependency_map_prefix}")
foreach(module IN LISTS BUILD_SUBMODULES)
message(NOTICE "Configuring '${module}'")
# Check for unmet dependencies
if(NOT DEFINED BUILD_${module} OR BUILD_${module})
foreach(dep IN LISTS "${qt_module_dependency_map_prefix}${module}")
if (dep STREQUAL "qtbase")
# Always available skip
continue()
endif()
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dep}/CMakeLists.txt")
message(FATAL_ERROR "Module '${module}' depends on '${dep}', but ${dep}'s \
CMakeLists.txt couldn't be found.\nNote: Use '-skip ${module}' to exclude it \
from build.\n")
endif()
if(DEFINED BUILD_${dep} AND NOT BUILD_${dep})
message(FATAL_ERROR "Module '${module}' depends on '${dep}', but '${dep}' \
will not be built.\nNote: Use '-skip ${module}' to exclude it from build.\n")
endif()
endforeach()
endif()
ecm_optional_add_subdirectory("${module}")
if(module STREQUAL "qtbase")
@@ -56,25 +78,6 @@ foreach(module IN LISTS BUILD_SUBMODULES)
endif()
endforeach()
# Check for unmet dependencies
foreach(module IN LISTS BUILD_SUBMODULES)
foreach(dep IN LISTS "${qt_module_prop_prefix}${module}_depends")
if (dep STREQUAL qtbase)
# Always available skip
continue()
endif()
if (DEFINED BUILD_${module} AND BUILD_${module})
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dep}/CMakeLists.txt")
message(FATAL_ERROR "Module '${module} depends on '${dep}', but ${deps}'s CMakeLists.txt couldn't be found.\n")
endif()
if(NOT BUILD_${dep})
message(FATAL_ERROR "Module '${module} depends on '${dep}', but ${deps} will not be built.\n")
endif()
endif()
endforeach()
endforeach()
if(NOT QT_BUILD_STANDALONE_TESTS)
# Display a summary of everything
include(QtBuildInformation)

View File

@@ -33,9 +33,12 @@ 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
# 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)
function(qt_internal_add_module_dependencies module ordered out_ordered out_has_dependencies
out_module_dependencies)
set(depends_file "${CMAKE_CURRENT_SOURCE_DIR}/${module}/dependencies.yaml")
if(NOT EXISTS "${depends_file}")
set(${out_has_dependencies} "" PARENT_SCOPE)
@@ -55,7 +58,8 @@ function(qt_internal_add_module_dependencies module ordered out_ordered out_has_
if (dindex EQUAL -1)
# dependency hasnt' been seen yet - load it
list(INSERT ordered ${pindex} "${dependency}")
qt_internal_add_module_dependencies(${dependency} "${ordered}" ordered has_dependency)
qt_internal_add_module_dependencies(${dependency} "${ordered}" ordered has_dependency
"${out_module_dependencies}")
elseif(dindex GREATER pindex)
# otherwise, make sure it is before module
list(REMOVE_AT ordered ${dindex})
@@ -63,15 +67,24 @@ function(qt_internal_add_module_dependencies module ordered out_ordered out_has_
endif()
endforeach()
set(${out_ordered} "${ordered}" PARENT_SCOPE)
set(${out_module_dependencies} ${${out_module_dependencies}} ${dependencies} PARENT_SCOPE)
endfunction()
# populates $out_all_ordered with the sequence of the modules that need
# to be built in order to build $modules
function(qt_internal_sort_module_dependencies modules out_all_ordered)
# 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 "")
foreach(module IN LISTS modules)
set(out_ordered "")
qt_internal_add_module_dependencies(${module} "${ordered}" out_ordered module_depends)
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}")
set(${module_dependencies_list_var_name}
"${${module_dependencies_list_var_name}}" PARENT_SCOPE)
if(NOT module_depends)
list(APPEND no_dependencies "${module}")
endif()