ExternalProject_Add autogen project prevent configure on rebuild
Asked Answered
N

2

8

I have a CMake project on linux and I'm using ExternalProject to build Google Protobuf. It works great, however any subsequent builds still call the configure step in the external project (which is annoying because protobuf is an autogen project with a rather long step). I used the UPDATE_DISCONNECTED argument so it wouldn't re-clone which helps some, but you'd think if it didn't re-clone, it wouldn't need to re-configure or re-build/install. How can I get CMake to just build it the one time and skip subsequent builds (i.e. my next make from the build directory)?

Here's my CMakeLists.txt

cmake_minimum_required(VERSION 2.8.11)
project(pbuf_test)

include(${PROJECT_SOURCE_DIR}/cmake/protogen.cmake)

set(PBUF_DIR ${PROJECT_BINARY_DIR}/protobuf)

include(ExternalProject)
ExternalProject_Add(protobuf
    PREFIX ${PROTOBUF_DIR}
    GIT_REPOSITORY https://github.com/google/protobuf.git
    GIT_TAG v3.4.1
    UPDATE_DISCONNECTED 1
    BUILD_IN_SOURCE 1
    CONFIGURE_COMMAND ./autogen.sh COMMAND ./configure --prefix=${PBUF_DIR}
)

set(PBUF_INCLUDE_DIR ${PBUF_DIR}/include)
set(PBUF_LIBRARY ${PBUF_DIR}/lib/libprotobuf.so)
set(PBUF_PROTOC ${PBUF_DIR}/bin/protoc)

file(GLOB PBUF_FILES "${PROJECT_SOURCE_DIR}/msg/*.proto")
custom_protobuf_generate_cpp(PBUF_SRCS PBUF_HDRS ${PBUF_FILES})

include_directories(
    ${PROJECT_BINARY_DIR}
    ${PBUF_INCLUDE_DIR}
)

add_executable(${PROJECT_NAME} main.cpp ${PBUF_SRCS} ${PBUF_HDRS})
add_dependencies(${PROJECT_NAME} protobuf)
target_link_libraries(${PROJECT_NAME}
    ${PBUF_LIBRARY}
)   

Full example project here

Nutt answered 23/9, 2017 at 18:24 Comment(2)
Can people who run into this please comment and give a thumbs up for this problem report: gitlab.kitware.com/cmake/cmake/issues/19703Courtyard
I'm realizing that cmake is not really very flexible. Easy to build projects that use it. Cumbersome to make one.Inexpungible
I
1

The only way I know is to move the steps to build the external project into a script called by add_command. And then add an dependency between your project and the external project's output/lib/binary.

  • Pro: Avoids unnecessary rebuilds
  • Pro: Avoids unexpected updates of the external lib
  • Con: Does not rebuild in case the external repository was updated (and this is required)
  • Con: Additional work to write such a script

BTW: Within my project, we do it the hard way. But we do not want any unexpected updates of external libs.

Infrastructure answered 2/11, 2017 at 23:10 Comment(0)
I
1

It seems the solution to this for now that still uses ExternalProject is to move the configure step into the download step.

Something like this. Note the name of the target is the directory it expects the download to create. This might only work on certain operating systems because of the use of the && joiner: I'm a little new to cmake.

ExternalProject_Add(protobuf
    PREFIX ${PROTOBUF_DIR}
    DOWNLOAD_COMMAND git clone https://github.com/google/protobuf.git protobuf &&
        cd protobuf &&
        git checkout v3.4.1 &&
        ./autogen.sh &&
        ./configure --prefix=${PBUF_DIR}
    UPDATE_COMMAND git pull
    UPDATE_DISCONNECTED 1
    BUILD_IN_SOURCE 1
    CONFIGURE_COMMAND ""
)
Inexpungible answered 13/5, 2020 at 23:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.