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

Attachment: signature.asc
Description: Message signed with OpenPGP

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

Reply via email to