dll interface differently for compilation and usage. The INTERFACE keyword is a bit more curious: For example, with definitions, you can use it to define your. It’s good practice to favor PRIVATE to avoid “leaking” dependencies so they won’t stack up in the dependent libraries and bring down your compile times. your *.cpp and *.c files and internal headers. Typically, you’d use the PRIVATE keyword for includes and definitions that are exclusively used in you implementation, i.e. Now here’s a program that wants to use that:Ĭool_tool can just #include "cool_feature.hpp" without knowing exactly where it is located in the source tree or without having to worry about setting up the boost includes for itself! Pretty neat! PRIVATE, PUBLIC and INTERFACE Here’s a small example of a library that uses Boost in its headers and therefore wishes to have its clients setup those directories as well: There’s also the PRIVATE keyword that can be used to avoid adding the settings to all dependent targets. To do this, you need to use target_include_directories and target_compile_definitions with the PUBLIC or INTERFACE keywords on your targets. The gist is this: Using target_link_libraries to link A to an internal target B will not only add the linker flags required to link to B, but also the definitions, include paths and other settings – even transitively – if they are configured that way. Of course, it’s all in the CMake documentation, but mentioned implicitly at best. The ones that initially put me on the right track were The Ultimate Guide to Modern CMake and CMake – Introduction and best practices. But information on this is pretty scarce on the web. It turns out there’s actually a pretty elegant solution built into CMake, which centers around target_link_libraries. All these homegrown solutions work, but they are rather clumsy and don’t work well when integrating libraries not written in that same convention.
![cmake print cmake print](https://pic3.zhimg.com/v2-3597ae245c54db93eea3ed784764e686_r.jpg)
Other projects defined “interface” files for each library that could be included by other targets. I’ve seen projects tackle this problem in various ways – for example by defining specifically named variables for each library and using that for their clients. Of course, this is all heavily order-dependent – so the build system breaks as soon as you make an ever so subtle change to the directory layout. I’d use the include_directories, add_definitions and add_compile_options command in the top-level or in mid-level CMakeLists.txt files just to get the whole thing to compile.
Cmake print how to#
One thing that has eluded me in the past was how to efficiently manage dependencies of different components within one CMake project.