# Use of -isystem

**URL:** <https://discourse.cmake.org/t/use-of-isystem/1574>\
**Category:** Development\
**Created:** [July 16, 2020, 4:18pm UTC](https://discourse.cmake.org/t/use-of-isystem/1574 "2020-07-16T16:18:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![yann](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/y/bc79bd/32.png) [@yann](https://discourse.cmake.org/u/yann)\
**Post date:** [July 16, 2020, 4:18pm UTC](https://discourse.cmake.org/t/use-of-isystem/1574/1 "2020-07-16T16:18:19Z")

</div>

We had a problem when cross-compiling software against sentry, which  
is linked to sentry-targets.cmake causing usage of  
$sysroot/usr/include, which causes -isystem to appear early in the  
commandline. “gcc -v” shows that when this happens the  
$sysroot/usr/include that occured near the end of the search path  
(after STL’s $sysroot/usr/include/c++/7.3.0) is the one that gets  
dropped. This in turn causes problems for STL headers, as  
`#include_next <stdlib.h>` now fails to find the file, as can be also  
seen in [https://gcc.gnu.org/bugzilla/show\_bug.cgi?id=70129](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129)

Digging, I found this is caused by Modules/Compiler/GNU.cmake, with a  
declaration which I suppose is used in  
cmLocalGenerator::GetIncludeFlags(), where a logic says “if  
IsSystemIncludeDirectory() use -isystem instead of -I”.

The reason exposed in [https://cmake.org/Bug/view.php?id=3453](https://cmake.org/Bug/view.php?id=3453) is “The  
-isystem instead of -I is very useful when you compile your own code  
with -pedantic warnings and don’t want to see teh warnings noise”.

In bug 3462 (sorry I’m forbidden to use more than 1 link) we learn it was felt not to  
be a problem because gcc documentation in 2006 said “If a standard  
system include directory, or a directory specified with -isystem, is  
also specified with -I, the -I option will be ignored.”

Now in 2020 it says “If you specify other options on the command line,  
such as ‘-I’, that affect where the preprocessor searches for header  
files, the directory list printed by the ‘-v’ option reflects the  
actual search path used by the preprocessor.” which does not seem to  
give any such warranty.

In fact, it seems that in the case of double specification of a system  
include, the first one is kept, so it seems reasonable that we never  
want to add `-isystem` on a system header, so as to avoid unwanted  
side-effects.

Removing this statement causes cmake to use -I instead of -isystem, in which  
case it is the system include which is kept, and the build can proceed.  
This would be the following patch.

Does it seem reasonable ?

```auto
--- cmake-3.10.3.orig/Modules/Compiler/GNU.cmake
+++ cmake-3.10.3/Modules/Compiler/GNU.cmake
@@ -44,9 +44,6 @@ macro(__compiler_gnu lang)
   string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG")
   set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
   set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
- if(NOT APPLE OR NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4) # work around #4462
- set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
- endif()
 
   set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
   set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)

```

---

<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:** [July 16, 2020, 4:28pm UTC](https://discourse.cmake.org/t/use-of-isystem/1574/2 "2020-07-16T16:28:38Z")

</div>

Removing `-isystem` in general is not a good solution. That’s supposed to apply to user-provided include directories e.g. for external dependencies.

CMake tries pretty hard not to pass the compiler’s own implicit include directories on the command line at all. We even have [CMake Issue 19227](https://gitlab.kitware.com/cmake/cmake/-/issues/19227) where people want to turn that filtering off.

If CMake is generating an explicit `-isystem $sysroot/usr/include` when that is one of the compiler’s builtin include directories then something is going wrong with the detection and filtering. In a build tree where this happens, what is the output of the following?

```auto
$ grep IMPLICIT_INCLUDE_DIRECTORIES CMakeFiles/*/CMake*Compiler.cmake

```

---

<div class="post-metadata">

**Author:** ![yann](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/y/bc79bd/32.png) [@yann](https://discourse.cmake.org/u/yann)\
**Post date:** [July 16, 2020, 4:48pm UTC](https://discourse.cmake.org/t/use-of-isystem/1574/3 "2020-07-16T16:48:26Z")

</div>

Jus nothing:

```auto
$ ls CMakeFiles/*/CMake*Compiler.cmake
CMakeFiles/3.10.3/CMakeCCompiler.cmake CMakeFiles/3.10.3/CMakeCXXCompiler.cmake
$ grep IMPLICIT_INCLUDE_DIRECTORIES CMakeFiles/*/CMake*Compiler.cmake
$

```

---

<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:** [July 16, 2020, 4:54pm UTC](https://discourse.cmake.org/t/use-of-isystem/1574/4 "2020-07-16T16:54:12Z")

</div>

> `CMakeFiles/3.10.3/CMakeCCompiler.cmake`

CMake 3.10 pre-dates the filtering I mentioned. Please try a more recent version.
