I have a problem with my CMake build system. There are CMakeLists.txt files defining runtimes or libraries or using ExternalProjects_Add() to downl
You can classify your projects into three groups:
You need to configure, build and install the project in groups #1 and #2 before configuring the super-project:
CMakeLists.txt, for example, from a shell-scriptCMakeLists.txt, using execute_process(${CMAKE_COMMAND} ...). You can do it conditionally using the result of an appropriate find_package(... QUIET) command.You need to decide if projects in group #3, like engine will be used solely in projects that uses them as subdirectories or you intend to use them as standalone libraries, built in their own build trees.
Also, you mentioned that: "My libraries include directories of external libraries". Let's cover all such possible libraries the engine can be dependent on:
LIB1 and LIB2 are private and public external dependencies of engine and their config-modules export old-school LIB1_* and LIB2_* variablesLIB3 and LIB4 are private and public external dependencies of engine and their config-modules export the LIB3 and LIB4 imported librariesBy public and private dependencies I mean whether the particular library is used or not used on the interface of engine.
Now, if engine is to be used only as a subdirectory then the relevant section of engine/CMakeLists.txt is:
add_library(engine ...)
target_include_directories(engine
PRIVATE
${LIB1_INCLUDE_DIRS}
PUBLIC
$
${LIB2_INCLUDE_DIRS})
target_compiled_definitions(engine
PRIVATE ${LIB1_DEFINITIONS}
PUBLIC ${LIB2_DEFINITIONS})
target_link_libraries(engine
PRIVATE LIB3
PUBLIC LIB4)
in repository/CMakeLists.txt:
add_subdirectory(engine)
add_subdirectory(game)
in game/CMakeLists.txt:
add_executable(game ...)
target_link_libraries(game engine)
The include dirs of both of the engine and of its public dependencies will be correctly forwarded to game.
If engine will also be built in its own build tree (in another project) you need to add the exporting code to engine/CMakeLists.txt and maybe a custom config-module that calls find_package (or find_dependency) for its dependencies. See How to use CMake to find and link to a library using install-export and find_package? for details. One issue not discussed in that answer is finding the dependencies of a library in the library's config module:
The referenced SO answer simply installs the script, generated by the install(EXPORT ...) command, as the config-module:
install(EXPORT engine-targets
FILE engine-config.cmake
DESTINATION lib/cmake/engine)
This solution is fine when engine has no further dependencies. If it does, they need to be found at the beginning of the config module, which should be written manually.
engine/engine-config.cmake:
include(CMakeFindDependencyMacro)
find_dependency(some-dep-of-engine)
include(${CMAKE_CURRENT_LIST_DIR}/engine-targets.cmake)
and in engine/CMakeLists.txt:
install(EXPORT engine-targets
FILE engine-targets.cmake
DESTINATION lib/cmake/engine)
install(FILES engine-config.cmake
DESTINATION lib/cmake/engine)
Note: The CMakeFindDependencyMacro has been introduced in CMake 3.0. With an older CMake you can use find_package instead of find_dependency (handling of QUIET and REQUIRED options will not be forwarded to the dependency).