Reputation: 1733
I have an executable and a dynamic library that both depend on a static libary. If more context helps, the executable embeds a Python interperter and the dynamic library is a Python extension module. The dynamic library should not link to the static library because the later is already linked by the executable. However, the dynamic library requires headers from the static library to compile, which is only supplied implicitly via target_link_libraries
. In effect, What I need is a target_link_libraries
that adds include paths and does nothing else.
Here is what I've tried:
Retrieve include directories from target property of the static library, but indirectly included headers are still missing.
Have the executable and the dynamic library both link to the static library. That can't be expected to work, and it doesn't.
Turn the static library into a dynamic library. That would work, but I would like to avoid touching build scripts for the static library and the executable as much as possible.
Make the dynamic library static and links it with executable. This is impossible because Python extensions must be dynamically loaded.
Upvotes: 4
Views: 1575
Reputation: 1733
The $<TARGET_PROPERTY>
generator expression does the trick.
target_include_directories(
MyDynamicLib
PRIVATE
$<TARGET_PROPERTY:MyStaticLib,INCLUDE_DIRECTORIES>)
get_target_property
is evaluated in the configuration phase and return what is written in CMakeLists.txt. The $<TARGET_PROPERTY>
generator expression is evaluated in the generation phase and returns the actual value.
Upvotes: 1
Reputation: 54589
You will need a separate target that provides only the headers.
Both the static and the dynamic library will then depend on that header-only target, but not on each other.
This is typically achieved by defining an interface library target for the headers:
target_include_directories(MyHeaders INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
add_library(MyStaticLib STATIC a.cpp)
target_link_libraries(MyStaticLib PUBLIC MyHeaders)
add_library(MyDynamicLib SHARED b.cpp)
target_link_libraries(MySDynamicLib PUBLIC MyHeaders)
Note how for this to work you will need full control over the definition of all the library targets. If the static library is provided by a third-party build that is not under your control this will not work. In that case you should get into contact with the maintainer of the third-party library to figure out how they can support your use case.
Upvotes: 0
Reputation: 85276
Usually find_package(Foo)
defines packages' include directories in a variable FOO_INCLUDE_DIR
.
You can simply add that to your project's include path with
include_directories("${FOO_INCLUDE_DIR}")
Upvotes: 1