Reputation: 873
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
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