I have the following reduced CMake code for using Abseil in a library: (minimal repository to reproduce)
cmake_minimum_required(VERSION 3.20)
project(MyProject)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
set(ABSL_PROPAGATE_CXX_STD ON)
find_package(absl REQUIRED)
add_library(MyStaticLibTarget STATIC MyStaticLib.cpp)
target_link_libraries(MyStaticLibTarget absl::strings)
install(TARGETS MyStaticLibTarget EXPORT MyProjectTargets)
install(TARGETS strings EXPORT MyProjectTargets)
if(EXPORT_MYSTATICLIB)
export(TARGETS MyStaticLibTarget FILE lib/cmake/MyProject/MyProjectTargets.cmake)
endif()
# Setup for downstream clients of MyProject?
install(EXPORT MyProjectTargets DESTINATION lib/cmake/MyProject COMPONENT cmake-exports)
However, I run into an error as shown if I try to use the export
code path, when running CMake with:
cmake -G Ninja -S . -B build -DABSL_ENABLE_INSTALL=ON -DEXPORT_MYSTATICLIB=ON
# CMake Error in CMakeLists.txt:
# export called with target "MyStaticLibTarget" which requires target
# "strings" that is not in any export set.
I don't understand the error message; it seems to me that strings
is already part of MyProjectTargets
(which I think is an export set?), so there shouldn't be any error.
That said, based on the error message, I tried adding an export
line for strings
, and transitively fixed all the errors, and I ended up with
export(TARGETS
strings
strings_internal
type_traits
base
config
throw_delegate
dynamic_annotations
log_severity
base_internal
raw_logging_internal
atomic_hook
core_headers
spinlock_wait
endian
bits
int128
memory
errno_saver
meta
APPEND FILE lib/cmake/MyProject/MyProjectTargets.cmake)
That does fix all errors! In practice, this would be very painful to do by hand for a larger library. It also seems like the "wrong" solution, because I am naming lots of internal details of Abseil by hand.
- Is manually adding the targets as above the "right" solution?
- Is there a better way to achieve the same result as above?
I have the following constraints:
- I need to export
MyStaticLibTarget
so it can be used by downstream clients. - I'm pretty sure the dependency (in
target_link_libraries
) needs to be public, as in the actual case (this is a minimal example), Abseil headers will be included in the library's public headers.