diff options
author | Brad King <brad.king@kitware.com> | 2020-09-09 15:25:41 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-09-09 15:26:26 (GMT) |
commit | f2e42c8369830b63e04356139c2ada18c6fed4ae (patch) | |
tree | 5832704b693b01459aa35aa0cfc6a8acfe1c4275 | |
parent | a09e9f98c0cca6baae9e47b388058e14ddcfa4da (diff) | |
parent | be36266dabee16d17a4f2e71fa9d05f8ef4769ce (diff) | |
download | CMake-f2e42c8369830b63e04356139c2ada18c6fed4ae.zip CMake-f2e42c8369830b63e04356139c2ada18c6fed4ae.tar.gz CMake-f2e42c8369830b63e04356139c2ada18c6fed4ae.tar.bz2 |
Merge topic 'file-real_path'
be36266dab file(): Add REAL_PATH sub-command
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5202
-rw-r--r-- | Help/command/file.rst | 14 | ||||
-rw-r--r-- | Help/command/get_filename_component.rst | 5 | ||||
-rw-r--r-- | Help/release/dev/file-REAL_PATH.rst | 5 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 46 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH-no-base-dir-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt | 2 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH-no-base-dir.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH-unexpected-arg-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH-unexpected-arg-stderr.txt | 2 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH-unexpected-arg.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH.cmake | 14 | ||||
-rw-r--r-- | Tests/RunCMake/file/RunCMakeTest.cmake | 3 |
12 files changed, 95 insertions, 2 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst index f4a817e..d77ad2d 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -49,6 +49,7 @@ Synopsis file(`CHMOD_RECURSE`_ <files>... <directories>... PERMISSIONS <permissions>... [...]) `Path Conversion`_ + file(`REAL_PATH`_ <path> <out-var> [BASE_DIRECTORY <dir>]) file(`RELATIVE_PATH`_ <out-var> <directory> <file>) file({`TO_CMAKE_PATH`_ | `TO_NATIVE_PATH`_} <path> <out-var>) @@ -806,6 +807,19 @@ the ``<directories>..`` recursively. Path Conversion ^^^^^^^^^^^^^^^ +.. _REAL_PATH: + +.. code-block:: cmake + + file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>]) + +Compute the absolute path to an existing file or directory with symlinks +resolved. + +If the provided ``<path>`` is a relative path, it is evaluated relative to the +given base directory ``<dir>``. If no base directory is provided, the default +base directory will be :variable:`CMAKE_CURRENT_SOURCE_DIR`. + .. _RELATIVE_PATH: .. code-block:: cmake diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst index 9d33a0a..e8c68b2 100644 --- a/Help/command/get_filename_component.rst +++ b/Help/command/get_filename_component.rst @@ -46,8 +46,9 @@ cache. .. note:: - All previous sub-commands, except ``REALPATH``, has been superseded by - :command:`cmake_path` command. + All previous sub-commands has been superseded by + :command:`cmake_path` command, except ``REALPATH`` now offered by + :ref:`file(REAL_PATH) <REAL_PATH>` command. .. code-block:: cmake diff --git a/Help/release/dev/file-REAL_PATH.rst b/Help/release/dev/file-REAL_PATH.rst new file mode 100644 index 0000000..32768ca --- /dev/null +++ b/Help/release/dev/file-REAL_PATH.rst @@ -0,0 +1,5 @@ +file-REAL_PATH +-------------- + +* The :command:`file` gained sub-command `REAL_PATH` to compute a path with + symlinks resolved. diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index cdb1492..84639a7 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -28,6 +28,7 @@ #include "cmAlgorithms.h" #include "cmArgumentParser.h" +#include "cmCMakePath.h" #include "cmCryptoHash.h" #include "cmExecutionStatus.h" #include "cmFSPermissions.h" @@ -1234,6 +1235,50 @@ bool HandleInstallCommand(std::vector<std::string> const& args, return installer.Run(args); } +bool HandleRealPathCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + if (args.size() < 3) { + status.SetError("REAL_PATH requires a path and an output variable"); + return false; + } + + struct Arguments + { + std::string BaseDirectory; + }; + static auto const parser = cmArgumentParser<Arguments>{}.Bind( + "BASE_DIRECTORY"_s, &Arguments::BaseDirectory); + + std::vector<std::string> unparsedArguments; + std::vector<std::string> keywordsMissingValue; + std::vector<std::string> parsedKeywords; + auto arguments = + parser.Parse(cmMakeRange(args).advance(3), &unparsedArguments, + &keywordsMissingValue, &parsedKeywords); + + if (!unparsedArguments.empty()) { + status.SetError("REAL_PATH called with unexpected arguments"); + return false; + } + if (!keywordsMissingValue.empty()) { + status.SetError("BASE_DIRECTORY requires a value"); + return false; + } + + if (parsedKeywords.empty()) { + arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory(); + } + + cmCMakePath path(args[1]); + path = path.Absolute(arguments.BaseDirectory).Normal(); + auto realPath = cmSystemTools::GetRealPath(path.GenericString()); + + status.GetMakefile().AddDefinition(args[2], realPath); + + return true; +} + bool HandleRelativePathCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { @@ -3360,6 +3405,7 @@ bool cmFileCommand(std::vector<std::string> const& args, { "RPATH_CHECK"_s, HandleRPathCheckCommand }, { "RPATH_REMOVE"_s, HandleRPathRemoveCommand }, { "READ_ELF"_s, HandleReadElfCommand }, + { "REAL_PATH"_s, HandleRealPathCommand }, { "RELATIVE_PATH"_s, HandleRelativePathCommand }, { "TO_CMAKE_PATH"_s, HandleCMakePathCommand }, { "TO_NATIVE_PATH"_s, HandleNativePathCommand }, diff --git a/Tests/RunCMake/file/REAL_PATH-no-base-dir-result.txt b/Tests/RunCMake/file/REAL_PATH-no-base-dir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/REAL_PATH-no-base-dir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt b/Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt new file mode 100644 index 0000000..7c58aeb --- /dev/null +++ b/Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\): + file BASE_DIRECTORY requires a value diff --git a/Tests/RunCMake/file/REAL_PATH-no-base-dir.cmake b/Tests/RunCMake/file/REAL_PATH-no-base-dir.cmake new file mode 100644 index 0000000..132aee6 --- /dev/null +++ b/Tests/RunCMake/file/REAL_PATH-no-base-dir.cmake @@ -0,0 +1,2 @@ + +file(REAL_PATH "some-path" real_path BASE_DIRECTORY) diff --git a/Tests/RunCMake/file/REAL_PATH-unexpected-arg-result.txt b/Tests/RunCMake/file/REAL_PATH-unexpected-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/REAL_PATH-unexpected-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/REAL_PATH-unexpected-arg-stderr.txt b/Tests/RunCMake/file/REAL_PATH-unexpected-arg-stderr.txt new file mode 100644 index 0000000..301db75 --- /dev/null +++ b/Tests/RunCMake/file/REAL_PATH-unexpected-arg-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at REAL_PATH-unexpected-arg.cmake:[0-9]+ \(file\): + file REAL_PATH called with unexpected arguments diff --git a/Tests/RunCMake/file/REAL_PATH-unexpected-arg.cmake b/Tests/RunCMake/file/REAL_PATH-unexpected-arg.cmake new file mode 100644 index 0000000..144f30b --- /dev/null +++ b/Tests/RunCMake/file/REAL_PATH-unexpected-arg.cmake @@ -0,0 +1,2 @@ + +file(REAL_PATH "some-path" real_path extra_arg) diff --git a/Tests/RunCMake/file/REAL_PATH.cmake b/Tests/RunCMake/file/REAL_PATH.cmake new file mode 100644 index 0000000..be25706 --- /dev/null +++ b/Tests/RunCMake/file/REAL_PATH.cmake @@ -0,0 +1,14 @@ + +file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/test.txt") +file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test.sym") +file(CREATE_LINK "test.txt" "${CMAKE_CURRENT_BINARY_DIR}/test.sym" SYMBOLIC) + +file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/test.sym" real_path) +if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt") + message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"") +endif() + +file(REAL_PATH "test.sym" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") +if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt") + message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"") +endif() diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index 8d84943..22813eb 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -72,6 +72,9 @@ if(NOT WIN32 OR CYGWIN) run_cmake(READ_SYMLINK-noexist) run_cmake(READ_SYMLINK-notsymlink) run_cmake(INSTALL-FOLLOW_SYMLINK_CHAIN) + run_cmake(REAL_PATH-unexpected-arg) + run_cmake(REAL_PATH-no-base-dir) + run_cmake(REAL_PATH) endif() if(RunCMake_GENERATOR MATCHES "Ninja") |