From e6a3bdf8dd130d9087fc0f132586f63f7a54c568 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Santiago=20Ospina=20De=20Los=20R=C3=ADos?=
 <sospinar@gmail.com>
Date: Tue, 27 Aug 2024 13:46:08 +0200
Subject: [PATCH] Add helper script to generate super build projects

---
 cmake/scripts/GenerateDuneSuperBuild.cmake | 81 ++++++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 cmake/scripts/GenerateDuneSuperBuild.cmake

diff --git a/cmake/scripts/GenerateDuneSuperBuild.cmake b/cmake/scripts/GenerateDuneSuperBuild.cmake
new file mode 100644
index 000000000..20c0c5503
--- /dev/null
+++ b/cmake/scripts/GenerateDuneSuperBuild.cmake
@@ -0,0 +1,81 @@
+# SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
+# SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
+cmake_minimum_required(VERSION 3.17 FATAL_ERROR)
+
+#[[
+Helper script generate a CMakeLists.txt for a dune super build project.
+In particular, it sets up the correct minimum required flags and the correct oreding of sub-modules.
+Call this from the root folder where you want to create a super build. For example:
+```
+# generate CMakeLists.txt for super build project
+cmake -P dune-common/cmake/scripts/GenerateDuneSuperBuild.cmake
+# generate a Ninja configuration in a directory named `build`
+cmake . -G Ninja -B build/
+# start the actual build
+cmake --build build/
+```
+]]
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../modules)
+
+include(DuneModuleInformation)
+
+# find dune.module in sub-directories (note that dir name may differ from module name)
+set(mod_names)
+set(mod_dirs)
+file(GLOB subdirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
+foreach(_dir IN LISTS subdirs)
+    if(EXISTS ${_dir}/dune.module)
+        # extract module information
+        dune_module_information(${CMAKE_CURRENT_SOURCE_DIR}/${_dir})
+        list(APPEND mod_dirs ${_dir})
+        list(APPEND mod_names ${DUNE_MOD_NAME})
+
+        if(${DUNE_MOD_NAME}_DEPENDS)
+            split_module_version(${${DUNE_MOD_NAME}_DEPENDS} ${DUNE_MOD_NAME}_DEPENDS_MODULE ${DUNE_MOD_NAME}_DEPENDS_VERSION)
+        endif()
+        if(${DUNE_MOD_NAME}_SUGGESTS)
+            split_module_version(${${DUNE_MOD_NAME}_SUGGESTS} ${DUNE_MOD_NAME}_SUGGESTS_MODULE ${DUNE_MOD_NAME}_SUGGESTS_VERSION)
+        endif()
+    endif()
+endforeach()
+
+# sort modules with respect to their dependencies
+foreach(_mod _dir IN ZIP_LISTS mod_names mod_dirs)
+    # get current module index
+    list(FIND mod_names "${_mod}" _old_pos)
+    set(_new_pos ${_old_pos})
+    # move module index after all its dependency indices
+    foreach(_dep IN LISTS ${_mod}_DEPENDS_MODULE ${_mod}_SUGGESTS_MODULE)
+        list(FIND mod_names "${_dep}" _dep_pos)
+        if(_dep_pos GREATER _new_pos)
+            math(EXPR _new_pos "${_dep_pos}")
+        endif()
+    endforeach()
+    # move module name and module dir to their new index
+    list(REMOVE_AT mod_names ${_old_pos})
+    list(INSERT mod_names ${_new_pos} ${_mod})
+    list(REMOVE_AT mod_dirs ${_old_pos})
+    list(INSERT mod_dirs ${_new_pos} ${_dir})
+endforeach()
+
+# include directories in dependency order
+set(add_dirs)
+foreach(_mod _dir IN ZIP_LISTS mod_names mod_dirs)
+    set(add_dirs "${add_dirs}add_subdirectory(${_dir})\n")
+endforeach()
+
+# write the new file
+file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt "
+# This file was automatically generated by ${CMAKE_CURRENT_LIST_FILE}
+cmake_minimum_required(VERSION 3.24 FATAL_ERROR)
+project(dune-super-build CXX)
+
+# let 'find_package' know where configured projects can be found
+set(CMAKE_PREFIX_PATH \${PROJECT_BINARY_DIR})
+# allow dune to see imported targets across modules
+set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)
+
+# include DUNE sub-directories in configuration order
+${add_dirs}
+")
-- 
GitLab