diff options
-rw-r--r-- | CMakeLists.txt | 80 | ||||
-rw-r--r-- | cmake/TopologicalSort.cmake | 148 | ||||
-rw-r--r-- | cmake/TopologicalSort_LICENSE.txt | 23 | ||||
-rw-r--r-- | cmake/qt_attribution.json | 13 |
4 files changed, 256 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e54ec11a..98b44543 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,12 +10,39 @@ project(Qt # Required so we can call ctest from the root build directory enable_testing() +set(qt_module_prop_prefix "__qt_prop_") +function(extract_git_submodules out_module_list) + set(modules "") + set(current_module "") + set(module_list "") + file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules" lines) + foreach(line IN LISTS lines) + string(REGEX REPLACE "^\\[submodule \"([^\"]+)\"\\]$" "\\1" module ${line}) + if (NOT module STREQUAL line) + list(APPEND modules ${modules}) + set(current_module ${module}) + list(APPEND module_list ${module}) + else() + string(REGEX REPLACE "^\t([^ =]+) *=.*$" "\\1" prop ${line}) + if (NOT prop STREQUAL line) + string(REGEX REPLACE "^[^=]+= *" "" value ${line}) + string(REPLACE " " ";" value ${value}) + set("${qt_module_prop_prefix}${current_module}_${prop}" "${value}" PARENT_SCOPE) + else() + message(FATAL_ERROR "Malformed line ${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules: ${line}") + endif() + endif() + endforeach() + set(${out_module_list} ${module_list} PARENT_SCOPE) +endfunction() + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") if (NOT QT_BUILD_STANDALONE_TESTS) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/qtbase/cmake") endif() include(ECMOptionalAddSubdirectory) +include(TopologicalSort) # Use the CMake config files from the binary dir list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") @@ -25,21 +52,58 @@ if (NOT QT_BUILD_STANDALONE_TESTS) endif() set(QT_SUPERBUILD TRUE) +# Get submodules list +extract_git_submodules(git_module_list) +foreach(module IN LISTS git_module_list) + # Prepare a list of dependencies to be fed into topological sort + set("${qt_module_prop_prefix}${module}_all_dependencies" + ${${qt_module_prop_prefix}${module}_depends} + ${${qt_module_prop_prefix}${module}_recommends} + ${${qt_module_prop_prefix}${module}_serialize} + ) +endforeach() + +# Sort by dependencies +topological_sort(git_module_list "${qt_module_prop_prefix}" "_all_dependencies") + +# Check for unknown modules +foreach(module IN LISTS git_module_list) + foreach(dep IN LISTS "${qt_module_prop_prefix}${module}_all_dependencies") + if (NOT dep IN_LIST git_module_list) + message(FATAL_ERROR "Module '${module}' depends on undeclared module '${dep}'") + endif() + endforeach() +endforeach() + # qtbase is always needed +list(REMOVE_ITEM git_module_list qtbase) add_subdirectory(qtbase) if (NOT QT_BUILD_STANDALONE_TESTS) list(APPEND CMAKE_PREFIX_PATH "${QtBase_BINARY_DIR}") endif() -ecm_optional_add_subdirectory(qtconnectivty) -ecm_optional_add_subdirectory(qtdeclarative) -ecm_optional_add_subdirectory(qtgraphicaleffects) -ecm_optional_add_subdirectory(qtimageformats) -ecm_optional_add_subdirectory(qtsvg) -ecm_optional_add_subdirectory(qtquickcontrols2) -ecm_optional_add_subdirectory(qtgamepad) -ecm_optional_add_subdirectory(qttools) +foreach(module IN LISTS git_module_list) + ecm_optional_add_subdirectory(${module}) +endforeach() + +# Check for unmet dependencies +foreach(module IN LISTS git_module_list) + 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) diff --git a/cmake/TopologicalSort.cmake b/cmake/TopologicalSort.cmake new file mode 100644 index 00000000..b85e7749 --- /dev/null +++ b/cmake/TopologicalSort.cmake @@ -0,0 +1,148 @@ +############################################################################## +# @file TopologicalSort.cmake +# @brief CMake implementation of topological sorting algorithm. +# +# Perform a reverse topological sort on the given LIST. +# +# topological_sort(my_list "MY_" "_EDGES") +# +# LIST is the name of a variable containing a list of elements to be +# sorted in reverse topological order. Each element in the list has a +# set of outgoing edges (for example, those other list elements that +# it depends on). In the resulting reverse topological ordering +# (written back into the variable named LIST), an element will come +# later in the list than any of the elements that can be reached by +# following its outgoing edges and the outgoing edges of any vertices +# they target, recursively. Thus, if the edges represent dependencies +# on build targets, for example, the reverse topological ordering is +# the order in which one would build those targets. +# +# For each element E in this list, the edges for E are contained in +# the variable named ${PREFIX}${E}${SUFFIX}. If no such variable +# exists, then it is assumed that there are no edges. For example, if +# my_list contains a, b, and c, one could provide a dependency graph +# using the following variables: +# +# MY_A_EDGES b +# MY_B_EDGES +# MY_C_EDGES a b +# +# With the involcation of topological_sort shown above and these +# variables, the resulting reverse topological ordering will be b, a, c. +# +# @verbatim +############################################################################## +# Modified from Boost Utilities +# +# Copyright 2010 Kitware, Inc. +############################################################################## +# Copyright 2007 Douglas Gregor <doug.gregor@gmail.com> +# Copyright 2007 Troy Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +############################################################################## +# Boost Software License - Version 1.0 - August 17th, 2003 +# +# Permission is hereby granted, free of charge, to any person or organization +# obtaining a copy of the software and accompanying documentation covered by +# this license (the "Software") to use, reproduce, display, distribute, +# execute, and transmit the Software, and to prepare derivative works of the +# Software, and to permit third-parties to whom the Software is furnished to +# do so, all subject to the following: +# +# The copyright notices in the Software and this entire statement, including +# the above license grant, this restriction and the following disclaimer, +# must be included in all copies of the Software, in whole or in part, and +# all derivative works of the Software, unless such copies or derivative +# works are solely in the form of machine-executable object code generated by +# a source language processor. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +# SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +# FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +############################################################################## +# @endverbatim +# +# @ingroup CMakeUtilities +############################################################################## + +function(topological_sort LIST PREFIX SUFFIX) + # Clear the stack and output variable + set(VERTICES "${${LIST}}") + set(STACK) + set(${LIST}) + + # Loop over all of the vertices, starting the topological sort from + # each one. + foreach(VERTEX ${VERTICES}) + + # If we haven't already processed this vertex, start a depth-first + # search from where. + if (NOT FOUND_${VERTEX}) + # Push this vertex onto the stack with all of its outgoing edges + string(REPLACE ";" " " NEW_ELEMENT + "${VERTEX};${${PREFIX}${VERTEX}${SUFFIX}}") + list(APPEND STACK ${NEW_ELEMENT}) + + # We've now seen this vertex + set(FOUND_${VERTEX} TRUE) + + # While the depth-first search stack is not empty + list(LENGTH STACK STACK_LENGTH) + while(STACK_LENGTH GREATER 0) + # Remove the vertex and its remaining out-edges from the top + # of the stack + list(GET STACK -1 OUT_EDGES) + list(REMOVE_AT STACK -1) + + # Get the source vertex and the list of out-edges + separate_arguments(OUT_EDGES) + list(GET OUT_EDGES 0 SOURCE) + list(REMOVE_AT OUT_EDGES 0) + + # While there are still out-edges remaining + list(LENGTH OUT_EDGES OUT_DEGREE) + while (OUT_DEGREE GREATER 0) + # Pull off the first outgoing edge + list(GET OUT_EDGES 0 TARGET) + list(REMOVE_AT OUT_EDGES 0) + + if (NOT FOUND_${TARGET}) + # We have not seen the target before, so we will traverse + # its outgoing edges before coming back to our + # source. This is the key to the depth-first traversal. + + # We've now seen this vertex + set(FOUND_${TARGET} TRUE) + + # Push the remaining edges for the current vertex onto the + # stack + string(REPLACE ";" " " NEW_ELEMENT + "${SOURCE};${OUT_EDGES}") + list(APPEND STACK ${NEW_ELEMENT}) + + # Setup the new source and outgoing edges + set(SOURCE ${TARGET}) + set(OUT_EDGES + ${${PREFIX}${SOURCE}${SUFFIX}}) + endif(NOT FOUND_${TARGET}) + + list(LENGTH OUT_EDGES OUT_DEGREE) + endwhile (OUT_DEGREE GREATER 0) + + # We have finished all of the outgoing edges for + # SOURCE; add it to the resulting list. + list(APPEND ${LIST} ${SOURCE}) + + # Check the length of the stack + list(LENGTH STACK STACK_LENGTH) + endwhile(STACK_LENGTH GREATER 0) + endif (NOT FOUND_${VERTEX}) + endforeach(VERTEX) + + set(${LIST} ${${LIST}} PARENT_SCOPE) +endfunction(topological_sort) diff --git a/cmake/TopologicalSort_LICENSE.txt b/cmake/TopologicalSort_LICENSE.txt new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/cmake/TopologicalSort_LICENSE.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/cmake/qt_attribution.json b/cmake/qt_attribution.json new file mode 100644 index 00000000..0699021c --- /dev/null +++ b/cmake/qt_attribution.json @@ -0,0 +1,13 @@ +{ + "Id": "cmake_topological_sort", + "Name": "CMake Topological Sort", + "QDocModule": "qt", + "QtUsage": "Used in the CMake super build project file", + "Files": TopologicalSort.cmake", + + "Description": "CMake implementation of the topological sort algorithm", + "License": "Boost Software License - Version 1.0", + "LicenseFile": "TopologicalSort_LICENSE.txt", + "Copyright": "Copyright 2010 Kitware, Inc." +} + |