jhaiduce
jhaiduce

Reputation: 438

CMake can't find header from dependency of imported project

I have a CMake project C that depends on project B, which in turn depends on project A. I've created a superbuild that builds all three. Project C uses headers from project B, and my CMakeLists for Project C looks like this:

cmake_minimum_required(VERSION 3.10)

project(code_c)

find_package(b REQUIRED)

add_library(c c.c)
target_link_libraries(c PUBLIC b)
target_include_directories(c INTERFACE
  $<INSTALL_INTERFACE:include>)
install(TARGETS c EXPORT c)
install(FILES c.h DESTINATION include)

export(PACKAGE c)

export(TARGETS c FILE "${PROJECT_BINARY_DIR}/bTargets.cmake")

install(EXPORT c FILE aTargets.cmake DESTINATION lib/cmake/c)

include(CMakePackageConfigHelpers)

configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/cConfig.cmake"
  INSTALL_DESTINATION lib/cmake/c)

install(FILES
  "${CMAKE_CURRENT_BINARY_DIR}/cConfig.cmake"
  DESTINATION lib/cmake/c)

install(EXPORT c
  FILE cTargets.cmake
  DESTINATION lib/cmake/c)

My CMakeLists for Project B looks like this:

cmake_minimum_required(VERSION 3.10)

project(code_b)

find_package(a REQUIRED)

add_library(b b.c)
target_link_libraries(b PUBLIC a)
target_include_directories(b INTERFACE
  $<INSTALL_INTERFACE:include>)
install(TARGETS b EXPORT b)
install(FILES b.h DESTINATION include)

export(PACKAGE b)

export(TARGETS b FILE "${PROJECT_BINARY_DIR}/bTargets.cmake")

install(EXPORT b FILE aTargets.cmake DESTINATION lib/cmake/b)

include(CMakePackageConfigHelpers)

configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/bConfig.cmake"
  INSTALL_DESTINATION lib/cmake/b)

install(FILES
  "${CMAKE_CURRENT_BINARY_DIR}/bConfig.cmake"
  DESTINATION lib/cmake/b)

install(EXPORT b
  FILE bTargets.cmake
  DESTINATION lib/cmake/b)

My Config.cmake.in for Project B looks like

@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/bTargets.cmake")

check_required_components(b)

When I attempt to build Project C, I get

/Users/jhaiduce/Development/cmake_include_test/build/b/include/b.h:4:10: fatal error: 
      'a.h' file not found
#include "a.h"
         ^~~~~
1 error generated.

However, if I add find_package(a REQUIRED) to the CMakeLists.txt for Project A, then the include directories from target 'a' are added to the build and Project C compiles successfully. Should this be necessary? I would have expected that CMake would export Project A's targets along with Project B, making it unneccesary to call find_package(a) from Project C. Does the fact that Project C fails to build without this indicate a problem with the way I exported Project B?

Upvotes: 0

Views: 335

Answers (1)

Mizux
Mizux

Reputation: 9271

I think in BConfig.cmake.in you should use:

include(CMakeFindDependencyMacro)
if(NOT A_FOUND AND NOT TARGET a)
  find_dependency(A REQUIRED)
endif()

ref:

Upvotes: 1

Related Questions