file(WRITE ...) behaves differently on Linux compared to Windows regarding escaped whitespaces?

Hi,

I wanted to automate the version-string generation from a git tag via CMake and came up with an approach very similar to the following.

main.c:

#include <stdio.h>

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

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)

project(TestingCmake LANGUAGES C)

add_executable(TestingCmake main.c)

set(FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/test_file.c)

add_custom_command(
    OUTPUT ${FILE_NAME}
    COMMAND ${CMAKE_COMMAND}
        -DSTRING_CONTENT="text with whitespace"
        -DFILE_PATH="${FILE_NAME}"
            -P ${CMAKE_CURRENT_SOURCE_DIR}/CreateVersion.cmake
)

add_custom_target(CreateClControllerVersionFile ALL
    COMMAND ${CMAKE_COMMAND}
        -DSTRING_CONTENT="text with whitespace"
        -DFILE_PATH="${FILE_NAME}"
            -P ${CMAKE_CURRENT_SOURCE_DIR}/CreateVersion.cmake
)

add_dependencies(TestingCmake CreateClControllerVersionFile)

CreateVersion.cmake:

file(WRITE ${FILE_PATH} "${STRING_CONTENT}")

Doing so I encountered [to me] seemingly strange behavior:
- under Windows [CMake 3.23.2] I got the expected result in the output file

text with whitespace
- under Linux [CMake 3.21.3] I encountered
text\ with\ whitespace

Is this expected behavior?

Is there a way for me to tell CMake to unescape the whitespaces during writing to file?

Should I approach my goal in a totally different way?

Thankful for any help

Johannes

You may want the VERBATIM argument here. Another problem (which may avoid the issue) is that inner quotes don’t work in CMake.

Try "-DSTRING_CONTENT=text with whitespace"; that may avoid the need for the VERBATIM. Also the same fix for FILE_PATH.

Hi Ben,

thanks for the fast reply.

Your proposed solution with the surrounding quotes seems to work. Thanks. Could you hint me to somewhere, in order to understand why?

In addition I ended up using VERBATIM as well, because I also had ( and ) as part of the string - which needed to be escaped for the command line.

Thanks

Johannes

My Quoting In CMake article discusses the broader topic. It may fill in a few blanks for you.

Other than the docs, quoting only works on whole “words”. It is not like bash (or other shells) where paired quotes can be jammed together to perform concatenation; in CMake the quotes become literal when they are not paired around words.