[CMake] Concerning IDE support for superbuilds

Kai Wolf kai.wolf at gmail.com
Sun Jan 21 05:16:22 EST 2018


Hi all,

a common approach for dealing with larger dependencies in a project is using a superbuild approach, where all dependencies get downloaded in a separate repository using ExternalProject_Add() and the actual project is included as a sub repository (e.g. using git submodules) and also build as an external project [1], [2], [3]. This is necessary since external projects don’t play well as a direct dependency for internal targets, as the external projects won’t be created and available until build time, whereas CMake needs some information already at configure time for creating a proper build system.

As discussed previously on this mailing list this approach has some significant drawbacks: Since the actual project is also build as an external project, CMake treats it as an external source respectively and IDE support is not available. One possible solution to this problem is to let the outer project generate a cache file which subsequently can be used in the actual project to configure all paths to the previously downloaded and built external dependencies:

    +----------------+
    |   Superbuild   |  ----> generates init-cache.cmake
    +----------------+

    +----------------+
    | actual project |  ----> uses: cmake -C init-cache.cmake
    +----------------+

However, this means we now need two steps to configure and build the actual project and also cannot easily maintain the external dependencies within one large project.

After thinking about this for a while I came up with the following hackish solution and would like to ask you, if you see any drawback in using this. Basically all I’m doing is to include the actual project first as a dummy external project and set the external projects as dependencies, thus they’ll get built beforehand and in the BUILD_COMMAND of the actual project I’m calling CMake to the project’s CMakeLists.txt again to trigger a reconfigure, writing a cache file and set a specific variable |project_deps_installed| which is used as an indicator in the CMakeLists. configuration to include the actual project via add_subdirectory(). For instance:

    CMakeLists.txt:
    option(BUILD_MYPROJECT „Build the actual project“ ON)
    if(BUILD_MYPROJECT)
      if(project_deps_installed)
        include(${CMAKE_CURRENT_BINARY_DIR}/init-cache.cmake)
        add_subdirectory(MyProject)
      else()
        include(External_project)
      endif()
    endif()

    External_project.cmake
    ExternalProject_Add(MyProject
      SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MyProject
      BUILD_COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_BINARY_DIR}
        ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}
      INSTALL_COMMAND „"
      DEPENDS ${external_deps})

    write_cmake_cache_file(„${cache_script}“ „${cache_args}“)
    set(project_deps_installed TRUE CACHE BOOL „“)

As a result, all external dependencies get build and installed via ExternalProject_Add() and the actual project is configured properly and included via add_subdirectory(), thus it can continue using find_package() as usual and will be pointed to the previously configured dependencies. So far, I haven’t found any downside to this and consider making this part of CMake itself, in case you don’t see any problems using this approach?


Thanks in advance for your input.


[1] https://github.com/OpenChemistry/openchemistry
[2] https://github.com/MITK/MITK
[3] https://github.com/SuperElastix/SuperElastix

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: Message signed with OpenPGP
URL: <https://cmake.org/pipermail/cmake/attachments/20180121/3d1d05cd/attachment.sig>


More information about the CMake mailing list