# target\_include\_directories() vs headers in target\_sources()

**URL:** https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625
**Category:** Code
**Created:** [January 25, 2021, 8:17pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625 "2021-01-25T20:17:44Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![eriols](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eriols/32/945_2.png) [@eriols](https://discourse.cmake.org/u/eriols)
#### Post date: [January 25, 2021, 8:17pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/1 "2021-01-25T20:17:44Z")

</div>

Looking for advice on how to think about when to add directories with headers in them as `target_include_directories()` vs adding every header file by hand using `target_sources()`.

One thing I’ve noted is that I struggle to tell the linker which one to use if different headers with the same name (say utils.h) exists on different levels in a code base. Is `target_sources()` the most practical solution in that case?  
Would appreciate some rules of thumb type advice on this, thanks.

---

<div class="post-metadata">

### Author: ![McMartin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mcmartin/32/150_2.png) [@McMartin](https://discourse.cmake.org/u/McMartin)
#### Post date: [January 25, 2021, 8:36pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/2 "2021-01-25T20:36:50Z")

</div>

`target_include_directories` is relevant to the preprocessor (which is usually part of the compiler), since it allows to resolve `#include` preprocessor directives.

Adding headers with `target_sources` is relevant to IDEs (Visual Studio, Xcode, etc.) so they can display these header files, even if they are not directly compiled.

So these 2 functions are doing quite different things, and I can’t think of any situation where you would have to choose between them.

I hope this helps.

---

<div class="post-metadata">

### Author: ![Oodini](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/db5fbb/32.png) [@Oodini](https://discourse.cmake.org/u/Oodini)
#### Post date: [November 23, 2023, 10:43am UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/3 "2023-11-23T10:43:37Z")

</div>

I was asking myself the same question.

The [documentation](https://cmake.org/cmake/help/latest/command/target_sources.html) of `target_sources` says :

_Specifies sources to use **when building** a target and/or its dependents._

There is no mention of display in the documentation of this function.

Are you not confused with the command `source_group` ?

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [November 23, 2023, 9:33pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/4 "2023-11-23T21:33:45Z")

</div>

The situation has changed with the advent of _file sets_. Now you can define a HEADERS file set with `target_sources()`, and it _does_ affect the header search path in a way that you probably don’t need `target_include_directories()` any more. See the [target\_sources](https://cmake.org/cmake/help/latest/command/target_sources.html#file-sets) documentation for details.

---

<div class="post-metadata">

### Author: ![Oodini](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/db5fbb/32.png) [@Oodini](https://discourse.cmake.org/u/Oodini)
#### Post date: [November 23, 2023, 9:44pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/5 "2023-11-23T21:44:59Z")

</div>

Yes, I discovered file sets today wy reading one of your post on your web site (so I bought your book some hours ago…).  
But I don’t really understand how to use them.

Especially `FILE_SET <set>` : what is this set name used for ?

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [November 23, 2023, 10:11pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/6 "2023-11-23T22:11:56Z")

</div>

In the Professional CMake book, there’s a section on file sets in “Chapter 35: Installing”. The next edition will split things out to earlier sections for more logical flow and to make file set details easier to find.

> Especially `FILE_SET <set>` : what is this set name used for ?

The set name is primarily useful with `install(TARGETS ... FILE_SET ...)`. This is a very convenient way to install headers that are in `PUBLIC` and `INTERFACE` header sets. You also need the set name when you are adding files to a file set progressively, such as when you have them spread across multiple directories and you want to add each directory’s files in its own `target_sources()` call.

---

<div class="post-metadata">

### Author: ![mnarowski](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mnarowski/32/4969_2.png) [@mnarowski](https://discourse.cmake.org/u/mnarowski)
#### Post date: [September 27, 2024, 3:57pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/7 "2024-09-27T15:57:25Z")

</div>

In my case HEADERS file set could not replace `target_include_directories()`. My project structure is highly atomized, with lots of deeply nested subdirectories and private headers kept distinct from sources. `target_include_directories()` allows me to use `#include` without any paths preceding the header’s filename. With HEADERS file set using BASE\_DIR the best I could do was to - as the argument says - set the base directory from which my paths had to be built in `#include`s. Adding to the BASE\_DIR list any subdirectory of already added catalog leads to an error, and setting the FILES list doesn’t help the preprocessor.  
I feel like file sets are currently focused on less complex project structure and helping the `install()` process.  
If there is any way to satisfy such needs with `target_sources()` I would be glad to acknowledge it.

---

<div class="post-metadata">

### Author: ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)
#### Post date: [September 27, 2024, 4:08pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/8 "2024-09-27T16:08:43Z")

</div>

You’re not limited to just one header set named `HEADERS` - you can create multiple header sets that have overlapping `BASE_DIRS`.

---

<div class="post-metadata">

### Author: ![mnarowski](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mnarowski/32/4969_2.png) [@mnarowski](https://discourse.cmake.org/u/mnarowski)
#### Post date: [September 27, 2024, 4:54pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/9 "2024-09-27T16:54:07Z")

</div>

Right. Somehow it didn’t work for me previously.

Now, I’m confused if there are any advantages of adding headers to file set’s FILES argument in my case, which is I’m not sharing the headers and I don’t need them to be available for installation. The software I develop isn’t destined to be included or linked anywhere.

---

<div class="post-metadata">

### Author: ![bmcdonnell-fb](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bmcdonnell-fb/32/5561_2.png) [@bmcdonnell-fb](https://discourse.cmake.org/u/bmcdonnell-fb)
#### Post date: [June 24, 2025, 3:46pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/10 "2025-06-24T15:46:33Z")

</div>

> [@kyle.edwards](#):
>
> you can create multiple header sets that have overlapping `BASE_DIRS`.

Multiple header sets, yes.

Overlapping `BASE_DIRS`, I think you are mistaken. CMake complained at me every time I tried.

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [June 24, 2025, 8:22pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/11 "2025-06-24T20:22:16Z")

</div>

> [@target\_include\_directories() vs headers in target\_sources()](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/10):
>
> Multiple header sets, yes. Overlapping BASE\_DIRS, I think you are mistaken. CMake complained at me every time I tried.

You can’t have nested/overlapping `BASE_DIRS` within a single header set. A given header set can have `BASE_DIRS` which overlap with the `BASE_DIRS` of other header sets.

---

<div class="post-metadata">

### Author: ![bmcdonnell-fb](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bmcdonnell-fb/32/5561_2.png) [@bmcdonnell-fb](https://discourse.cmake.org/u/bmcdonnell-fb)
#### Post date: [June 24, 2025, 9:09pm UTC](https://discourse.cmake.org/t/target-include-directories-vs-headers-in-target-sources/2625/12 "2025-06-24T21:09:10Z")

</div>

I believe you are correct.

(I don’t think the part I quoted expresses that clearly, though on re-reading I can see it could be interpreted that way.)
