I am working on a project that is based on the merged header placement (headers, sources and tests are in the same directory). I would like to link another directory to this, however using the target_include_directory will include the private header files as well. I am wondering how can i exclude certain headers file from being accessible by libraries that are linked to my current target
I have tried to read through the documents of cmake and seems that i am not able to achieve this quite easily. I am quite new to cmake so sorry if this is a trivial question. I have also searched for example of this structure in github and could not find any example project.
The reason I did not choose the separate structure is that the current project i am working on is very modularized. There are many nested subdirectories 5-6 level and having the project structure repeated 3 time in src test and include was very annoying to navigate. That is why we have switched to the merged header placement structure to have only a single nested directory.
CodePudding user response:
You can switch to a split header layout and put public headers under include/
and private headers under src/
. Then target_include_directories()
include/
for your target.
As far as I'm aware, the merged header placement problem can't be solved by CMake for the build tree (what you use at development time). It's a "limitation" due to how include directory flags work on all major compilers: If you put a directory in the include path, then everything under it can be path-resolved through it (thought that's not to say everything that can be path-resolved is valid source code just that it can be path-resolved). But it can be solved for the install tree for private headers that don't need to be installed: Just don't install those ones.
Unless there's something I'm missing about how CMake and compiler include paths work, if you really want to make your private headers non-reachable by dependent targets at build time, you'll need to just bit the bullet and switch to a layout where the private headers are under a separate tree than the public ones.
The Pitchfork Layout Spec even alludes to this in its section on Separate Header Placement:
Consumers of a library using separated header layout should be given the path to the § 2.2 include/ directory as the sole include search directory for the library’s public interface. This prevents users from being able to
#include
paths which exist only in thesrc/
directory.