'install EXPORT problem for library with dependencies

I try to build two libraries (say A and B) from one project. I use add_subdirectory cmake command in root cmake file. B depends on A.

When I try to add

INSTALL (TARGETS B EXPORT B
    PUBLIC_HEADER DESTINATION "include/B"
    LIBRARY DESTINATION "lib"
    ARCHIVE DESTINATION "lib")

INSTALL (EXPORT B DESTINATION "./")

CMake warns me about error in line with INSTALL (EXPORT .... It prints:

CMake Error: INSTALL (EXPORT "B" ...) includes target "B" which requires target "A" that is not in the export set.



Solution 1:[1]

Aside from fixing

"A" that is not in the export set

part of the error message, one could consider to fix the part

target "B" which requires target "A"

by using PRIVATE linkage of B with A:

target_link_libraries(B PRIVATE A)

Such linkage implies that A is needed only for building the library B, but is not needed for anyone who links with B.

It depends from the library B whether such linkage is sufficient. But if it is, then this is a preferable way to overcome the error: If users of B doesn't need to link with A, then there is no reason to EXPORT A.


There are some easy signs when PRIVATE linkage is NOT an option:

  1. Some public header of library B includes a header of library A. In that case, if a user #include-s that header of B, then the header of A will be included too. And to find that header a compiler should be aware of include directories for A.
  2. B is a STATIC library, and A is either STATIC or SHARED. In that case, the binary file for B won't "embed" the binary file for A. So, when link with B, one should explicitly link with A too.

However, if both A and B are SHARED libraries, then PRIVATE linkage could still be an option:

While binary file for shared B doesn't "embed" the binary file for shared A, the binary file for B contains reference to the binary file for A. So when a linker will find B binary in the command line, it will link with A binary too. If B is installed, then A should be installed too (otherwise the linker won't find A). But for being able to export B, the A needn't to be exported.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tsyvarev