En CMake, tengo el siguiente fragmento:

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

En el código C ++, tengo este fragmento:

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

Lo cual funciona bien excepto en este caso: si alguien en MS Windows y copia la ruta del archivo a la GUI de CMake de la siguiente manera:

C:\nnn.txt
__^____

En lugar de:

C:/nnn.txt
__^____

O:

C:\\nnn.txt
__^^___

Va a causar un problema debido al carácter de escape.

¿Qué opciones tengo para resolver este problema además de decirle al desarrollador que preste atención a la "\ cosa"?

Pensé en reemplazar todos los sencillos \ con /, pero me di cuenta de que no hay nada llamado sencillo \ y no puedes buscar el sencillo \ si se inyecta en la cadena como simple \ en lugar de doble \\.

Por cierto, cualquier forma de solucionar este problema es muy apreciada incluso si fue en el nivel de CMake, no en el nivel de código C ++.

1
Humam Helfawi 18 feb. 2018 a las 05:03

2 respuestas

La mejor respuesta

Aquí hay algunos comentarios / soluciones en el lado de CMake

  1. Debes usar FILEPATH en lugar de STRING tipo de caché

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

    De la set() documentación del comando :

    FILEPATH: ruta a un archivo en el disco. cmake-gui (1 ) ofrece un cuadro de diálogo de archivo.

    Esto agrega el pequeño botón ... al final de su entrada en caché:

    ingrese la descripción de la imagen aquí

  2. Probablemente debería establecer la política CMP0005: los valores de definición del preprocesador ahora se escapan automáticamente a NEW

    cmake_policy(SET CMP0005 NEW)
    

    Eso manejaría el escape adecuado si el usuario pega manualmente una ruta de archivo que incluye barras invertidas.

  3. Puede usar el comando file() para normalizar la ruta me gusta:

    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}")
    

Referencias

3
Florian 19 feb. 2018 a las 08:43

¿Está buscando un enfoque config.h.in y una llamada configure_file() CMake?

Además, hay literales de cadena sin formato en C ++ 11 y posteriores, por lo que R"(c:\n.txt)" es en realidad lo mismo que "c:\\n.txt".

1
Victor Istomin 18 feb. 2018 a las 02:16