libunifex
libunifex copied to clipboard
`std::coroutines` in INTERFACE_LINK_LIBRARIES breaks cmake packages that consume libunifex
The CMake config file installed with unifex (e.g., /usr/local/cmake/lib/unifexConfig.cmake
) contains the following:
set_target_properties(unifex::unifex PROPERTIES
INTERFACE_COMPILE_FEATURES "cxx_std_17"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "std::coroutines"
)
Having std::coroutines in INTERFACE_LINK_LIBRARIES
means a package that declares a dependency on unifex also depends on std::coroutines. (This happens because std::coroutines is declared with the INTERFACE
keyword, in libunifex/cmake/FindCoroutines.cmake
.) But a definition for std::coroutines itself isn't published, so the consuming project will fail to configure, with
CMake Error at CMakeLists.txt:33 (add_executable):
Target "myproject_mytarget" links to target "std::coroutines" but the target
was not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?
I asked a cmake expert, who said:
Enabling coroutines for older compilers is a project level concern that's done by setting flags in a toolchain/the command-line. Best course of action would be reporting the broken install interface and suggesting removing that find module altogether.
I hereby so report and suggest.
They also suggested a workaround for the consuming package to include()
in its CMakeLists.txt,
In the meantime, you can use a find module to proxy the package discovery and remove the faulty bits:
# Findunifex.cmake
find_package(unifex NO_MODULE)
if(unifex_FOUND)
get_target_property(link_libs unifex::unifex INTERFACE_LINK_LIBRARIES)
list(REMOVE_ITEM link_libs std::coroutines)
set_property(TARGET unifex::unifex PROPERTY INTERFACE_LINK_LIBRARIES "${link_libs}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(unifex CONFIG_MODE)
Correction: the find module should not be include
d. It is for find_package
, when operating in module mode. Instead, save the find module in the consuming project as cmake/find/Findunifex.cmake
. Add the following to the consuming project's CMakeLists.txt
(as usual):
find_package(unifex REQUIRED)
target_link_libraries(
myproject_mytarget PRIVATE unifex::unifex
)
Then the person bulding the package can tell find_package
to use the find module, if they decide they need to, by adding cmake/find
to CMAKE_MODULE_PATH when configuring. For example,
cmake -S . -B build -DCMAKE_MODULE_PATH=./cmake/find
It's possible to only depends on std::coroutines
at build time.
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -77,7 +77,7 @@ target_include_directories(unifex
target_compile_features(unifex PUBLIC cxx_std_17)
if(CXX_COROUTINES_HAVE_COROUTINES)
- target_link_libraries(unifex PUBLIC std::coroutines)
+ target_link_libraries(unifex PUBLIC $<BUILD_INTERFACE:std::coroutines>)
endif()
configure_file(unifex.pc.in unifex.pc @ONLY)
Thanks for flagging this bug with a suggested fix @bustercopley and @l2x-huang. We're planning on investing more time into maintaining this library, and we've filed a task to address this bug to our backlog.