Search code examples
c++cmakerestbed

How to build and link external CMake dependencies with CMake?


I'd like to use the following third party library: https://github.com/Corvusoft/restbed

I'd like to create a folder structure similar to this:

- root
     - CMakeLists.txt
     - src
     - third_party
         - restbed
             - src
             - CMakeLists.txt
         - CMakeLists.txt

I've found out that I should use the ExternalProject CMake module to achieve this but it does not seem that I can do it correctly. For some reason the external lib's (restbed's) source does not appear in my XCode project when I generate it out with the use of the root CMakeLists.txt. This root CMakeLists.txt includes in the third_party folder's CMakeLists.txt. The third_party folder's CMakeLists.txt looks like this:

include(ExternalProject)

# CMAKE_CURRENT_LIST_DIR -> third_party folder
set(RESTBED_DIR ${CMAKE_CURRENT_LIST_DIR}/restbed)

ExternalProject_Add(restbed
    PREFIX ${RESTBED_DIR}
    SOURCE_DIR ${RESTBED_DIR}
    CMAKE_ARGS -DBUILD_SSL=NO
    DOWNLOAD_COMMAND ""
    UPDATE_COMMAND ""
    BUILD_COMMAND cmake ..
    BINARY_DIR ${RESTBED_DIR}/build
    INSTALL_DIR ${RESTBED_DIR}/distribution
    INSTALL_COMMAND make install
)

set(RESTBED_INCLUDE_DIR ${RESTBED_DIR}/distribution/include)
set(RESTBED_LIB_DIR ${RESTBED_DIR}/distribution/lib)

add_library(librestbed IMPORTED STATIC)
add_dependencies(librestbed restbed)

After this I'd like to use target_include_dir and target_link_libraries to add librestbed as a dependency to my root project. After this when I build my XCode project nothing happens, the external lib won't get built. What am I doing wrong? I would not like to use the built-in CMake git functionality because I'd like to store my external dependencies as git submodules in the third_party lib. I'd rather not let CMake figure out if it needs to re-download a given dependency. Thanks in advance!


Solution

  • I think you mixed up the BUILD_COMMAND option with the CONFIGURE_COMMAND option. The cmake .. should be placed after the option CONFIGURE_COMMAND.

    ExternalProject_Add(restbed
        PREFIX ${RESTBED_DIR}
        SOURCE_DIR ${RESTBED_DIR}
        CMAKE_ARGS -DBUILD_SSL=NO
        DOWNLOAD_COMMAND ""
        UPDATE_COMMAND ""
        CONFIGURE_COMMAND cmake ..
        BINARY_DIR ${RESTBED_DIR}/build
        INSTALL_DIR ${RESTBED_DIR}/distribution
        INSTALL_COMMAND make install
    )
    

    Per the documentation, there are defaults to each of these commands, so you likely don't have to specify the CONFIGURE_COMMAND at all. For example, for BUILD_COMMAND:

    If this option is not given, the default build command will be chosen to integrate with the main build in the most appropriate way (e.g. using recursive make for Makefile generators or cmake --build if the project uses a CMake build).

    Also, if you do specify the CONFIGURE_COMMAND, you likely expand the arguments you pass it to something like this:

        ...
        CONFIGURE_COMMAND cd restbed && mkdir build && cd build && cmake ..
        ...