user2721842
user2721842

Reputation:

CMake: rebuild external project

I have a project that uses an external library. The project's CMakeLists.txt looks like this:

cmake_minimum_required(VERSION 3.6.0)

project(my-project)

set(CMAKE_CXX_STANDARD 14)

include(ExternalProject)
find_package(Git REQUIRED)

ExternalProject_Add(library
        PREFIX ${my-project_SOURCE_DIR}/lib/library
        GIT_REPOSITORY https://github.com/vendor/library
        GIT_TAG master
        UPDATE_COMMAND ""
        INSTALL_COMMAND ""
        )

link_directories(${my-project_SOURCE_DIR}/lib/library/src/library-build/src)

add_subdirectory(src)

And src/CMakeLists.txt like this:

include_directories(../lib/library/src/library/include)

add_executable(my-project
        main.cpp
        )

add_dependencies(my-project library)

target_link_libraries(my-project liblibrary.a)

It pulls the library from Git and builds it for the first time without any problems.

I want to edit source code of the library and have the library .a file be recompiled automatically. What is the cleanest way I can achieve that? It currently ignores any updates to the source code, because it already has .a file of the library.

When I try to add

add_subdirectory(lib/library/src/library/src)

to my main CMakeLists.txt, I get the following error:

CMake Error at lib/library/src/library/src/CMakeLists.txt:55 (add_library): add_library cannot create target "library" because another target with the same name already exists. The existing target is a custom target created in source directory "/cygdrive/c/Code/my-project". See documentation for policy CMP0002 for more details.

I guess it's caused by calling

add_library(gram STATIC ${SOURCE_FILES})

in the library CMakeLists.txt and then calling

ExternalProject_Add(library ...)

in the project CMakeLists.txt.

Any ideas?

Upvotes: 1

Views: 4056

Answers (2)

Jagger Yu
Jagger Yu

Reputation: 637

add this command in ExternalProject_Add maybe help you: UPDATE_COMMAND ""

https://gitlab.kitware.com/cmake/cmake/issues/16419

Upvotes: 0

Torbjörn
Torbjörn

Reputation: 5800

As your main goal for using ExternalProject_Add is to download the dependency from an external source without configuring and building it, you could define the CMAKE_COMMAND, CONFIGURE_COMMAND and BUILD_COMMAND as empty strings. Same as you already did for the UPDATE_COMMAND and INSTALL_COMMAND. That way, ExternalProject_Add will only clone the repository once.

To overcome the name clash, just use a different one for the first argument of ExternalProject_Add, e.g. library_src:

ExternalProject_Add(library_src
    PREFIX ${my-project_SOURCE_DIR}/lib/library
    GIT_REPOSITORY https://github.com/vendor/library
    GIT_TAG master
    UPDATE_COMMAND ""
    CONFIGURE_COMMAND ""
    CMAKE_COMMAND ""
    BUILD_COMMAND ""
    INSTALL_COMMAND ""
)
ExternalProject_Get_Property(library_src SOURCE_DIR)
add_subdirectory(${SOURCE_DIR})

The second command (ExternalProject_Get_Property) will give you the named properties for the given external project. The output variables are of the same name as the properties. That way, you are immune against changes in the behaviour of ExternalProject_Add where it places the actual source tree.

Upvotes: 1

Related Questions