CMake ExternalProject_Add and parallel builds
Asked Answered
S

3

6

With the following CMakeLists.txt build script:

include( ExternalProject )
ExternalProject_Add( framework SOURCE_DIR ${framework_SOURCE}
                     PREFIX framework_build
                     INSTALL_DIR ${framework_DISTRIBUTION} )

    ...

add_library( ${PROJECT_NAME} SHARED ${BUILD_MANIFEST} )
add_dependencies( ${PROJECT_NAME} framework )

When I attempt to perform a parallel build (make -j5) it will occasionally fail due to a build artefact from the framework not being present. The order of the build, fixed by add_dependencies, is not being adhered to.

Have I misunderstood the documentation around add_dependencies?

Output from cmake --graphviz=graph.dot

enter image description here

Status answered 4/7, 2015 at 16:16 Comment(0)
S
2

Ok, so an updated version of CMake has warned me that the framework dependency is not present. ExternalProject_Add and add_dependencies can not be used with each other, as ExternalProject_Add has not actually built and therefore registered the framework as a high-level target.

Note: Anyone encountering this problem in future. I've found another SO post by @matiu that resolved my issue.

Status answered 5/7, 2015 at 10:10 Comment(0)
S
0

Maybe ExternalProject_Add_StepDependencies could solve that and create a dependency between the externalproject_add and the imported target?

Selfexamination answered 17/9, 2020 at 21:46 Comment(0)
U
-1

This is a minimal working example adding Google test as a dependency.

    cmake_minimum_required(VERSION 2.8)
    project(ExampleProject)

    # Set the build type if it isn't already
    if(NOT CMAKE_BUILD_TYPE)
      set(CMAKE_BUILD_TYPE Debug)
    endif()

    include(ExternalProject)

    set(GOOGLE_TEST GoogleTest)
    set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/${GOOGLE_TEST}")

    ExternalProject_Add(${GOOGLE_TEST}
      GIT_REPOSITORY https://chromium.googlesource.com/external/googletest 
      PREFIX ${GTEST_PREFIX}
      CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 
      INSTALL_COMMAND ""
    )

    # Specify include directory
    ExternalProject_Get_Property(${GOOGLE_TEST} source_dir)
    include_directories(${source_dir}/include)

    set(LIBPREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
    set(LIBSUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
    set(GTEST_LOCATION "${GTEST_PREFIX}/src/${GOOGLE_TEST}-build")
    set(GTEST_LIBRARY  "${GTEST_LOCATION}/${LIBPREFIX}gtest${LIBSUFFIX}")
    set(EXECUTABLE_NAME ${CMAKE_PROJECT_NAME})

    add_executable(${EXECUTABLE_NAME} main.cpp)
    add_dependencies(${EXECUTABLE_NAME} ${GOOGLE_TEST})

    target_link_libraries(
        ${EXECUTABLE_NAME}
        ${GTEST_LIBRARY}
        -lpthread
    )

    enable_testing()
    set(TEST_NAME ${EXECUTABLE_NAME})
    add_test(${EXECUTABLE_NAME} ${TEST_NAME})

And this is the dependency graph:

CMake graph

In this case without add_dependencies a parallel build will always fail, because of missing the dependency.

Unlettered answered 5/7, 2015 at 10:59 Comment(3)
Why have you merely repeated my posts? This is just static.Status
I've just shared working example of combination of ExternalProject_Add and add_dependencies. Because your build sometimes fail you can compare code and find a difference. In my case running cmake in parallel doesn't cause any problems. Graph shows also that main project depends on the external project. Without add_dependencies cmake don't know what is the dependency between those project and try to build it in parallel.Unlettered
Thanks for the additional static (comment).Status

© 2022 - 2024 — McMap. All rights reserved.