cmakedependenciescross-compilingstamp

How to reuse extracted source with CMake's ExternalProject_Add?


I use the following CMake file to automatically download and compile the Boost libraries. After generating project files for my compiler, I run cmake --build . --config Debug and cmake --build . --config Release to build both variants. So I envoke the build process twice. Even though CMake is clever enough to not download the archive again if the checksum still matches, it extracts it into the source directory twice. Extraction takes a couple of minutes for the large Boost libraries, so I'd like to prevent CMake from doing it for the second build.

ExternalProject_Add(Boost
    PREFIX            ${BOOST_PREFIX}
    TMP_DIR           ${BOOST_PREFIX}/temp
    STAMP_DIR         ${BOOST_PREFIX}/stamp
    #--Download step--------------
    DOWNLOAD_DIR      ${BOOST_PREFIX}/download
    URL               http://downloads.sourceforge.net/project/boost/boost/1.56.0/boost_1_56_0.tar.gz
    URL_MD5           8c54705c424513fa2be0042696a3a162
    #--Update/Patch step----------
    UPDATE_COMMAND    ""
    #--Configure step-------------
    SOURCE_DIR        ${BOOST_PREFIX}/source
    CONFIGURE_COMMAND ${BOOST_CONFIGURE_COMMAND}
    #--Build step-----------------
    BUILD_COMMAND     ${BOOST_BUILD_EXECUTABLE} install
                          --build-dir=${BOOST_PREFIX}/build
                          --prefix=${BOOST_PREFIX}/install
                          variant=${BOOST_VARIANT}
                          link=${BOOST_LINK}
                          threading=multi
                          address-model=32
                          toolset=${BOOST_TOOLSET}
                          runtime-link=${BOOST_RUNTIME_LINK}
    BUILD_IN_SOURCE   1
    #--Install step---------------
    INSTALL_COMMAND   ""
)

In this particually example it would possible to just use variant=debug,release, but there are some other external dependencies in my project that I build this way. How can I make CMake only extract the archive if it downloaded a new one?


Solution

  • Create two projects: Foo-Release and Foo-Debug. Leave DOWNLOAD_COMMAND empty for the second project and make it depends on the first. Set SOURCE_DIR explicilty for both projects (point to the same directory). I.e.:

    set(source_dir "${CMAKE_CURRENT_BINARY_DIR}/3rdParty/Foo/Source")
    
    ExternalProject_Add(
        Foo-Release
        URL "..."
        URL_HASH SHA1=...
        SOURCE_DIR "${source_dir}"
        ...
    )
    
    ExternalProject_Add(
        Foo-Debug
        DOWNLOAD_COMMAND
        ""
        SOURCE_DIR "${source_dir}"
        ...
    )
    
    add_dependencies(Foo-Debug Foo-Release)