How to specify system include directories as `-isystem` in CMake

Viewed 658

In CMake, I know I can do

target_include_directories(my_target SYSTEM PRIVATE ${SOME_THIRD_PARTY_LIBRARY_INCLUDES})

to avoid catching warnings coming from that library that could stop my compilation if I have those warnings defined as errors in my environment:

list(APPEND CXX_COMPILER_FLAGS_TO_USE "-Werror")

However, I can't figure out how to extend that behavior to system include directories. For example, in CentOS 7 using GCC 10, I can't enable -Wundef, since the system includes fail because of it:

list(APPEND CXX_COMPILER_FLAGS_TO_USE "-Wundef")

causes:

In file included from /opt/rh/devtoolset-10/root/usr/include/c++/10/x86_64-redhat-linux/bits/c++config.h:2791,
                 from /opt/rh/devtoolset-10/root/usr/include/c++/10/cmath:41,
                 ...
/opt/rh/devtoolset-10/root/usr/include/c++/10/pstl/pstl_config.h:47:5: error: "__clang__" is not defined, evaluates to 0 [-Werror=undef]
   47 | #if __clang__
      |     ^~~~~~~~~
compilation terminated due to -Wfatal-errors.
cc1plus: all warnings being treated as errors

/opt/rh/devtoolset-10/root/usr/include/ is never explicitly added by my config files, but automatically detected by CMake instead.

Is there a way to tell CMake to treat all the compiler-added include directories as SYSTEM? I could add those directories by hand, like:

target_include_directories(my_target SYSTEM PRIVATE /opt/rh/devtoolset-10/root/usr/include)

but I don't think that's an elegant and probably not even correct solution.

I was reading this reference and also this reference, but they don't seem to cover the same issue described here, though.

PS: Just in case is useful, I'm defining the compiler to be used with the command:

SET(CMAKE_CXX_COMPILER "/opt/rh/devtoolset-10/root/usr/bin/g++")
SET(CMAKE_C_COMPILER "/opt/rh/devtoolset-10/root/usr/bin/gcc")

as the first lines in my root CMakeLists.txt, otherwise CMake tries to use the default GCC 4.8 shipped by CentOS.

Thanks a lot for your help.

1 Answers

My 2 cents,

The –system-header-prefix= and –no-system-header-prefix= command-line arguments can be used to override whether subsets of an include path are treated as system headers. When the name in a #include directive is found within a header search path and starts with a system prefix, the header is treated as a system header. The last prefix on the command-line which matches the specified header name takes precedence. For instance:

 $ clang -Ifoo -isystem bar --system-header-prefix=x/ \
  --no-system-header-prefix=x/y/

Here, #include "x/a.h" is treated as including a system header, even if the header is found in foo, and #include "x/y/b.h" is treated as not including a system header, even if the header is found in bar.

ref: https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-in-system-headers

Otherwise did you try to see if it is not an issue with the compiler to not consider its own headers as system headers by default ?

Related