aboutsummaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-08 14:28:12 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-11 11:44:25 +0100
commitda25b7f149ee55317e14365ae10f2df77e8250bb (patch)
treed8836d2b64e962079bc62e3c1046a445e2992d88 /cmake
parent9a82a87954fda2e5f6420d346798d9a841e5c810 (diff)
Use dependencies.yaml to order sub modules
Don't rely on .gitmodules, instead parse the dependencies.yaml file from every subdirectory with a CMakeLists.txt, and sort all projects based on that data. Projects with no dependencies are added last. This allows us to get rid of the duplication of dependency information in .gitmodules, and makes each module the authoritative source of its own dependencies. Change-Id: Ib1ec6c63bde2aa1852399d598dac5b8e1efda31d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/QtTopLevelHelpers.cmake85
1 files changed, 85 insertions, 0 deletions
diff --git a/cmake/QtTopLevelHelpers.cmake b/cmake/QtTopLevelHelpers.cmake
new file mode 100644
index 00000000..b9f4341a
--- /dev/null
+++ b/cmake/QtTopLevelHelpers.cmake
@@ -0,0 +1,85 @@
+# Populates $out_module_list with all subdirectories that have a CMakeLists.txt file
+function(qt_internal_find_modules out_module_list)
+ set(module_list "")
+ file(GLOB directories LIST_DIRECTORIES true RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *)
+ foreach(directory IN LISTS directories)
+ if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${directory}"
+ AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${directory}/CMakeLists.txt")
+ list(APPEND module_list "${directory}")
+ endif()
+ endforeach()
+ message(DEBUG "qt_internal_find_modules: ${module_list}")
+ set(${out_module_list} "${module_list}" PARENT_SCOPE)
+endfunction()
+
+# poor man's yaml parser, populating $out_dependencies with all dependencies
+# in the $depends_file
+function(qt_internal_parse_dependencies depends_file out_dependencies)
+ file(STRINGS "${depends_file}" lines)
+ set(dependencies "")
+ foreach(line IN LISTS lines)
+ if(line STREQUAL "dependencies:")
+ set(found_dependencies 1)
+ elseif(found_dependencies AND line MATCHES "^ (.*):$")
+ set(dependency ${CMAKE_MATCH_1})
+ # dependencies are specified with relative path to this module
+ string(REPLACE "../" "" dependency ${dependency})
+ list(APPEND dependencies ${dependency})
+ endif()
+ endforeach()
+ message(DEBUG "qt_internal_parse_dependencies for ${depends_file}: ${module_list}")
+ 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
+# 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)
+ set(depends_file "${CMAKE_CURRENT_SOURCE_DIR}/${module}/dependencies.yaml")
+ if(NOT EXISTS "${depends_file}")
+ set(${out_has_dependencies} "" PARENT_SCOPE)
+ 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})
+ endif()
+ foreach(dependency IN LISTS dependencies)
+ list(FIND ordered "${dependency}" dindex)
+ 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)
+ elseif(dindex GREATER pindex)
+ # otherwise, make sure it is before module
+ list(REMOVE_AT ordered ${dindex})
+ list(INSERT ordered ${pindex} "${dependency}")
+ endif()
+ endforeach()
+ set(${out_ordered} "${ordered}" 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)
+ set(ordered "")
+ foreach(module IN LISTS modules)
+ set(out_ordered "")
+ qt_internal_add_module_dependencies(${module} "${ordered}" out_ordered module_depends)
+ if(NOT module_depends)
+ list(APPEND no_dependencies "${module}")
+ endif()
+ set(ordered "${out_ordered}")
+ endforeach()
+ if (no_dependencies)
+ list(APPEND ordered "${no_dependencies}")
+ endif()
+ message(DEBUG "qt_internal_parse_dependencies sorted ${modules}: ${ordered}")
+ set(${out_all_ordered} "${ordered}" PARENT_SCOPE)
+endfunction()