How to configure ExternalProject during main project configuration?

后端 未结 4 612
粉色の甜心
粉色の甜心 2021-02-05 10:37

The CMake\'s ExternalProject allows to define how to an external project is going to be downloaded, configured, built and installed. All whose steps are going to be performed at

相关标签:
4条回答
  • 2021-02-05 10:59

    If you don't want to build the project at configure-time, but just want to download it, use FetchContent. FetchContent_Declare uses many of the same arguments as ExternalProject_Add, except it doesn't allow building the project.

    The documentation has a great example on how to use this:

    FetchContent_Declare(
      googletest
      GIT_REPOSITORY https://github.com/google/googletest.git
      GIT_TAG        release-1.8.0
    )
    
    FetchContent_GetProperties(googletest)
    if(NOT googletest_POPULATED)
      FetchContent_Populate(googletest)
      add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
    endif()
    

    This requires CMake 3.11 or later. For prior versions, you can download the FetchContent.cmake module from the CMake repository along with the FetchContent directory, ensuring you comply with the BSD 3-Clause license.

    † Building at configure-time has some serious drawbacks. For example, users of your library can't control the build process unless you set it up very carefully. A package manager is a better solution

    0 讨论(0)
  • 2021-02-05 11:01

    Since CMake 3.14 and up wards, this how you use FetchContent

    FetchContent_Declare(
      googletest
      GIT_REPOSITORY https://github.com/google/googletest.git
      GIT_TAG        release-1.8.0
    )
    
    FetchContent_MakeAvailable(googletest)
    

    Then to build your test test/CMakeLists.txt

    cmake_minimum_required(VERSION 3.15)
    project(${PROJECT_NAME}_test)
    
    # Tests for mu_project
    file(GLOB_RECURSE TEST_SOURCES 
        ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
        ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
    )
    
    add_executable(${PROJECT_NAME}_test ${TEST_SOURCES})
    target_link_libraries(${PROJECT_NAME}_test gtest gmock_main)
    
    # Register the tests
    add_test(NAME ${PROJECT_NAME}_test
             COMMAND ${PROJECT_NAME}_test)
    enable_testing()
    

    You're now good to go

    0 讨论(0)
  • 2021-02-05 11:08

    ExternalProject is just a sequence of steps to perform. So you may use two instances of it:

    1. ExternalProject_Add() call to be built at main project's configuration stage. E.g., as described in that question:

    other_project/CMakeLists.txt:

    project(other_project)
    include(ExternalProject)
    
    ExternalProject_Add(<project_name> <options...>
        BUILD_COMMAND "" # Disable build step.
        INSTALL_COMMAND "" # Disable install step too.
    )
    

    CMakeLists.txt:

    # The first external project will be built at *configure stage*
    execute_process(
        COMMAND ${CMAKE_COMMAND} --build . ${CMAKE_SOURCE_DIR}/other_project
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/other_project
    )
    
    1. ExternalProject_Add() call to be built at main project's build stage.

    CMakeLists.txt:

    # The second external project will be built at *build stage*
    ExternalProject_Add(<project_name> <options...>
        CONFIGURE_COMMAND "" # Disable configure step. But other steps will be generated.
    )
    

    By using same <options> for both ExternalProject_Add() calls we achieve "preemption" of both external projects created: build and follow steps of the second project will use result of configure step of the first one.

    0 讨论(0)
  • 2021-02-05 11:15

    The Hunter C++ package manager does what I asked for. Hunter is based on CMake ExternalProject, but comes with a set of predefined projects. Also, it builds the dependencies during configuration and they can be accessed by find_package(... CONFIG). Very nice stuff!

    0 讨论(0)
提交回复
热议问题