Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cmake the following imported targets are referenced, but are missing

Tags:

c++

cmake

I have a repository with two libraries (liba and libb) whereas liba depends on libb. They are part of a single repository and are built using a single cmake "context". The file structure is shown below:

├── CMakeLists.txt
├── liba
│   ├── CMakeLists.txt
│   ├── internal
│   │   └── private.hh
│   ├── module.cc
│   ├── module.hh
└── libb
    ├── CMakeLists.txt
    ├── other.cc
    └── other.hh

Everything compiles and installs without any issues. Although, if I try to create a new project that depends on liba. Like so:

cmake_minimum_required(VERSION 3.5)

find_package(Threads REQUIRED)
find_package(OpenCV REQUIRED)
find_package(liba REQUIRED)

add_executable(exec exec.cc)
target_link_libraries(exec PRIVATE is::liba)

I get the following error:

CMake Error at CMakeLists.txt:5 (find_package):
  Found package configuration file:

    /home/hodor/is-sdk/lib/cmake/liba/libaConfig.cmake

  but it set liba_FOUND to FALSE so package "liba" is considered to be NOT
  FOUND.  Reason given by package:

  The following imported targets are referenced, but are missing: is::libb

What I am missing here? Repository link for context

CMakeLists that generates liba:

cmake_minimum_required(VERSION 3.5)
include(GNUInstallDirs)

find_package(OpenCV REQUIRED core)
find_package(Threads REQUIRED)

list(APPEND liba_public_headers 
  "module.hh"
)

list(APPEND liba_private_headers 
  "internal/private.hh"
)

list(APPEND liba_sources 
  "module.cc"
  ${liba_public_headers}
  ${liba_private_headers}
)

add_library(liba ${liba_sources})

target_include_directories(
  liba
 PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> # for headers when building
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # for generated files in build mode
  $<INSTALL_INTERFACE:include/is/liba> # for clients in install mode
 PRIVATE
  ${OpenCV_INCLUDE_DIRS}
)

target_link_libraries(liba 
 PRIVATE
  is::libb
  ${OpenCV_LIBRARIES} 
  Threads::Threads
)

set_property(TARGET liba PROPERTY CXX_STANDARD 11)

install(
  TARGETS liba EXPORT libaTargets
  LIBRARY  DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  ARCHIVE  DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  RUNTIME  DESTINATION "${CMAKE_INSTALL_BINDIR}"
  INCLUDES  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)

install(FILES ${liba_public_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/is/liba)

install(
  EXPORT libaTargets
  FILE libaConfig.cmake
  NAMESPACE is::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/liba
)

CMakeLists that generates libb:

cmake_minimum_required(VERSION 3.5)
include(GNUInstallDirs)

list(APPEND libb_public_headers 
  "other.hh"
)

list(APPEND libb_sources 
  "other.cc"
  ${libb_public_headers}
)

add_library(libb ${libb_sources})

target_include_directories(
  libb
 PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> # for headers when building
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # for generated files in build mode
  $<INSTALL_INTERFACE:include/is/libb> # for clients in install mode
)

install(
  TARGETS libb EXPORT libbTargets
  LIBRARY  DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  ARCHIVE  DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  RUNTIME  DESTINATION "${CMAKE_INSTALL_BINDIR}"
  INCLUDES  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)

install(FILES ${libb_public_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/is/libb)

install(
  EXPORT libbTargets
  FILE libbConfig.cmake
  NAMESPACE is::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libb
)

add_library(is::libb ALIAS libb)

Top level CMakeLists that includes liba and libb:

cmake_minimum_required(VERSION 3.5)

add_subdirectory(liba)
add_subdirectory(libb)
like image 981
Rodolfo Picoreti Avatar asked Apr 27 '18 11:04

Rodolfo Picoreti


People also ask

What is imported target in CMake?

IMPORTED targets are used to convert files outside of a CMake project into logical targets inside of the project. IMPORTED targets are created using the IMPORTED option of the add_executable() and add_library() commands. No build files are generated for IMPORTED targets.

How do I add a library to CMake?

To add a library in CMake, use the add_library() command and specify which source files should make up the library. Rather than placing all of the source files in one directory, we can organize our project with one or more subdirectories. In this case, we will create a subdirectory specifically for our library.


1 Answers

After watching C++Now 2017: Daniel Pfeifer “Effective CMake" I now realized what was missing in my configuration. As mentioned by @Tsyvarev the problem was about libaConfig.cmake.

When exporting a library with dependencies you should export mylibraryTargets.cmake, like so:

install(
  EXPORT libaTargets
  FILE libaTargets.cmake
  NAMESPACE is::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/liba
)

And then manually (a bit disappointed here I have to say) write a mylibraryConfig.cmake with all the dependencies like so:

include(CMakeFindDependencyMacro)

find_dependency(libb)
find_dependency(OpenCV)
find_dependency(Threads)

include("${CMAKE_CURRENT_LIST_DIR}/libaTargets.cmake")
like image 164
Rodolfo Picoreti Avatar answered Sep 26 '22 01:09

Rodolfo Picoreti