Humam Helfawi
Humam Helfawi

Reputation: 20304

File path from CMake as string in C++

In CMake, I have the following snippet:

set(FILE_PATH "" CACHE STRING "Full path of the file")
add_definitions(-DFILE_PATH="${DATA_SET_PATH}")

In C++ code, I have this snippet:

std::string my_file_path = std::string(FILE_PATH);

Which works well except for this case: If some one on MS Windows and copy the file path to the CMake GUI as following:

C:\nnn.txt
__^____

Instead of:

C:/nnn.txt
__^____

or:

C:\\nnn.txt
__^^___

It is going to cause a problem because of the escape character.

What options do I have to solve this problem other than telling the developer to pay attention for the "\ thing"?

I thought of replacing all singles \ with / but I realized that there is nothing called single \ and you can not search for single \ if it was injected in the string as single \ instead of double \\.

BTW, any way to fix this problem is much appreciated even if it was on CMake level not C++ code level.

Upvotes: 1

Views: 3762

Answers (2)

Florian
Florian

Reputation: 43020

Here are some remarks/solutions on the CMake side of it

  1. You should use FILEPATH instead of STRING cache type

    set(FILE_PATH "" CACHE FILEPATH "Full path of the file")
    

    From the set() command documentation:

    FILEPATH : Path to a file on disk. cmake-gui(1) offers a file dialog.

    This does add the little ... button at the end of your cached entry:

    enter image description here

  2. You should probably set policy CMP0005: Preprocessor definition values are now escaped automatically to NEW

    cmake_policy(SET CMP0005 NEW)
    

    That would handle the proper escaping if the user does manually paste a file path including backslashes.

  3. You could use the file() command to normalize the path like:

    set(FILE_PATH "" CACHE FILEPATH "Full path of the file")
    file(TO_CMAKE_PATH "${FILE_PATH}" FILE_PATH_NORMALIZED)
    add_definitions(-DFILE_PATH="${FILE_PATH_NORMALIZED}")
    

References

Upvotes: 3

Victor Istomin
Victor Istomin

Reputation: 1156

Are you looking for config.h.in approach and configure_file() CMake call?

Additionally, there is raw string literals in C++ 11 and later, so R"(c:\n.txt)" is actually the same as "c:\\n.txt".

Upvotes: 1

Related Questions