1

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.

starball
  • 20,030
  • 7
  • 43
  • 238
hamid
  • 13
  • 2
  • If the problem is navigation being annoying, then that's solvable to a degree by just using IDE file search functions- is it not? What IDE are you using? – starball Jan 29 '23 at 22:57
  • The three top compiler used by our developers in order are visual studio, visual studio code and clion. The main problem we had was with visual studio compiler, we debated to create a filter to ease the workflow for developers using that ide, but we ran into issues maintaining the filter. Do you know of a trick that make this work for that ide? – hamid Jan 29 '23 at 23:05
  • I'm not familiar with Visual Studio and filters- just enough to think (subjective opinion) that they're weird. I prefer to / am accustomed to viewing my files in the exact same layout as the filesystem layout (probably because my first and primary IDE is VS Code). You might be able to find another Q&A here with tips on that. – starball Jan 29 '23 at 23:08
  • Here are some Q&A I found by searching `cmake visual studio filter`: [how to create visual studio filters](/q/33808087), [support of Visual Studio filters](/q/44020407), [How to set Visual Studio Filters for nested sub directory using cmake](/q/31422680). – starball Jan 29 '23 at 23:12

1 Answers1

1

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 (though 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 bite 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 the src/ directory.

starball
  • 20,030
  • 7
  • 43
  • 238