# Idiomatic way to deal with huge number of include directories

**URL:** https://discourse.cmake.org/t/idiomatic-way-to-deal-with-huge-number-of-include-directories/3947
**Category:** Code
**Tags:** os:linux, comp:gcc, comp:clang, gen:makefiles, gen:ninja
**Created:** [August 17, 2021, 5:36pm UTC](https://discourse.cmake.org/t/idiomatic-way-to-deal-with-huge-number-of-include-directories/3947 "2021-08-17T17:36:00Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [August 17, 2021, 5:36pm UTC](https://discourse.cmake.org/t/idiomatic-way-to-deal-with-huge-number-of-include-directories/3947/1 "2021-08-17T17:36:00Z")

</div>

Hi,

I’m writing a CMake build system for a very large, very elderly code base. It contains tens of thousands of source code files, most of which live in a complex nested directory structure. Each target is likely to have tens (if not hundreds) of subdirectories that contain source code.

My fundamental question is, what’s the idiomatic CMake way to deal with this?

What I’m attempting at the moment is, for each target, adding the subdirs as PUBLIC target\_include\_directories. This has the following problems:

- Sometimes, libraries wish to consume only headers from a library. The cleanest way to manage “inheritance” of include directories seems to be to add a link dependency between the two libraries. Adding a link just to get some includes seems inelegant… Is there a better way to handle inheritance of includes?
- The list of header files is so large that when developers write a bug, it’s normally impossible to see the first error without piping the error to file and doing a lot of scrolling. Is there a way to reduce the size of the messages I get? It would be great if I could somehow collapse the list of include directories.

I’m building on Linux with Make, Ninja, Clang, and Gcc.

Thanks!

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [August 17, 2021, 7:10pm UTC](https://discourse.cmake.org/t/idiomatic-way-to-deal-with-huge-number-of-include-directories/3947/2 "2021-08-17T19:10:06Z")

</div>

> [@tom](#):
>
> Adding a link just to get some includes seems inelegant… Is there a better way to handle inheritance of includes?

You can do something like this:

```cmake
add_library(foo-headers INTERFACE)
target_include_directories(foo-headers INTERFACE …)
add_library(foo SHARED …)
target_link_libraries(foo PUBLIC foo-headers)

```

Eventually, we’ll have `$<COMPILE_ONLY>` to strip off the linking (there’s an issue for it, but I don’t have it handy).

> [@tom](#):
>
> It would be great if I could somehow collapse the list of include directories.

I don’t know of a way to do this. Maybe you could force response files, but I think that is Ninja-only.

---

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [August 17, 2021, 9:10pm UTC](https://discourse.cmake.org/t/idiomatic-way-to-deal-with-huge-number-of-include-directories/3947/3 "2021-08-17T21:10:54Z")

</div>

Thanks Ben, very useful!

I did mess around with INTERFACE libraries for a bit, but got in a tangle with the export rules. I’ll give it another go.

At the moment the only idea I have to fix the second problem is to programmatically re-factor all the `#include bar.h` → `#include path/from/top/level/target/dir/bar.h`. I’ll have to think about that one a bit more though - I don’t actually think it would be that hard to script…

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [August 17, 2021, 9:19pm UTC](https://discourse.cmake.org/t/idiomatic-way-to-deal-with-huge-number-of-include-directories/3947/4 "2021-08-17T21:19:18Z")

</div>

> [@tom](#):
>
> At the moment the only idea I have to fix the second problem is to programmatically re-factor all the `#include bar.h` → `#include path/from/top/level/target/dir/bar.h`

I think that is the better way to handle it because then you don’t have to worry about conflicting header names and the reader of the code can have a better idea of what `frobnicator.h` is for if it is referred to as `package/processing/frobnicator.h`. Other (minor) benefits:

- fewer paths the compiler pokes around in for headers that are found after your targets
- shorter command lines
