mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 19:00:54 -06:00
file(): Add REAL_PATH sub-command
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
5
Help/release/dev/file-REAL_PATH.rst
Normal file
5
Help/release/dev/file-REAL_PATH.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
file-REAL_PATH
|
||||
--------------
|
||||
|
||||
* The :command:`file` gained sub-command `REAL_PATH` to compute a path with
|
||||
symlinks resolved.
|
||||
@@ -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 },
|
||||
|
||||
1
Tests/RunCMake/file/REAL_PATH-no-base-dir-result.txt
Normal file
1
Tests/RunCMake/file/REAL_PATH-no-base-dir-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
2
Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt
Normal file
2
Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\):
|
||||
file BASE_DIRECTORY requires a value
|
||||
2
Tests/RunCMake/file/REAL_PATH-no-base-dir.cmake
Normal file
2
Tests/RunCMake/file/REAL_PATH-no-base-dir.cmake
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
file(REAL_PATH "some-path" real_path BASE_DIRECTORY)
|
||||
1
Tests/RunCMake/file/REAL_PATH-unexpected-arg-result.txt
Normal file
1
Tests/RunCMake/file/REAL_PATH-unexpected-arg-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
2
Tests/RunCMake/file/REAL_PATH-unexpected-arg-stderr.txt
Normal file
2
Tests/RunCMake/file/REAL_PATH-unexpected-arg-stderr.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
CMake Error at REAL_PATH-unexpected-arg.cmake:[0-9]+ \(file\):
|
||||
file REAL_PATH called with unexpected arguments
|
||||
2
Tests/RunCMake/file/REAL_PATH-unexpected-arg.cmake
Normal file
2
Tests/RunCMake/file/REAL_PATH-unexpected-arg.cmake
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
file(REAL_PATH "some-path" real_path extra_arg)
|
||||
14
Tests/RunCMake/file/REAL_PATH.cmake
Normal file
14
Tests/RunCMake/file/REAL_PATH.cmake
Normal file
@@ -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()
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user