John
John

Reputation: 7339

CMake - How to export a library with private dependencies

I am trying to export a library from a CMake project. Internally, I've broken this library up into multiple sub-targets. I would now like to export just the full public library, without needing my private library binaries. The following doesn't work.

cmake_minimum_required(VERSION 3.2)

project(export-mwe)

add_library(priv priv.cpp)

add_library(exp-lib exp-lib.cpp)
target_link_libraries(exp-lib PRIVATE priv)

install(TARGETS exp-lib EXPORT export-mwe DESTINATION lib)

install(EXPORT export-mwe DESTINATION .)

When I try generating this project I get an error.

CMake Error: install(EXPORT "export-mwe" ...) includes target "exp-lib" which requires target "priv" that is not in the export set.

How can I export only exp-lib in this example, without having to export priv with it?

Upvotes: 1

Views: 2835

Answers (1)

Tsyvarev
Tsyvarev

Reputation: 66061

The library exp-lib is static (this is default on Linux), so it is NOT "physically" linked with priv: creation of a static library doesn't calls a linker at all.

When applied to a static library, CMake interprets target_link_libraries in a specific manner: the actual linkage with the priv library file is moved to the every target, which links with exp-lib.

That is, further

target_link_libraries(shared-lib exp-lib)

will be translated to the linker's command line

ld -o shared-lib.so <...> exp-lib.a deps.a

When a static library is exported, CMake exposes the same behavior: Any target, which links with IMPORTED target exp-lib via target_link_libraries, automatically gets linkage with deps.a. To implement such behavior, CMake needs to know where deps.a is installed.

While installation location of deps.a can be obtained from install(TARGETS deps) command, CMake still requires that the installation be exported: install(TARGETS deps EXPORT export-mwe).

Upvotes: 3

Related Questions