

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. 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 LINK LIBRARY HOW TO#
One thing that has eluded me in the past was how to efficiently manage dependencies of different components within one CMake project.
