# Preserving options with spaces in add\_compile\_options

**URL:** https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551
**Category:** Usage
**Tags:** os:linux, gen:makefiles, comp:intel, lang:c, lang:fortran
**Created:** [July 14, 2020, 10:51am UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551 "2020-07-14T10:51:52Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![kvrigor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kvrigor/32/739_2.png) [@kvrigor](https://discourse.cmake.org/u/kvrigor)
#### Post date: [July 14, 2020, 10:51am UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/1 "2020-07-14T10:51:52Z")

</div>

Hello,

I have a CMake project with several targets and I wish to set global compile options through `add_compile_options` . These are the flags that I need to set:

| **ifort** | **icc** |
| --- | --- |
| `-qno-opt-dynamic-align` | `-qno-opt-dynamic-align` |
| `-convert big_endian` | `-fp-model precise` |
| `-assume byterecl` | `-O2` |
| `-ftz` | `-debug minimal` |
| `-traceback` | |
| `-assume realloc_lhs` | |
| `-fp-model source` | |
| `-O2` | |
| `-debug minimal` | |
| `-free` | |

First I validated the flags via `icc` and `ifort` (v19.0.5.281). No compiler warnings generated and compilation is successful.

```auto
ifort -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free -o hello_F90.out hello.F90
icc -qno-opt-dynamic-align -fp-model precise -O2 -debug minimal -o hello_C.out hello.c

```

Next, I created a test project which tries to achieve the same result through `add_compile_options`.

```auto
cmake_minimum_required (VERSION 3.14)

project (helloworld LANGUAGES C Fortran)

# CASE 1: unquoted flags, space-separated
set(fflags -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free)
set(cflags -qno-opt-dynamic-align -fp-model precise -O2 -debug minimal)
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:${fflags}>")
add_compile_options("$<$<COMPILE_LANGUAGE:C>:${cflags}>")

add_library(helloworld STATIC hello.c hello.F90)

```

Triggering the build on my Bash terminal,

```auto
$ cmake -S . -B bld -DCMAKE_C_COMPILER=icc -DCMAKE_Fortran_COMPILER=ifort
-- The C compiler identification is Intel 19.0.5.20190815
-- The Fortran compiler identification is Intel 19.0.5.20190815
-- Check for working C compiler: /opt/software/icc/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/icc
-- Check for working C compiler: /opt/software/icc/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/icc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working Fortran compiler: /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort
-- Check for working Fortran compiler: /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort -- works
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Checking whether /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort supports Fortran 90
-- Checking whether /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort supports Fortran 90 -- yes
-- Configuring done
-- Generating done
-- Build files have been written to: /home/projectuser/cmake-hello/bld
$ cmake --build bld
Scanning dependencies of target helloworld
[33%] Building C object CMakeFiles/helloworld.dir/hello.c.o
[66%] Building Fortran object CMakeFiles/helloworld.dir/hello.F90.o
ifort: error #10236: File not found: 'realloc_lhs'
gmake[2]: *** [CMakeFiles/helloworld.dir/hello.F90.o] Error 1
gmake[2]: *** Deleting file `CMakeFiles/helloworld.dir/hello.F90.o'
gmake[1]: *** [CMakeFiles/helloworld.dir/all] Error 2
gmake: *** [all] Error 2

```

I get the error `File not found: 'realloc_lhs'`. Inspecting `bld/CMakeFiles/helloworld.dir/flags.make` reveals the flags used:

```auto
C_FLAGS = -qno-opt-dynamic-align -fp-model precise -O2 -debug minimal
Fortran_FLAGS = -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback realloc_lhs -fp-model source -O2 -debug minimal -free

```

I tried different variations of setting compiler flags and was able to successfully compile the project, but the compiler warnings suggest that some flags were not recognized.

- **CASE 2:** Enclosed in quotes, space-separated

- **CASE 3:** Enclosed in quotes, semicolon separated

- **CASE 4:** Key-value pair options enclosed in quotes, space-separated

To summarize this post, **how can I pass a compiler option of the form _-key value_ to `add_compiler_options` (minimum CMake v3.14)?** Note that I don’t wish to use `target_compile_options` since my goaI is to “enforce” compiler-dependent flags on all my targets.

If it helps, these are the Hello World programs that I used for testing.

- C

```auto
#include <stdio.h>

int main() {
   printf("Hello World!");
   return 0;
}

```

- Fortran

```auto
program hello
  print *, 'Hello, World!'
end program hello

```

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [July 14, 2020, 1:56pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/2 "2020-07-14T13:56:49Z")

</div>

To pass “compound” options, you have to use `SHELL:` prefix (see [add\_compile\_options, Arguments paragraph](https://cmake.org/cmake/help/latest/command/add_compile_options.html)).

For example:

```cmake
add_compile_options("SHELL:-assume realloc_lhs" "SHELL:-assume byterecl")

```

---

<div class="post-metadata">

### Author: ![kvrigor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kvrigor/32/739_2.png) [@kvrigor](https://discourse.cmake.org/u/kvrigor)
#### Post date: [July 14, 2020, 2:47pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/3 "2020-07-14T14:47:53Z")

</div>

Thank you Marc! I can’t believe I missed this on the CMake docs (I’m drowned by a lot of docs that I need to look up for my project).

I would suggest to make this use case more transparent via an example instead of burying it in a block of text which is more likely to be overlooked. Anyway I’d also better RTFM more carefully next time; important thing this is now solved. Thanks again!

---

<div class="post-metadata">

### Author: ![kvrigor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kvrigor/32/739_2.png) [@kvrigor](https://discourse.cmake.org/u/kvrigor)
#### Post date: [July 14, 2020, 3:30pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/4 "2020-07-14T15:30:21Z")

</div>

To complete this post, either of the methods below can successfully compile my project.

1. All flags wrapped with **"SHELL:"**

```auto
set(fflags "SHELL:-qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free")
set(cflags "SHELL:-qno-opt-dynamic-align -fp-model precise -O2 -debug minimal")
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:${fflags}>")
add_compile_options("$<$<COMPILE_LANGUAGE:C>:${cflags}>")

```

1. Compound flags separated from single-token flags and then wrapped with **"SHELL:"**

```auto
set(fflags -O2 -ftz -free -traceback -qno-opt-dynamic-align "SHELL:-convert big_endian -assume byterecl -assume realloc_lhs -fp-model source -debug minimal")
set(cflags -O2 -qno-opt-dynamic-align "SHELL:-fp-model precise -debug minimal")
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:${fflags}>")
add_compile_options("$<$<COMPILE_LANGUAGE:C>:${cflags}>")

```

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [July 14, 2020, 3:40pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/5 "2020-07-14T15:40:16Z")

</div>

But option 1. is not a so good approach because it will prevent `CMake` to de-duplicate options.

---

<div class="post-metadata">

### Author: ![kvrigor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kvrigor/32/739_2.png) [@kvrigor](https://discourse.cmake.org/u/kvrigor)
#### Post date: [July 14, 2020, 4:20pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/6 "2020-07-14T16:20:37Z")

</div>

Wouldn’t de-duplication take effect only when `add_compile_options` is used without the `SHELL:` prefix? My thought is once `SHELL:` is used then the compile line is treated as-is and no further post-processing is done on the flags.

---

<div class="post-metadata">

### Author: ![kvrigor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kvrigor/32/739_2.png) [@kvrigor](https://discourse.cmake.org/u/kvrigor)
#### Post date: [July 14, 2020, 4:25pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/7 "2020-07-14T16:25:44Z")

</div>

Sorry I got confused, you meant that _option 1 **would prevent** `CMake` to de-duplicate options._. I need to clarify then that my use case is only valid for multiple unique flags. I will update the accepted answer.

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [July 14, 2020, 5:34pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/8 "2020-07-14T17:34:24Z")

</div>

Not exactly. All options are treated for de-duplication even when `SHELL:` is used. The effect of `SHELL:` is to take is argument as **one** option and this option will be considered for de-duplication. For example, for `"SHELL:-assume realloc_lhs"`, `CMake` will consider `"-assume realloc_lhs"` for de-duplication.

So specify all options as part of one `SHELL:` will have as result to consider all your options as one option for de-duplication step.

---

<div class="post-metadata">

### Author: ![kvrigor](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kvrigor/32/739_2.png) [@kvrigor](https://discourse.cmake.org/u/kvrigor)
#### Post date: [July 15, 2020, 7:20am UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/9 "2020-07-15T07:20:57Z")

</div>

> The effect of `SHELL:` is to take is argument as **one** option and this option will be considered for de-duplication.

Thanks for the clarification. IMO de-duplication under the context of `SHELL:` usage isn’t transparent in the docs. Anyway while de-duplication is useful there might be times when I don’t want my flags to be modified in any way, e.g. one case might be replicating compile warnings/errors from users of our software. I realize this could be already out of scope of `add_compile_options` and setting `CMAKE_<LANG>_FLAGS` instead might be better suited to this purpose.

---

<div class="post-metadata">

### Author: ![Shaun-Cox](https://discourse.cmake.org/user_avatar/discourse.cmake.org/shaun-cox/32/912_2.png) [@Shaun-Cox](https://discourse.cmake.org/u/Shaun-Cox)
#### Post date: [March 24, 2021, 9:17pm UTC](https://discourse.cmake.org/t/preserving-options-with-spaces-in-add-compile-options/1551/10 "2021-03-24T21:17:09Z")

</div>

Is there a way to make `SHELL:` work when the second argument is a full path containing spaces and needs embedded quotes to be handled correctly by the compiler argument processing code?

e.g. this doesn’t work:

```
add_compile_options(
    "SHELL:/analyze:ruleset \"${CFW_VS_RULESETS_PATH}/SecurityRules.ruleset\""
    "SHELL:/analyze:ruleset \"${CFW_VS_RULESETS_PATH}/NativeMinimumRules.ruleset\""
    "SHELL:/analyze:ruleset \"${CFW_VS_RULESETS_PATH}/NativeRecommendedRules.ruleset\""
)
```
