schrödinbug
schrödinbug

Reputation: 873

CMake Error: install EXPORT includes target which requires target that is not in any export set

I'm writing a library that has a few dependencies that are pulled in via CMake's FetchContent. In my toplevel CMakeLists.txt, close to the top I have:

include(external/dependencies.cmake) which contains

include(FetchContent)
   
# a pretty awesome text formatting library
option(_USE_FMT "include components for formatting helpers based on fmt" ON)
if(_USE_FMT)
FetchContent_Declare(
  fmt_fc
  GIT_REPOSITORY https://github.com/fmtlib/fmt.git
  GIT_TAG 7.1.3
  GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(fmt_fc)
endif()
       
FetchContent_Declare(
  eigen_fc
  GIT_REPOSITORY https://github.com/eigenteam/eigen-git-mirror.git
  GIT_TAG 3.3.7
  GIT_SHALLOW TRUE
)

# # do the actual fetching

FetchContent_MakeAvailable(eigen_fc)

so I have a couple of dependencies, fmt and eigen, with fmt being optional. Later on in the toplevel CMakeLists.txt I have a

add_library(my_common "")
add_library(my::my_common ALIAS my_common)
#...
add_subdirectory(src)
add_subdirectory(extras)

in src, I have several target_sources() statements that add files to the target and in one directory I have a

target_link_libraries(my_common
  PUBLIC
    eigen 
)

and in extras I have a CMakeLists.txt that follows the same pattern (not shown is a guard to omit adding this directory if the option _USE_FMT is set as such):

target_sources(my_common
PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/geometry_adapters.hpp>
  $<INSTALL_INTERFACE:${MY_COMMON_INSTALL_INCLUDE_DIR}/geometry_adapters.hpp>
)
# ...
target_link_libraries(my_common
PUBLIC
  fmt::fmt
)

later in the toplevel CMakeLists.txt I have

install(TARGETS my_common EXPORT my_common-targets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/my_common
)

prior to me adding fmt with just eigen (and actually catch2 as well, although it's snipped out for brevity) everything was great this worked as I would've expected it to. However after adding fmt, I'm getting this error in the generation phase:

CMake Error: install(EXPORT "my_common-targets" ...) includes target "my_common" which requires target "fmt" that is not in any export set.

adding fmt to the install command above fixes it, but that doesn't seem right--why is this required for fmt and not eigen (or catch2)? All three of those libraries have very good cmake support and have their own install (TARGETS ... EXPORT) command. One thing I can think of might be that eigen and catch2 are header only?

Any thoughts?

Upvotes: 5

Views: 6043

Answers (1)

Mizux
Mizux

Reputation: 9329

Because in fmt, install rules are disabled if it's a subproject...

# Determine if fmt is built as a subproject (using add_subdirectory)
# or if it is the master project.
if (NOT DEFINED FMT_MASTER_PROJECT)
  set(FMT_MASTER_PROJECT OFF)
  if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
    set(FMT_MASTER_PROJECT ON)
    message(STATUS "CMake version: ${CMAKE_VERSION}")
  endif ()
endif ()

ref: https://github.com/fmtlib/fmt/blob/373262f9fbacab7d868ab10f1f0b20978c096572/CMakeLists.txt#L8-L16

option(FMT_INSTALL "Generate the install target." ${FMT_MASTER_PROJECT})

ref: https://github.com/fmtlib/fmt/blob/373262f9fbacab7d868ab10f1f0b20978c096572/CMakeLists.txt#L67

then:

# Install targets.
if (FMT_INSTALL)
  ...

https://github.com/fmtlib/fmt/blob/373262f9fbacab7d868ab10f1f0b20978c096572/CMakeLists.txt#L260-L261

If CMP0077 is set to new, you can try to use set(FMT_INSTALL ON)

Upvotes: 5

Related Questions