# CMake grouping/combining -include directives/flags

**URL:** https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852
**Category:** Usage
**Created:** [November 12, 2022, 12:46am UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852 "2022-11-12T00:46:15Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![nilsdeppe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/nilsdeppe/32/2919_2.png) [@nilsdeppe](https://discourse.cmake.org/u/nilsdeppe)
#### Post date: [November 12, 2022, 12:46am UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852/1 "2022-11-12T00:46:15Z")

</div>

Hi!

I’m trying to specify multiple `-include blah` includes via generator expressions. CMake is not generating the expected compilation command, i.e.

```auto
-include cstddef -include csignal

```

but instead

```auto
-include cstddef csignal

```

which GCC doesn’t accept.

Here’s an example CMake config that has this problem:

```auto
 set(CODE_NAME ToyRts)
 set(CODE_VERSION 0.1.0)

 cmake_minimum_required(VERSION 3.12.0)

 project(${CODE_NAME} VERSION ${CODE_VERSION} LANGUAGES CXX)

 set(CMAKE_CXX_STANDARD 17)

 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

 add_executable(
   Main
   Main.cpp
 )

 set_property(TARGET Main
   APPEND PROPERTY
   COMPILE_OPTIONS
   $<$<COMPILE_LANGUAGE:CXX>:-include csignal>)

 set_property(TARGET Main
   APPEND PROPERTY
   COMPILE_OPTIONS
   $<$<COMPILE_LANGUAGE:CXX>:-include cstddef>)

```

Any `Main.cpp` will produce the issue. CMake generates the following compile command:

```auto
/usr/bin/c++ -include csignal cstddef -flto=auto -ffat-lto-objects -std=gnu++17 -o CMakeFiles/Main.dir/Main.cpp.o -c /home/nils/SpECTRE/ToyRts/Main.cpp

```

and then GCC complains with:

```auto
c++: warning: cstddef: linker input file unused because linking not done
c++: error: cstddef: linker input file not found: No such file or directory

```

as it should since somehow the incorrect compile command was generated. If I build with

```auto
/usr/bin/c++ -include csignal -include cstddef -flto=auto -ffat-lto-objects -std=gnu++17 -o CMakeFiles/Main.dir/Main.cpp.o -c /home/nils/SpECTRE/ToyRts/Main.cpp

```

everything compiles fine. This is the compilation command I would expect CMake to generate.

Any suggestions on how to get CMake to not combine the two `-include` directives would be appreciated!

Best wishes,

Nils

---

<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: [November 12, 2022, 1:24am UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852/2 "2022-11-12T01:24:58Z")

</div>

CMake uniquifies flags. It also has no abstraction for forced inclusion. Why can you not just add the appropriate `#include` lines to the files in question?

---

<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: [November 12, 2022, 1:43am UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852/3 "2022-11-12T01:43:17Z")

</div>

Let’s get some related things out of the way first:

- You should quote your generator expressions when they contain spaces or semicolons. See the following article for a detailed explanation of why (especially the _Generator Expressions_ section): [https://crascit.com/2022/01/25/quoting-in-cmake/](https://crascit.com/2022/01/25/quoting-in-cmake/)
- Prefer to use `target_compile_options()` rather than manipulating the `COMPILE_OPTIONS` target property directly.

Now to the core of your question. The `COMPILE_OPTIONS` target property is subject to compiler option de-duplication. Because you haven’t put quotes around your generator expression, CMake actually sees your generator expression as two separate arguments to the `set_property()` command. This results in a semicolon being used to separate the `-include` and `csignal` parts of what you tried to set. That in turn makes `-include` and `csignal` separately subject to de-duplication rather than the whole expression. Since `-include` will appear multiple times, CMake de-duplicates that and all but the first `-include` gets removed.

The `SHELL:` prefix is designed to handle this situation. It allows you to specify multiple options in a way that keeps them together. See the “Option De-duplication” section of the [target\_compile\_options()](https://cmake.org/cmake/help/latest/command/target_compile_options.html#option-de-duplication) docs. I think you’ll get the behavior you want if you replace your two `set_property()` calls with the following:

```cmake
target_compile_options(Main PRIVATE
    "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-include csignal>"
    "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-include cstddef>"
)

```

But like @ben.boeckel said, your source code should use `#include` rather than relying on `-include` compiler flags for something like this.

---

<div class="post-metadata">

### Author: ![nilsdeppe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/nilsdeppe/32/2919_2.png) [@nilsdeppe](https://discourse.cmake.org/u/nilsdeppe)
#### Post date: [November 12, 2022, 2:18am UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852/4 "2022-11-12T02:18:20Z")

</div>

Hi Ben and Craig!

Thanks for the very helpful responses!

The actual use-case is a bit more complicated than the example. The code base uses a PCH, which GCC needs to have specified as `-include`. Additionally, in debug mode we override the error handling of a 3rd party library (Blaze) with a macro definition (this is the official way to change error handling behavior in Blaze). The goal is to raise a `SIGTRAP` before throwing an exception (`catch throw` in GDB isn’t super user-friendly in our use-case). This means we’ve effectively inserted a new include requirement into the 3rd-party header-only library. While we could try to maintain wrapper headers for every interface header that Blaze provides, this is a bit tedious and adds non-negligible overhead. Instead, having the Blaze CMake target specify `-include csignal` seems more maintainable. I don’t love it, so if you have alternative suggestions they would be appreciated!

I’ve forgotten why this CMake code ended up using `set_property` instead of `target_compile_options`, but I’ll see if our CI passes with `target_compile_options` instead. Looking at the Cake 3.12 documentation (the oldest we support), there doesn’t seem to be any reason to not use `target_compile_options`.

CI will have the final say in terms of any edge cases with compiler settings, but this seems to be working correctly in the 3 build variations I’ve tried locally. Thank you both so much! I and the rest of the team really appreciate it!

Best,

Nils

---

<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: [November 12, 2022, 2:27am UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852/5 "2022-11-12T02:27:40Z")

</div>

> [@nilsdeppe](#):
>
> with a macro definition

Why would `target_compile_definitions(Blaze INTERFACE "$<$<CONFIG:Debug>:SYMBOL_YOU_NEED>")` not be sufficient? Arguably, `<csignal>` can be included in Blaze itself if that is set.

---

<div class="post-metadata">

### Author: ![nilsdeppe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/nilsdeppe/32/2919_2.png) [@nilsdeppe](https://discourse.cmake.org/u/nilsdeppe)
#### Post date: [November 12, 2022, 2:38am UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852/6 "2022-11-12T02:38:53Z")

</div>

Hi Ben!

Thanks for the suggestion! I’m not sure I completely follow, so my apologies if have misinterpreted. The definition we add is:

```auto
   target_compile_options(Blaze
     INTERFACE
     "$<$<COMPILE_LANGUAGE:CXX>:SHELL:
     -D 'BLAZE_THROW(EXCEPTION)=struct sigaction handler{}\;handler.sa_handler=\
 SIG_IGN\;handler.sa_flags=0\;sigemptyset(&handler.sa_mask)\;\
 sigaction(SIGTRAP,&handler,nullptr)\;raise(SIGTRAP)\;throw EXCEPTION'
     >")

```

The problem is that `SIGTRAP` is a preprocessor macro defined in `<csignal>` so I can’t forward declare that.

I think your second suggestion is that Blaze could include `csignal` for us. While true, since they don’t need it _unless_ someone changes the error handling in this particular way, I’m not sure I’ll have a good argument for them to include the header in a “just in case” way.

Best,

Nils

---

<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: [November 12, 2022, 8:36pm UTC](https://discourse.cmake.org/t/cmake-grouping-combining-include-directives-flags/6852/7 "2022-11-12T20:36:47Z")

</div>

I think it’d be better to have Blaze do something like:

```nohighlight
#if defined(BLAZE_OVERRIDE_THROW_HEADER)
#include BLAZE_OVERRIDE_THROW_HEADER
#endif

```

You can then stuff whatever you want in a real header and tell Blaze how to include it via `target_compile_definitions`.
