I'm trying to write a cmake script for installing a project I'm working on. Part of this is the necessary install(EXPORT LIB_EXPORTS ...)
where LIB_EXPORTS
is what I've been using for the EXPORT property in my various install(TARGETS ...)
.
I have a superbuild structure that uses add_subdirectory
to build some projects (SDL2, CivetWeb) that my project depends on.
My problem is that when I use target_link_libraries
to add a link from a subproject (SDL2-static from SDL2, c-library from CivetWeb) cmake complains that these dependencies aren't in the export set.
CMake Error: install(EXPORT "LIB_EXPORTS" ...) includes target "sc2api" which requires target "c-library" that is not in the export set.
CMake Error: install(EXPORT "LIB_EXPORTS" ...) includes target "sc2renderer" which requires target "SDL2-static" that is not in the export set.
The only way I know to add targets to an export set is by using install(TARGETS ... EXPORT LIB_EXPORTS)
but we can't install a target that this subdirectory hasn't created. I could install(FILES ... EXPORT LIB_EXPORTS)
if I could find for sure where that library file's been generated but I have a feeling that this would install it twice (once by the CMakeLists.txt in the project subdirectory, once here). Frankly, I'm not sure why including these are necessary, since the libraries should be statically linked into the targets in my project.
My questions:
we can't install a target that this subdirectory hasn't created
First off, this isn't quite true. Since you're adding your dependencies with add_subdirectory
, they are not IMPORTED
; this means they are globally visible and it doesn't matter where in the project they were created. It just matters that they have been created in time for the call to install(TARGETS)
.
One convenient approach is to put all your packaging commands in packaging/CMakeLists.txt
and then call add_subdirectory(packaging)
at the end of your top-level CMakeLists.txt
so that every target has been created before the first install()
call.
You would then add the targets to your normal export set:
install(TARGETS sc2api sc2renderer c-library SDL2-static
EXPORT LIB_EXPORTS
...)
install(EXPORT LIB_EXPORTS ...)
This is the preferred way of doing things.
Frankly, I'm not sure why including these are necessary, since the libraries should be statically linked into the targets in my project.
They might carry their own usage requirements, like other libraries they depend on. So when exporting, CMake needs to recreate everything that's relevant to using your library, including all transitive dependencies. If you're absolutely certain that this will never be a concern, you can use $<BUILD_INTERFACE:...>
to block the dependency from exporting.
add_library(sc2api SHARED)
target_link_libraries(sc2api PRIVATE $<BUILD_INTERFACE:c-library>)
This is occasionally useful for INTERFACE
libraries that collect warning flags or the like, and would export as empty targets.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With