declare dependencies between subdirectories
i found this limitation while translating qmake to cmake
qmake allows to build subdirectories "in order", for example
# PyQt6.pro
TEMPLATE = subdirs
CONFIG += ordered nostrip
SUBDIRS = dbus QtCore QtNetwork QtGui
this will build: dbus → QtCore → QtNetwork → QtGui
with cmake, i have two options to express this
ExternalProject_Add
# /src/CMakeLists.txt
# head
cmake_minimum_required(VERSION 3.16)
project(QtCore VERSION 1.0 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# body
include(ExternalProject)
ExternalProject_Add(dbus SOURCE_DIR dbus)
ExternalProject_Add(QtCore SOURCE_DIR QtCore DEPENDS dbus)
ExternalProject_Add(QtNetwork SOURCE_DIR QtCore DEPENDS dbus QtCore)
ExternalProject_Add(QtGui SOURCE_DIR QtCore DEPENDS dbus QtCore QtNetwork)
# ...
problem with ExternalProject_Add:
the sub-projects must be standalone cmake projects,
with the usual headers like find_package
# /src/QtCore/CMakeLists.txt
# head
cmake_minimum_required(VERSION 3.16)
project(QtCore VERSION 1.0 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt6 REQUIRED COMPONENTS Core Network Gui Qml Widgets DBus)
qt_standard_project_setup()
# body
qt_add_plugin(QtCore)
target_sources(QtCore PRIVATE
../../PyQt6-6.3.0/qpy/QtCore/qpycore_api.h
# ...
)
add_subdirectory + add_dependencies
here i need the headers only once, in the top-level cmake file
# /src/CMakeLists.txt
# head ...
# body
add_subdirectory(dbus)
add_subdirectory(QtCore)
add_dependencies(QtCore dbus)
add_subdirectory(QtNetwork)
add_dependencies(QtNetwork QtCore dbus)
add_subdirectory(QtGui)
add_dependencies(QtGui QtNetwork QtCore dbus)
problem: i must know all the internal targets of the subdirectories
possible workaround: return a list of targets to the parent scope
# /src/CMakeLists.txt
# head ...
add_subdirectory(dbus)
set(last_subdir_scope_targets ${subdir_scope_targets})
add_subdirectory(QtCore)
add_dependencies(QtCore ${last_subdir_scope_targets})
# /src/QtCore/CMakeLists.txt
qt_add_plugin(QtCore)
set(subdir_scope_targets ${all_targets_of_this_scope} PARENT_SCOPE)
# TODO all_targets_of_this_scope
to get all_targets_of_this_scope: How do I iterate over all CMake targets programmatically?
proposed solution
add option DEPENDS_SUBDIRECTORIES to add_subdirectory
# /src/CMakeLists.txt
# head ...
# body
add_subdirectory(dbus)
add_subdirectory(QtCore DEPENDS_SUBDIRECTORIES dbus)
add_subdirectory(QtNetwork DEPENDS_SUBDIRECTORIES dbus QtCore)
add_subdirectory(QtGui DEPENDS_SUBDIRECTORIES dbus QtCore QtNetwork)
this means:
all targets in the subdir QtCore depend on all targets in the subdir dbus
i suggest to not use DEPENDS, as that means "x depends on targets"