# target\_sources() and header visibility

**URL:** <https://discourse.cmake.org/t/target-sources-and-header-visibility/2096>\
**Category:** Code\
**Created:** [October 30, 2020, 10:38am UTC](https://discourse.cmake.org/t/target-sources-and-header-visibility/2096 "2020-10-30T10:38:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![DreamCaptain](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dreamcaptain/32/918_2.png) [@DreamCaptain](https://discourse.cmake.org/u/DreamCaptain)\
**Post date:** [October 30, 2020, 10:38am UTC](https://discourse.cmake.org/t/target-sources-and-header-visibility/2096/1 "2020-10-30T10:38:33Z")

</div>

Hi,  
I’m trying modern cmake approach, but seems like my understanding of how target\_sources() command works is wrong.  
Consider following hierarchy:

```
foo_project/
├── CMakeLists.txt
├── headers
│ └── foo.h
├── interfaces
│ └── foo_interface.h
└── sources
    ├── foo.cpp

```

headers directory contains target’s private headers  
interfaces directory contains target’s public headers (api)  
sources contains .cpp files.

```
// CMakeLists.txt:

cmake_minimum_required(VERSION 3.15.0)

project(FooProject)

add_library(foo_lib STATIC)

    target_sources(foo_lib
        PRIVATE
            sources/foo.cpp
            headers/foo.h
        PUBLIC
            interfaces/foo_interface.h
    )

```

The problem is that in foo.h the only way to include foo\_interface.h is by qualifying its directory name:

```
// foo.cpp
#include "../headers/foo.h"

// foo.h
#include "../interfaces/foo_interface.h"

```

The way i think it should look:

```
// foo.cpp
#include "foo.h"

// foo.h
#include "foo_interface.h"

```

How can i achieve this?

---

<div class="post-metadata">

**Author:** ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)\
**Post date:** [October 30, 2020, 10:56am UTC](https://discourse.cmake.org/t/target-sources-and-header-visibility/2096/2 "2020-10-30T10:56:33Z")

</div>

I think you probably want something like this:  
cmake\_minimum\_required(VERSION 3.15.0)

```
project(FooProject)

add_library(foo_lib STATIC)

target_sources(foo_lib
    PRIVATE
    sources/foo.cpp
    headers/foo.h
    interfaces/foo_interface.h
)

target_include_directories(foo_lib PUBLIC interfaces PRIVATE headers)
```

---

<div class="post-metadata">

**Author:** ![DreamCaptain](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dreamcaptain/32/918_2.png) [@DreamCaptain](https://discourse.cmake.org/u/DreamCaptain)\
**Post date:** [October 30, 2020, 11:24am UTC](https://discourse.cmake.org/t/target-sources-and-header-visibility/2096/3 "2020-10-30T11:24:33Z")

</div>

It works now, thank you.

Can you clarify, what’s the deal with target\_sources (… PUBLIC). My initial thought was that it allows to emulate target\_include\_directories(…PUBLIC) behavior.

so, i thought that

```
target_sources(foo_lib PUBLIC interface/foo_interface.h) 

```

and

```
target_include_directories(foo_lib PUBLIC interface) 

```

are equal.

---

<div class="post-metadata">

**Author:** ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)\
**Post date:** [October 30, 2020, 11:52am UTC](https://discourse.cmake.org/t/target-sources-and-header-visibility/2096/4 "2020-10-30T11:52:30Z")

</div>

I’m not deep enough to be sure but my understanding is that `target_sources (… PUBLIC...)` will cause inclusion of those source files in the source list of all targets that link to this target. In any case probably NOT what one wants. Someone smarter would have to answer that if you want details.

---

<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:** [October 30, 2020, 12:03pm UTC](https://discourse.cmake.org/t/target-sources-and-header-visibility/2096/5 "2020-10-30T12:03:16Z")

</div>

Yes, `target_sources` just adds source file paths to the list of files for consuming targets. Just like adding `arbitrary/path/foo.h` does not imply `-Iarbitrary/path`, if you want `-I` flags passed, you need to use `target_include_directories`.

There’s no documentation that indicates that your two examples are implied at all (if there is, please point us to it so it can be updated).

---

<div class="post-metadata">

**Author:** ![DreamCaptain](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dreamcaptain/32/918_2.png) [@DreamCaptain](https://discourse.cmake.org/u/DreamCaptain)\
**Post date:** [October 30, 2020, 12:46pm UTC](https://discourse.cmake.org/t/target-sources-and-header-visibility/2096/6 "2020-10-30T12:46:56Z")

</div>

No, it’s just me not being familiar enough with CMake.

Thanks all.
