Add normalize_path into the cmake -E

It would be very convenient, e.g., for some environments in which the mixed slashes could approach
I got this at GitHub Actions with their github.workflow - it has backslashes on Windows, but it was mixed with forward slashes and CMake has reported an error:

Run cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="D:\a\std_version\std_version/build" -DCMAKE_MODULE_PATH="D:\a\std_version\std_version/build"
-- Building for: Visual Studio 17 2022
-- The CXX compiler identification is MSVC 19.34.31935.0
-- Detecting CXX compiler ABI info
CMake Error at D:/a/std_version/std_version/build/CMakeFiles/CMakeScratch/TryCompile-ej6is1/CMakeLists.txt:2 (set):
  Syntax error in cmake code at

    D:/a/std_version/std_version/build/CMakeFiles/CMakeScratch/TryCompile-ej6is1/CMakeLists.txt:2

  when parsing string

    D:\a\std_version\std_version/build

  Invalid character escape '\a'.


CMake Error at C:/Program Files/CMake/share/cmake-3.25/Modules/CMakeDetermineCompilerABI.cmake:57 (try_compile):
  Failed to configure test project build system.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.25/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)
  CMakeLists.txt:4 (project)


-- Configuring incomplete, errors occurred!
See also "D:/a/std_version/std_version/build/CMakeFiles/CMakeOutput.log".

I’m thinking on making the simplest script with cmake_path() and executing it ad-hoc for normalizing paths, but the cmake -E normalize_path <path> would be more convenient. It looks like:

cmake_minimum_required(VERSION 3.20)
# cmake -P NormalizePath.cmake <path> - <path> is argv3
cmake_path(SET FS_PATH NORMALIZE "${CMAKE_ARGV3}")
message("${FS_PATH}")

and can be launched via cmake -P NormalizePath.cmake C:\some/wacky//weird/./path.

p.s. Github Actions run on Windows with failure logs: feat(CI): Test Github Actions on Windows and Macos (Take #2) · leha-bot/std_version@b12824b · GitHub

If you use -DCMAKE_PREFIX_PATH:PATH does it work (by telling CMake “this is a path” which then does /-normalization when inserting into the cache)? The problem here seems to be that the prefix path is written literally to the script where \ is an escape character. CMake generally prefers to use / in paths and convert to \ only where necessary.

1 Like

agreed, yes, and I think that instead of writing the script it’s better to call the proposed cmake -E normalize_path ${{github.workspace}}/build

The other thing CMake should do is escape variable values it writes for try_compile and friends.

Is there not a PowerShell command for doing this in the meantime?

That’s a bit of a lie, because formally CMAKE_PREFIX_PATH is a list of paths. That means STRING is the more correct variable type, since we have no other variable type for lists of anything. Quite often, a user might only put one path in CMAKE_PREFIX_PATH, which may make a PATH variable type appear to work. Maybe it’s fine when it only contains one value, but we shouldn’t really encourage this.

Ideally, we’d have PATHLIST or something, but CMake and types…

1 Like

I send a (maybe ad-hoc) fix for MODULE_PATH: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/8012