# Surrounding Paths with Spaces in Quotes: Where Does the Magic Happen?

**URL:** <https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940>\
**Category:** Development\
**Created:** [August 16, 2021, 11:22pm UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940 "2021-08-16T23:22:43Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![marco1475](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/c89c15/32.png) [@marco1475](https://discourse.cmake.org/u/marco1475)\
**Post date:** [August 16, 2021, 11:22pm UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/1 "2021-08-16T23:22:43Z")

</div>

On Windows, the following CMake code correctly wraps the path containing spaces in quotes:

```auto
set( cmdargs "-options" "${CMAKE_CURRENT_BINARY_DIR}/path with spaces" )

add_custom_command( OUTPUT MyGeneratedHeader.h
    COMMAND MyCompiler.exe ARGS ${cmdargs}
    USES_TERMINAL VERBATIM )

```

In Visual Studio, this generates the following command line:

```auto
MyCompiler.exe -options "D:/Project/_build/path with spaces"

```

So clearly there is some magic happening that puts quotes around the path, but not around -options.

However, that magic does not work for VS\_DEBUGGER\_COMMAND\_ARGUMENTS because

```auto
set_target_properties( "MyCompiler" PROPERTIES 
    VS_DEBUGGER_COMMAND_ARGUMENTS "${cmdargs}" )

```

results in

```auto
-options D:/Project/_build/path with spaces

```

in the Debugging → Command Line field of the MyCompiler project.

- When and where does CMake surround the path containing spaces with quotes?
- Can that same logic be applied to VS\_DEBUGGER\_COMMAND\_ARGUMENTS as well?

---

<div class="post-metadata">

**Author:** ![Dakon](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dakon/32/854_2.png) [@Dakon](https://discourse.cmake.org/u/Dakon)\
**Post date:** [August 17, 2021, 11:42am UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/2 "2021-08-17T11:42:38Z")

</div>

Did you notice you quoted on of them and not the other?

---

<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:** [August 17, 2021, 12:36pm UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/3 "2021-08-17T12:36:41Z")

</div>

The quoting is right in the CMake code here. `set_target_properties` takes a list of pairs, so not quoting `${cmdargs}` there would try to set a property named `"${CMAKE_CURRENT_BINARY_DIR}/path with spaces"` without a value (causing an error) and leave `VS_DEBUGGER_COMMAND_ARGUMENTS` with just `-options`.

Quoting is weird and inconsistent with CMake. I would recommend adding `\"` to `cmdargs` around arguments you want quoted for the target properties.

---

<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:** [August 17, 2021, 12:37pm UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/4 "2021-08-17T12:37:58Z")

</div>

Oh, there’s another difference here: `VERBATIM` in `add_custom_command`. I suspect that if you get it to work with `set_target_properties`, you can drop the `VERBATIM` and use the same value for both.

FWIW, I never use `VERBATIM` because I can’t remember all of the rules CMake applies and I find it easier to do some safety in the command specification myself, but YMMV.

---

<div class="post-metadata">

**Author:** ![marco1475](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/c89c15/32.png) [@marco1475](https://discourse.cmake.org/u/marco1475)\
**Post date:** [August 17, 2021, 10:00pm UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/5 "2021-08-17T22:00:00Z")

</div>

> I would recommend adding `\"` to `cmdargs` around arguments you want quoted for the target properties. […] I suspect that if you get it to work with `set_target_properties` , you can drop the `VERBATIM` and use the same value for both.

Yes, the workaround I came up with was surrounding the path with `\"` and not using `VERBATIM`.

`VERBATIM` and `\"` passes the escaped quote in the argument to my compiler, which causes issues with parsing the file path because Windows file I/O doesn’t handle quotes in file names. This forced me to write C++ code that strips leading and trailing quotes from paths.

Without `VERBATIM` and with `\"` I got what I wanted: the path is correctly quoted in both cases, but the quotes are not part of the argument.

I wanted to keep `VERBATIM` because the CMake documentation is recommending using it to guarantee that the arguments will be identical across platforms.

But I am still curious what causes the path to be quoted. It clearly is not part of the `set()` function, so my guess is that `add_custom_command()` does it. What I can’t figure out is how it decides to quote the second entry in my `cmdArgs` list, but not the first … Is it going by the presence of spaces in the entry?

---

<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:** [August 18, 2021, 12:57am UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/6 "2021-08-18T00:57:48Z")

</div>

> [@marco1475](#):
>
> What I can’t figure out is how it decides to quote the second entry in my `cmdArgs` list, but not the first … Is it going by the presence of spaces in the entry?

It sees a single CMake list item and wants to pass it as a single argument (with `VERBATIM`). This triggers adding the quotes.

> [@marco1475](#):
>
> I wanted to keep `VERBATIM` because the CMake documentation is recommending using it to guarantee that the arguments will be identical across platforms.

That is fine, but I just cannot keep CMake _and_ shell quoting in mind when looking at these things and I vastly prefer the conformity that not using `VERBATIM` affords with the “quote all variable expansions that are not part of `if` (and friends) arguments that care or are intended to be used as a list of arguments” rule I go by.

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [August 18, 2021, 11:17am UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/7 "2021-08-18T11:17:09Z")

</div>

the documentation states `The optional ARGS argument is for backward compatibility and will be ignored.` so it seems a version somewhere prior to CMake 3.0 is needed for the first case.

---

<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:** [August 18, 2021, 11:26am UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/8 "2021-08-18T11:26:58Z")

</div>

Huh? It is ignored. It doesn’t change anything. So…why would an older CMake be required?

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [August 18, 2021, 11:42am UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/9 "2021-08-18T11:42:34Z")

</div>

oh, i was just trying to recreate the examples, but i don’t see the same results and i don’t have VS installed.

While the quoting is correct i try to avoid unnecessary quoting. Quoting the target name is confusing and `-options` does not need quoting but YMMV.

---

<div class="post-metadata">

**Author:** ![marco1475](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/c89c15/32.png) [@marco1475](https://discourse.cmake.org/u/marco1475)\
**Post date:** [August 18, 2021, 6:14pm UTC](https://discourse.cmake.org/t/surrounding-paths-with-spaces-in-quotes-where-does-the-magic-happen/3940/10 "2021-08-18T18:14:11Z")

</div>

> the documentation states `The optional ARGS argument is for backward compatibility and will be ignored.` so it seems a version somewhere prior to CMake 3.0 is needed for the first case.

Huh, I am running that code example with CMake 3.20.5 and the `ARGS` arguments are being used. Thanks for the heads up, I’ll change the code to

```auto
add_custom_command( OUTPUT MyGeneratedHeader.h
    COMMAND MyCompiler.exe ${cmdargs}
    USES_TERMINAL VERBATIM )

```

as to not run the risk of it unexpectedly breaking with a new CMake version.

> It sees a single CMake list item and wants to pass it as a single argument (with `VERBATIM` ). This triggers adding the quotes.

If I understand it correctly, the logic is something like this:

1. The `COMMAND` property of `add_custom_command()` expects a `list`.
2. While parsing said `list`, if an entry contains spaces the entry’s content will be surrounded by quotes.

I have tested that this behavior is identical with and without `VERBATIM`. `VERBATIM` matters only if I explicitly add escaped quotes, which get passed to my executable with `VERBATIM` and are ignored without `VERBATIM`.

To bring this all back to what prompted my original post: **Would it make sense to add similar logic to `VS_DEBUGGER_COMMAND_ARGUMENTS`?**

My argument is that `VS_DEBUGGER_COMMAND_ARGUMENTS` explicitly expects _command arguments_ which should be surrounded by quotes if they contain spaces. Currently, if you pass the same list of arguments to `add_custom_command()` and to `VS_DEBUGGER_COMMAND_ARGUMENTS` you get two different argument lists.

The main question for someone familiar with the CMake source code is whether `set_property(TARGET)` already has special-case handling for different target properties. If all target properties are treated the same in `set_property()` then trying to implement a special case for `VS_DEBUGGER_COMMAND_ARGUMENTS` makes no sense …
