CMake: How to build external projects and include their targets

cmake, external-project

Solution

I think you're mixing up two different paradigms here.

As you noted, the highly flexible `ExternalProject` module runs its commands at build time, so you can't make direct use of Project A's import file since it's only created once Project A has been installed.

If you want to `include` Project A's import file, you'll have to install Project A manually before invoking Project B's CMakeLists.txt - just like any other third-party dependency added this way or via `find_file` / `find_library` / `find_package`.

If you want to make use of `ExternalProject_Add`, you'll need to add something like the following to your CMakeLists.txt:

ExternalProject_Add(project_a
  URL ...project_a.tar.gz
  PREFIX ${CMAKE_CURRENT_BINARY_DIR}/project_a
  CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
)

include(${CMAKE_CURRENT_BINARY_DIR}/lib/project_a/project_a-targets.cmake)

ExternalProject_Get_Property(project_a install_dir)
include_directories(${install_dir}/include)

add_dependencies(project_b_exe project_a)
target_link_libraries(project_b_exe ${install_dir}/lib/alib.lib)

Problem

I have a Project A that exports a static library as a target: ``` install(TARGETS alib DESTINATION lib EXPORT project_a-targets) install(EXPORT project_a-targets DESTINATION lib/alib) ``` Now I want to use Project A as an external project from Project B and include its built targets: ``` ExternalProject_Add(project_a URL ...project_a.tar.gz PREFIX ${CMAKE_CURRENT_BINARY_DIR}/project_a CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ) include(${CMAKE_CURRENT_BINARY_DIR}/lib/project_a/project_a-targets.cmake) ``` The problem is that the include file does not exist yet when CMakeLists of Project B is run. Is there a way to make the include dependent on the external project being built? Update: I wrote a short CMake by Example tutorial based on this and other common problems I encountered.

Original source

Related problems