# IDEs and header files

**URL:** <https://discourse.cmake.org/t/ides-and-header-files/2665>\
**Category:** Code\
**Tags:** gen:vs, gen:xcode\
**Created:** [February 1, 2021, 4:47am UTC](https://discourse.cmake.org/t/ides-and-header-files/2665 "2021-02-01T04:47:17Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/andrew/32/2478_2.png) [@Andrew](https://discourse.cmake.org/u/Andrew)\
**Post date:** [February 1, 2021, 4:47am UTC](https://discourse.cmake.org/t/ides-and-header-files/2665/1 "2021-02-01T04:47:17Z")

</div>

Sample project:  
add\_library( a )  
target\_sources( a PRIVATE a.c PUBLIC a.h )

```
add_library( b )
target_sources( b PRIVATE b.c PUBLIC b.h )
target_link_libraries( b PUBLIC a )

```

When I bring this up in my IDE, target _a_ has headers ‘a.h’, but target _b_ has headers ‘a.h’, ‘b.h’. It seems that all the public sources in _a_ are being imported into the visible space of _b_.

On the one hand, this is useful if I want to be able to easily view all the headers. But it also means that (in a large project) the headers that belong to _b_ directly get lost among all the headers of all _b_’s dependencies.

Am I doing something wrong here?

Note that all of _a_’s headers are already available in my project as source files from _a_. But CMake makes them appear a second time as source files of _b_.

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [February 1, 2021, 8:40am UTC](https://discourse.cmake.org/t/ides-and-header-files/2665/2 "2021-02-01T08:40:40Z")

</div>

`target_sources` adds source files to a target, just like `target_compile_options` adds compilation options to it etc.

With all these commands, `PRIVATE` means “this applies only to the target itself” and `PUBLIC` means “this applies both to the target itself and to anyone who links to it.”(1)

In other words, marking a source files as `PUBLIC` means “add this source file to this target and also to all targets which link to it.” In particular, it does _not_ mean “this header is intended for public consumption.”

So, it’s very rarely useful to mark a source file as `PUBLIC`, and I can’t think of a situation where it would make sense to do so for a _header_. In particular, note that it does _not_ give the consuming target any include-path access to the file.

As a rule of thumb, don’t mark source files as anything other than `PRIVATE`. If you do encounter a situation where you need to deviate from that, you will probably know it by just how extraordinary it is.

If you wanted to signal "`a.h` is a public API header of the library," you’d actually do that by setting the library’s `target_include_directories(a PUBLIC ...)` so that whoever links against `a` gets the correct paths to be able to do `#include "a.h"`.

* * *

(1) And for completeness, `INTERFACE` means "this applies only to those who link against the target. So `PUBLIC` is the union of `PRIVATE` and `INTERFACE`.

---

<div class="post-metadata">

**Author:** ![Russell\_Schultz](https://discourse.cmake.org/user_avatar/discourse.cmake.org/russell_schultz/32/282_2.png) [@Russell\_Schultz](https://discourse.cmake.org/u/Russell_Schultz)\
**Post date:** [February 3, 2021, 6:41pm UTC](https://discourse.cmake.org/t/ides-and-header-files/2665/3 "2021-02-03T18:41:04Z")

</div>

As an example of a PUBLIC source use is the source for many RTOSes. You’d prefer it to be in the library, but it needs to be compiled with the same headers and options as the application, since many of the lightweight rtoses configure the available resources and options with #defines in a config,h file to be included by the RTOS and application.
