# How to I include\_directories() and/or target\_include\_directories() with GCC's/Clang's -iquote/-idirafter

**URL:** <https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609>\
**Category:** Code\
**Tags:** os:linux\
**Created:** [December 11, 2023, 5:08pm UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609 "2023-12-11T17:08:51Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)\
**Post date:** [December 11, 2023, 5:08pm UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/1 "2023-12-11T17:08:51Z")

</div>

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`](https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html) as opposed to a mere `-I` or `-isystem`. It’s a question I raised in [ticket 12928](https://gitlab.kitware.com/cmake/cmake/-/issues/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.

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [December 12, 2023, 8:33am UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/2 "2023-12-12T08:33:48Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)\
**Post date:** [December 12, 2023, 8:40am UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/3 "2023-12-12T08:40:25Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)\
**Post date:** [December 12, 2023, 9:22am UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/4 "2023-12-12T09:22:36Z")

</div>

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 🙂

---

<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:** [December 19, 2023, 2:58am UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/5 "2023-12-19T02:58:21Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![some\_name](https://discourse.cmake.org/user_avatar/discourse.cmake.org/some_name/32/3023_2.png) [@some\_name](https://discourse.cmake.org/u/some_name)\
**Post date:** [March 16, 2024, 12:43pm UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/6 "2024-03-16T12:43:10Z")

</div>

Hi, I want to upvote this as well. There is nothing ‘fragile’ about using -iquote. As a matter of fact, I want to use it for very efficient lookup of my header files. I work on a large codebase with a root CMakeLists.txt and I want to specify -iquote ${CMAKE\_SOURCE\_DIR} once. All my #include lines then look like:

#include “a.hpp” // Something in root folder  
#include “f1/b.hpp” // Something in f1 folder  
// So on and so forth

The compiler can then very efficiently look up my includes. I have even upvoted the request for iquote with Microsoft:

[https://developercommunity.visualstudio.com/t/How-Can-I-Emulate-the-GCC-Compiler-Optio/419914](https://developercommunity.visualstudio.com/t/How-Can-I-Emulate-the-GCC-Compiler-Optio/419914)

and I encourage others who are interested in this to upvote this issue at Microsoft. The quotes in Microsoft are extremely broken. There is a ‘grand-fathering’ effect in the Microsoft compiler, wherein a quoted include is first looked up in the current folder, then the current folder of the parent file which includes this include file, so on and so forth. It would be very nice if Microsoft can provide a way to override this ‘grand-fathering’ effect with -iquote.

At this point, this is a chicken and egg problem. Tools such as CMake do not want to provide support because it is really only used by GCC. And vendors like Microsoft see no incentive in implementing it.

---

<div class="post-metadata">

**Author:** ![some\_name](https://discourse.cmake.org/user_avatar/discourse.cmake.org/some_name/32/3023_2.png) [@some\_name](https://discourse.cmake.org/u/some_name)\
**Post date:** [April 2, 2024, 1:07pm UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/7 "2024-04-02T13:07:58Z")

</div>

Would appreciate if someone from the CMake team could share an update on this. Thanks in advance!

---

<div class="post-metadata">

**Author:** ![buildSystemPerson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/buildsystemperson/32/2851_2.png) [@buildSystemPerson](https://discourse.cmake.org/u/buildSystemPerson)\
**Post date:** [April 2, 2024, 3:58pm UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/8 "2024-04-02T15:58:41Z")

</div>

I’m relatively new to the CMake team so here are just my thoughts. This sounds like a similar situation to `SYSTEM`.

For a while `target_include_directories(foo SYSTEM PRIVATE .)` would just use `-isystem` on platforms that supported that it (EX: `GCC`) and it fall back to regular includes on `MSVC`. That was the case for quite a while until MSVC recently added support for `-external:I`. Which CMake then incorporated ([https://gitlab.kitware.com/cmake/cmake/-/merge\_requests/4766](https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4766)).

Perhaps a similar approach could be done for `-iquote`?

`target_include_directories(foo QUOTE PRIVATE .)` which would use `-iquote` functionality when available and fallback to regular include directories if it isn’t supported. Similar to `SYSTEM`. If this gets enough usage it may encourage vendors like Microsoft to implement it.

But this does raise further questions:

EX: How would `QUOTE` work with package managers? Many users have the expectation to use angle bracket includes for packaged libraries. Should `QUOTE` be translated to system when the library is installed then? If so that makes including the library different when using `find_package` vs `add_subdirectory`. Perhaps it could be limited to `PRIVATE` includes? It creates a lot of questions IMHO. Which in turn is a fair amount of maintenance / testing. Agreed with @ben.boeckel it looks non trivial.

You bring up valid points. It’s just a matter of limited developer resources. If you feel you have a good design on how to make this work and are willing to put in the time to help we would appreciate it.

---

<div class="post-metadata">

**Author:** ![some\_name](https://discourse.cmake.org/user_avatar/discourse.cmake.org/some_name/32/3023_2.png) [@some\_name](https://discourse.cmake.org/u/some_name)\
**Post date:** [April 3, 2024, 10:29am UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/9 "2024-04-03T10:29:22Z")

</div>

Hi buildSystemPerson,

Many thanks for your prompt reply. For my usecase, something as simple as the following would work:

include\_directories(QUOTE \<Path\>)

which causes \<Path\> to be included automatically for all projects with -iquote if available, otherwise reverts back to /I. I don’t actually have a usecase for how target\_include\_directories(QUOTE …) would be used. Once you make include\_directories available, I am sure people will give you feedback and that will help you refine the feature further.

Does this still look like too much work? If you don’t have enough developer resources, then at a high level, could you point out places in the source code where modifications would be needed?

---

<div class="post-metadata">

**Author:** ![buildSystemPerson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/buildsystemperson/32/2851_2.png) [@buildSystemPerson](https://discourse.cmake.org/u/buildSystemPerson)\
**Post date:** [April 3, 2024, 4:25pm UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/10 "2024-04-03T16:25:24Z")

</div>

[Here](https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmIncludeDirectoryCommand.cxx?ref_type=heads#L22) would be a good starting point. From there start looking at how `SYSTEM` is implemented. It should give you an idea how to get started.

If you are going to contribute see [CONTRIBUTING.rst](https://gitlab.kitware.com/cmake/cmake/-/blob/master/CONTRIBUTING.rst?ref_type=heads) as well. Please note that for a feature like this to be accepted new tests will be required. Also updating the i`nclude_directories` documentation appropriately.

---

<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:** [April 10, 2024, 10:36pm UTC](https://discourse.cmake.org/t/how-to-i-include-directories-and-or-target-include-directories-with-gccs-clangs-iquote-idirafter/9609/11 "2024-04-10T22:36:48Z")

</div>

A new argument to `include_directories` is how the [defunct D support branch](https://github.com/Kitware/CMake/commit/90a61b1dea57ab5835e139b238a56e5540cd3969) did it for `-J` (“text includes”). It is completely orthogonal to `-I` in D-land, so a lot of the questions of “what if a directory is specified with multiple keywords?” never came up. It was also long before I understood usage requirements enough to ask things like “what happens when installed?”, though it is trivial in that case since it is orthogonal.
