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

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.

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.

Is this functionality available in CMake? I’m using 3.21.2.

Thanks a lot for your help.

I thought any paths that CMake detected as default header search paths were already treated as system. In fact, I thought it removed such paths from the header search path even if you explicitly added them. I might be recalling incorrectly though. Perhaps @ben.boeckel might be able to confirm that behavior?

If you’re using the CentOS devtoolsets, then usually there are things set in your shell environment. I don’t recall the exact command that does this, but if you use devtoolsets often, you probably know what I’m talking about. You must set the full environment that way, not just pull out the compiler paths only, from what I recall. That may be affecting what CMake sees as default system paths, if you’re not setting up the environment properly.

It’s definitely possible to stick -I/usr/include in CMake generated files. Things don’t like that much (#include_next being the main “victim”). That said, the compiler should be knowing that its own, built-in search paths are -isystem. Can you reproduce this behavior with a small test case outside of CMake? If so, what flags can make the warning/error go away?