# Setting CMAKE\_C\_FLAGS breaks transitive include folders?

**URL:** <https://discourse.cmake.org/t/setting-cmake-c-flags-breaks-transitive-include-folders/2165>\
**Category:** Code\
**Tags:** os:linux\
**Created:** [November 12, 2020, 1:12pm UTC](https://discourse.cmake.org/t/setting-cmake-c-flags-breaks-transitive-include-folders/2165 "2020-11-12T13:12:07Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ndevenish](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ndevenish/32/943_2.png) [@ndevenish](https://discourse.cmake.org/u/ndevenish)\
**Post date:** [November 12, 2020, 1:12pm UTC](https://discourse.cmake.org/t/setting-cmake-c-flags-breaks-transitive-include-folders/2165/1 "2020-11-12T13:12:07Z")

</div>

I’m trying to _understand_ a failing behaviour where linking to an imported target isn’t properly using the include directory. The target has a proper `INTERFACE_INCLUDE_DIRECTORIES` set but it isn’t propagated to the compiler call if it’s set in the environment but CFLAGS are cleared before use. I can fix this by setting the flags in a more modern way (this is a very old inherited CMakeList) but it caught me by surprise and took a while to diagnose.

The files in the test:

- `test.c`, contents: `#include "subheader.h"`
- `libdir/subheader.h` that is empty
- `CMakeLists.txt`:

```auto
cmake_minimum_required(VERSION 3.8)
project(test_flags)
set(CMAKE_C_FLAGS "") # Causes breaking behaviour
add_library(imported::target INTERFACE IMPORTED)
set_target_properties(imported::target PROPERTIES
      INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/libdir")
add_library(testinc test.c)
target_link_libraries(testinc PUBLIC imported::target)

```

Now, `cmake <path> && make` works fine. However, if I set the linking path `export CFLAGS="-isystem <path>/libdir"` (or `-I` equivalent) first then I get:

```auto
... fatal error: 'subheader.h' file not found

```

e.g. the transitive include path is not included in the target’s compile command. I encountered this with a find\_package module that finds something in a conda environment, and conda explicitly sets up the CFLAGS to prefer it’s includes first over the system paths.

It looks like the list of includes to ignore is cached at some earlier point, and later when it comes to generate the compiler command it filters out the duplicates. However, this seems to have gotten out of sync.

Is this a bug, or have I missed something? Is this documented somewhere I should have seen?

---

<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:** [November 12, 2020, 6:15pm UTC](https://discourse.cmake.org/t/setting-cmake-c-flags-breaks-transitive-include-folders/2165/2 "2020-11-12T18:15:23Z")

</div>

This is likely related to CMake’s detection of built-in include paths to the compiler. Though I can’t say for sure what about it this is interfering with.

Cc: @brad.king

---

<div class="post-metadata">

**Author:** ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)\
**Post date:** [November 13, 2020, 1:05pm UTC](https://discourse.cmake.org/t/setting-cmake-c-flags-breaks-transitive-include-folders/2165/3 "2020-11-13T13:05:14Z")

</div>

The `project()` command initializes support for C and CXX languages and performs introspection of the corresponding compilers. One of the things we detect is the implicit include path that the compiler uses. By putting `-I` or `-isystem` flags in `CFLAGS`, those end up in the initial `CMAKE_C_FLAGS`, which CMake assumes will always be used. Those flags are included in the initial detection of the implicit include path, so the paths specified in those flags are assumed to always be used by the compiler. CMake avoids explicitly adding flags for such paths to avoid breaking the compiler’s implicit include order. If you then _remove_ flags that CMake assumed would always be present, then nothing tells the compiler to add those include directories anymore.
