nybon
nybon

Reputation: 9611

benefits for setting dependency interface in cmake target_link_libraries

I use CMake in my C++ project for a while, and my project is an application (not a library) consisting of multiple sub modules, where each module depends on other internal modules in the same project, and depends on multiple third party libraries as well, and each of them is built using CMake.

Currently, we use PUBLIC in target_link_libraries when specifying these dependencies. I read some articles/documentations [1][2][3] about this topic, and know the general difference between PUBLIC/INTERFACE/PRIVATE, and know that it is recommended to specify different visibility as detailed as possible. But since I am building an application but not a library, I am not worried that internal APIs are "leaked" accidentally, is there any other benefit that we should choose to use non PUBLIC visibility like PRIVATE? For example, besides affecting linking's speed, does it affect compilation speed? If linking doesn't take too much time, does it still make sense to optimize compilation speed by exploring this option? Does it affect the size of the binary in the end? Or is there any other benefit for controlling this behavior? Thanks.

[1] https://cmake.org/cmake/help/latest/command/target_link_libraries.html [2] https://leimao.github.io/blog/CMake-Public-Private-Interface/ [3] https://cmake.org/pipermail/cmake/2016-May/063400.html

Upvotes: 1

Views: 910

Answers (1)

Alex Reinking
Alex Reinking

Reputation: 19956

You should absolutely always use a visibility specifier with target_link_libraries.

Whether or not target_link_libraries(target lib) is considered to be PRIVATE or PUBLIC by default depends on whether or not you use visibility specifiers elsewhere in the CMakeLists.txt. This risk of changing the visibility of a library simply by adding a different library should really be all the justification anyone needs to just use the maintainer-recommended best practices.

Having too many public dependencies will eventually lead to pointlessly long link lines, which can indeed bloat link times as the linker will need to determine that a symbol is not relevant. Worse, it's possible that one library that didn't need to be public will win a symbol conflict incorrectly and cause trouble. There's simply no reason to intentionally set up an inaccurate dependency model.

Finally, for executables, which visibility specifier to use is usually simple to choose: 99% of the time, it will be PRIVATE. However, this is not always the case. If you are building a plugin system, say, you might have ENABLE_EXPORTS set on your executable. In this case, libraries may in fact link to the executable target and visibility becomes relevant again.

Upvotes: 2

Related Questions