On Sat, Feb 23, 2019 at 4:14 PM Timothy Wrona <tjwrona1...@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/>
-- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: https://cmake.org/mailman/listinfo/cmake