Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking against an ExternalProject_add dependency in CMAKE

Tags:

c++

cmake

ninja

I'm getting this ninja build error below while running Ninja. My CMAKE build command iscmake -G"Ninja" -DCMAKE_BUILD_TYPE=Release.

ninja: error: 'ext_deps/api/src/ext_api/build/src/lib/libapi.a', needed by 'Project', missing and no known rule to make it

Let's say my project consists of an API (downloaded via CMAKE from GitHub) and the implementation (the Project).

The layout would look like:
Project/
-- build/
-- cmake/modules
----- ExternalDep.cmake
----- FindAPI.cmake
-- CMakeLists.txt
-- src/
---- CMakeLists.txt
-- include/

Let's say that in the top-level CMakeLists.txt I do the usual business of setting build settings, CXX flags, et cetera, and then I call include(ExternalDep), which checks if the "API" library is in the user's system (if not it is downloaded via CMAKE). In src/CMakeLists.txt I try to link against the API library using a

target_link_libraries(${PROJECT_NAME} PRIVATE ${API_LIBRARY})

The first issue I'm having is that before the "API" library can even be downloaded and built, I get the ninja build error I posted above. I'm positive the ExternalDep.cmake is included before I try to add the Project executable and link against the "API" library.

Here's a simplified version of ExternalDep.cmake:

  set(EXT_DEPS_PREFIX "ext_deps")

  ExternalProject_Add(ext_lib
    GIT_REPOSITORY "https://github.com/fake/api.git"
    GIT_TAG "master"
    PREFIX "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/api"
    TMP_DIR "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/api-tmp"
    STAMP_DIR "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/api-stamp"
    CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
    SOURCE_DIR "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/api/ext_api"
    BINARY_DIR "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/api/ext_api-build"
    BUILD_ALWAYS true
    TEST_COMMAND "")

  add_dependencies(ext_projects ext_api)

  set(API_LIBRARY "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/api/ext_api-build/src/lib/libapi.a")
like image 967
BlazePascal Avatar asked Oct 29 '16 00:10

BlazePascal


1 Answers

I ran into the same issue with Ninja while it worked fine with Unix Makefiles, and I managed to get it to work with Ninja by adding a BUILD_BYPRODUCTS line to my ExternalProject_Add block. Example:

    ExternalProject_Add(SDL2_PROJECT
        PREFIX 3rdparty
        URL https://www.libsdl.org/release/SDL2-2.0.5.tar.gz
        URL_MD5 d4055424d556b4a908aa76fad63abd3c
        CONFIGURE_COMMAND <SOURCE_DIR>/configure ${SDL2_configure_args} --prefix=<INSTALL_DIR> --disable-shared
        INSTALL_COMMAND make install -j9
        BUILD_BYPRODUCTS <INSTALL_DIR>/lib/libSDL2.a
    )
    ExternalProject_Get_Property(SDL2_PROJECT INSTALL_DIR)
    set(SDL2_INSTALL_DIR ${INSTALL_DIR})
    add_library(SDL2_LIBRARY STATIC IMPORTED GLOBAL)
    set_property(TARGET SDL2_LIBRARY PROPERTY IMPORTED_LOCATION ${SDL2_INSTALL_DIR}/lib/libSDL2.a)
    add_dependencies(SDL2_LIBRARY SDL2_PROJECT)
like image 91
mchiasson Avatar answered Sep 19 '22 23:09

mchiasson