[cmake-developers] [CMake] Ensuring an external project is built and installed before trying to call "find_package" on it
Timothy Wrona
tjwrona1992 at gmail.com
Mon Feb 25 22:31:10 EST 2019
I've tried a couple different approaches with ExternalProject_Add and
FetchContent, but none of them seem quite right... CMake just doesn't seem
to conpletely fulfill the role of a full blown package manager. I mean it
works, but it just feels like it could be better. I've decided I'm going to
take a few days and really try to learn how to use the Conan package
manager in depth. If it works out well I will try to summarize and report
some of my findings. :)
Thanks,
Tim
On Sat, Feb 23, 2019 at 2:32 AM Craig Scott <craig.scott at crascit.com> wrote:
>
>
> On Sat, Feb 23, 2019 at 4:14 PM Timothy Wrona <tjwrona1992 at gmail.com>
> wrote:
>
>> I am working on a CMake project that depends on a couple other projects I
>> have previously written. I would like to include those other projects using
>> "ExternalProject_Add", but I am having some issues.
>>
>> The basic layout of the project is this:
>>
>> cmake_minimum_required(VERSION 3.14.0)
>>
>> project(ProjectWithDependencies)
>>
>> include(ExternalProject)
>> ExternalProject_Add(Dependency1
>> GIT_REPOSITORY <URL to git repo>
>> )
>> ExternalProject_Add(Dependency2
>> GIT_REPOSITORY <URL to git repo>
>> )
>>
>> find_package(Dependency1 Required)
>> find_package(Dependency2 Required)
>>
>> # Use targets
>>
>> I was under the assumption that "ExternalProject_Add" would automatically
>> build and install the dependencies before getting to the "find_package"
>> calls (they are CMake projects so the default build and install commands
>> should be fine) but this doesn't seem to be how it works.
>>
>> When I get to "find_package" it fails because the dependency hasn't been
>> installed yet.
>>
>> How can I ensure that the dependencies are fully compiled and installed
>> before attempting to find them? (Note: FetchContent doesn't work here
>> because the two projects "Dependency1" and "Dependency2" have targets with
>> the same name which causes FetchContent to fail.)
>>
>> Any help is appreciated.
>>
>
> find_package() requires that the dependencies have been built already, as
> you've noted. When CMake runs and processes your example CMakeLists.txt
> file, it sets up the build rules for Dependency1 and Dependency2, but they
> won't actually be configured, built and installed until you build the main
> project. Since your find_package() calls will be processed during the
> configure stage of the main project (i.e. before the build stage), it's too
> early.
>
> To address this, you need to make your main project a true superbuild
> where it basically contains nothing more than a set of
> ExternalProject_Add() calls. Rather than putting the find_package() calls
> and use of targets directly in the main build, you can add it as another
> sub-build. Note that this will mean that none of the targets you define in
> the mainBuild will be visible as targets in your top level superbuild
> project. I'd also advise you to override the default install location of
> your dependencies. Otherwise they will typically try to install to a
> system-wide location, which is not usually a good thing. Putting it
> together, the top level superbuild project would look something like this:
>
> cmake_minimum_required(VERSION 3.14.0)
> project(ProjectWithDependencies)
>
> set(installDir ${CMAKE_CURRENT_BINARY_DIR}/install)
>
> include(ExternalProject)
> ExternalProject_Add(Dependency1
> GIT_REPOSITORY <URL to git repo>
> INSTALL_DIR ${installDir}
> CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
> )
> ExternalProject_Add(Dependency2
> GIT_REPOSITORY <URL to git repo>
> INSTALL_DIR ${installDir}
> CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
> )
> ExternalProject_Add(mainBuild
> SOURCE_DIR <path_to_some_subdir_in_this_repo>
> INSTALL_DIR ${installDir}
> DEPENDS Dependency1 Dependency2
> CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
> -DCMAKE_PREFIX_PATH:PATH=<INSTALL_DIR>
> )
>
> Or you could make the superbuild a completely separate repo and then use
> GIT_REPOSITORY rather than SOURCE_DIR for the "mainBuild" part.
>
> --
> Craig Scott
> Melbourne, Australia
> https://crascit.com
>
> Get the hand-book for every CMake user: Professional CMake: A Practical
> Guide <https://crascit.com/professional-cmake/>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake-developers/attachments/20190225/ac282cf6/attachment.html>
More information about the cmake-developers
mailing list