How to I include_directories() and/or target_include_directories() with GCC's/Clang's -iquote/-idirafter

Hi there,

I am wondering how to wield include_directories() and/or target_include_directories() to tell the preprocessor directly to use -iquote or -idirafter as opposed to a mere -I or -isystem. It’s a question I raised in ticket 12928 and I was referred here.

I would like to avoid having to set COMPILE_OPTIONS or similar explicitly via set().

To clarify: the SYSTEM option appears to correspond to -isystem, but there doesn’t appear to be a mapping of the other options.

I can’t provide an official answer, but to me these two options fall outside the abstractions CMake currently does or should potentially offer. The -iquote and -idirafter are very specialised, and to my knowledge very rarely used. To me, they are a sign that you’re probably doing something wrong. Code shouldn’t be so fragile that they need such fine-grained control over the header search path ordering. If the -I and -isystem flags are insufficient, you’re setting up your developers and any consumers of your project for future pain if you need -iquote or -idirafter to get a working build.

I took the time to sift through the code at 9be8198bcca330ba0810ab26cc9ae93712c63b8e and it turns out that -iquote and -isystem are not a thing in CMake, whereas -isystem is (243 matches in 49 files) as well as -isysroot.

Sorry, but I emphatically disagree with that assertion.

The lax handling and mashing up of quoted and angle-bracketed includes is a bad practice and the old-fashioned way. Making sure to only include system headers with angle brackets and others with quotes is the way to go. Making it impossible to represent this in CMake is unfortunate, but not the first time I hit these limitations over the years.

If you look at toolchain releases over the years you will also notice that transient includes are vanishing. So code that may have built on a previous release, now won’t, because header so-and-so doesn’t include another header that it previously did. In order to get cleaner this way, -iquote and -idirafter are tools you can’t work without.

But there’s a workaround, so it’s fine. Even though it’s not canonical or idiomatic CMake that comes out of it :slight_smile:

Note that there are various other “include directory” flavors in the wild. D has -J for “textual include” directories (as opposed to module search roots that -I provide). An abstraction would be nice, but also very non-trivial as CMake doesn’t really provide fine-grained control over the final ordering of such directories.

1 Like