# Transitive include directories

**URL:** https://discourse.cmake.org/t/transitive-include-directories/4248
**Category:** Code
**Created:** [October 11, 2021, 7:41pm UTC](https://discourse.cmake.org/t/transitive-include-directories/4248 "2021-10-11T19:41:33Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![JoeM](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/0ea827/32.png) [@JoeM](https://discourse.cmake.org/u/JoeM)
#### Post date: [October 11, 2021, 7:41pm UTC](https://discourse.cmake.org/t/transitive-include-directories/4248/1 "2021-10-11T19:41:34Z")

</div>

I’ve lost something in translation when reading this bit of documentation on **Transitive Usage Requirements** in cmake-buildsystem(7):

> Usage requirements are propagated by reading the `INTERFACE_` variants of target properties from dependencies and appending the values to the non-`INTERFACE_` variants of the operand. For example, the[`INTERFACE_INCLUDE_DIRECTORIES`](https://cmake.org/cmake/help/v3.20/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html#prop_tgt:INTERFACE_INCLUDE_DIRECTORIES) of dependencies is read and appended to the [`INCLUDE_DIRECTORIES`](https://cmake.org/cmake/help/v3.20/prop_tgt/INCLUDE_DIRECTORIES.html#prop_tgt:INCLUDE_DIRECTORIES) of the operand.

From this, I would expect that if I had 2 targets, libA and libB, and libA specified a PUBLIC or INTERFACE include dir using `target_include_directory(libA PUBLIC includeA)`, if I were to specify

```auto
add_library(libB b.c)
target_link_libraries(libB INTERFACE libA)

```

that the source file `b.c` would get compiled with `-I/path/to/includeA`.

I don’t observe this and I don’t understand why. Please explain?

Thanks!

PS - as an aside, I’m trying to use INTERFACE for just the headers, as I would want libB to dlsym lookup the symbols from libA (or any other libA equivalent interface library).

---

<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 12, 2021, 12:16am UTC](https://discourse.cmake.org/t/transitive-include-directories/4248/2 "2021-10-12T00:16:56Z")

</div>

> [@JoeM](#):
>
> ```auto
> add_library(libB b.c)
> target_link_libraries(libB INTERFACE libA)
> 
> ```
> 
> that the source file `b.c` would get compiled with `-I/path/to/includeA`.

You would need to use `PUBLIC libA`. `INTERFACE libA` only applies to consumers of `libB`, not parts of `libB` itself.

---

<div class="post-metadata">

### Author: ![JoeM](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/0ea827/32.png) [@JoeM](https://discourse.cmake.org/u/JoeM)
#### Post date: [October 12, 2021, 12:25am UTC](https://discourse.cmake.org/t/transitive-include-directories/4248/3 "2021-10-12T00:25:29Z")

</div>

I don’t know if it’s conventional, but I found a solution that fit my needs (and your answer makes perfect sense now).

I created a separate INTERFACE library for libA that would communicate the include directory but not attempt to link against libA.

```auto
add_library(libA SHARED a.c)
add_library(libAInterface INTERFACE)
target_include_directories(libAInterface INTERFACE includeA)
#### elsewhere
target_link_libraries(libB PRIVATE libAInterface)

```

I now get it that `target_link_libraries(foo INTERFACE bar)` commutes the INTERFACE properties of bar ot the INTERFACE properties of foo. It doesn’t do anything to foo’s compilation.

---

<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 12, 2021, 1:05am UTC](https://discourse.cmake.org/t/transitive-include-directories/4248/4 "2021-10-12T01:05:48Z")

</div>

I had a post somewhere about a `$<COMPILE_ONLY:>` genex that would do this, but yes, this is the best solution that I know of available today.
