mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 05:26:58 +08:00
file(REAL_PATH): add option EXPAND_TILDE
This option enables the replacement of any leading tilde with the path to the user's home directory.
This commit is contained in:

committed by
Craig Scott

parent
63ffe21036
commit
e4b793c614
@@ -687,7 +687,8 @@ When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
|
|||||||
<Normalization>` after the path computation.
|
<Normalization>` after the path computation.
|
||||||
|
|
||||||
Because ``cmake_path()`` does not access the filesystem, symbolic links are
|
Because ``cmake_path()`` does not access the filesystem, symbolic links are
|
||||||
not resolved. To compute a real path with symbolic links resolved, use the
|
not resolved and any leading tilde is not expanded. To compute a real path
|
||||||
|
with symbolic links resolved and leading tildes expanded, use the
|
||||||
:command:`file(REAL_PATH)` command instead.
|
:command:`file(REAL_PATH)` command instead.
|
||||||
|
|
||||||
Native Conversion
|
Native Conversion
|
||||||
|
@@ -50,7 +50,7 @@ Synopsis
|
|||||||
file(`CHMOD_RECURSE`_ <files>... <directories>... PERMISSIONS <permissions>... [...])
|
file(`CHMOD_RECURSE`_ <files>... <directories>... PERMISSIONS <permissions>... [...])
|
||||||
|
|
||||||
`Path Conversion`_
|
`Path Conversion`_
|
||||||
file(`REAL_PATH`_ <path> <out-var> [BASE_DIRECTORY <dir>])
|
file(`REAL_PATH`_ <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE])
|
||||||
file(`RELATIVE_PATH`_ <out-var> <directory> <file>)
|
file(`RELATIVE_PATH`_ <out-var> <directory> <file>)
|
||||||
file({`TO_CMAKE_PATH`_ | `TO_NATIVE_PATH`_} <path> <out-var>)
|
file({`TO_CMAKE_PATH`_ | `TO_NATIVE_PATH`_} <path> <out-var>)
|
||||||
|
|
||||||
@@ -924,16 +924,26 @@ Path Conversion
|
|||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>])
|
file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE])
|
||||||
|
|
||||||
.. versionadded:: 3.19
|
.. versionadded:: 3.19
|
||||||
|
|
||||||
Compute the absolute path to an existing file or directory with symlinks
|
Compute the absolute path to an existing file or directory with symlinks
|
||||||
resolved.
|
resolved.
|
||||||
|
|
||||||
If the provided ``<path>`` is a relative path, it is evaluated relative to the
|
``BASE_DIRECTORY <dir>``
|
||||||
given base directory ``<dir>``. If no base directory is provided, the default
|
If the provided ``<path>`` is a relative path, it is evaluated relative to the
|
||||||
base directory will be :variable:`CMAKE_CURRENT_SOURCE_DIR`.
|
given base directory ``<dir>``. If no base directory is provided, the default
|
||||||
|
base directory will be :variable:`CMAKE_CURRENT_SOURCE_DIR`.
|
||||||
|
|
||||||
|
``EXPAND_TILDE``
|
||||||
|
.. versionadded:: 3.21
|
||||||
|
|
||||||
|
If the ``<path>`` is ``~`` or starts with ``~/``, the ``~`` is replaced by
|
||||||
|
the user's home directory. The path to the home directory is obtained from
|
||||||
|
environment variables. On Windows, the ``USERPROFILE`` environment variable
|
||||||
|
is used, falling back to the ``HOME`` environment variable if ``USERPROFILE``
|
||||||
|
is not defined. On all other platforms, only ``HOME`` is used.
|
||||||
|
|
||||||
.. _RELATIVE_PATH:
|
.. _RELATIVE_PATH:
|
||||||
|
|
||||||
|
5
Help/release/dev/file-REAL_PATH-EXPAND_TILDE.rst
Normal file
5
Help/release/dev/file-REAL_PATH-EXPAND_TILDE.rst
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
file-REAL_PATH-EXPAND_TILDE
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* The :command:`file(REAL_PATH)` command gained the option ``EXPAND_TILDE`` to
|
||||||
|
replace any leading tilde with the path to the user's home directory.
|
@@ -1246,9 +1246,12 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
|
|||||||
struct Arguments
|
struct Arguments
|
||||||
{
|
{
|
||||||
std::string BaseDirectory;
|
std::string BaseDirectory;
|
||||||
|
bool ExpandTilde = false;
|
||||||
};
|
};
|
||||||
static auto const parser = cmArgumentParser<Arguments>{}.Bind(
|
static auto const parser =
|
||||||
"BASE_DIRECTORY"_s, &Arguments::BaseDirectory);
|
cmArgumentParser<Arguments>{}
|
||||||
|
.Bind("BASE_DIRECTORY"_s, &Arguments::BaseDirectory)
|
||||||
|
.Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde);
|
||||||
|
|
||||||
std::vector<std::string> unparsedArguments;
|
std::vector<std::string> unparsedArguments;
|
||||||
std::vector<std::string> keywordsMissingValue;
|
std::vector<std::string> keywordsMissingValue;
|
||||||
@@ -1270,7 +1273,21 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
|
|||||||
arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
|
arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
cmCMakePath path(args[1]);
|
auto input = args[1];
|
||||||
|
if (arguments.ExpandTilde && !input.empty()) {
|
||||||
|
if (input[0] == '~' && (input.length() == 1 || input[1] == '/')) {
|
||||||
|
std::string home;
|
||||||
|
if (
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
cmSystemTools::GetEnv("USERPROFILE", home) ||
|
||||||
|
#endif
|
||||||
|
cmSystemTools::GetEnv("HOME", home)) {
|
||||||
|
input.replace(0, 1, home);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmCMakePath path(input, cmCMakePath::auto_format);
|
||||||
path = path.Absolute(arguments.BaseDirectory).Normal();
|
path = path.Absolute(arguments.BaseDirectory).Normal();
|
||||||
auto realPath = cmSystemTools::GetRealPath(path.GenericString());
|
auto realPath = cmSystemTools::GetRealPath(path.GenericString());
|
||||||
|
|
||||||
|
@@ -1,14 +1,36 @@
|
|||||||
|
|
||||||
file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/test.txt")
|
if (NOT WIN32 OR CYGWIN)
|
||||||
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test.sym")
|
file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/test.txt")
|
||||||
file(CREATE_LINK "test.txt" "${CMAKE_CURRENT_BINARY_DIR}/test.sym" SYMBOLIC)
|
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)
|
file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/test.sym" real_path)
|
||||||
if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/test.txt")
|
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\"")
|
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()
|
||||||
endif()
|
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")
|
If (WIN32)
|
||||||
message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/test.txt\"")
|
cmake_path(SET HOME_DIR "$ENV{USERPROFILE}")
|
||||||
|
if (NOT HOME_DIR)
|
||||||
|
cmake_path(SET HOME_DIR "$ENV{HOME}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(HOME_DIR "$ENV{HOME}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(REAL_PATH "~" real_path EXPAND_TILDE)
|
||||||
|
if (NOT real_path STREQUAL "${HOME_DIR}")
|
||||||
|
message(SEND_ERROR "real path is \"${real_path}\", should be \"${HOME_DIR}\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(REAL_PATH "~/test.txt" real_path EXPAND_TILDE)
|
||||||
|
if (NOT real_path STREQUAL "${HOME_DIR}/test.txt")
|
||||||
|
message(SEND_ERROR "real path is \"${real_path}\", should be \"${HOME_DIR}/test.txt\"")
|
||||||
endif()
|
endif()
|
||||||
|
@@ -96,11 +96,12 @@ if(NOT WIN32 OR CYGWIN)
|
|||||||
run_cmake(READ_SYMLINK-noexist)
|
run_cmake(READ_SYMLINK-noexist)
|
||||||
run_cmake(READ_SYMLINK-notsymlink)
|
run_cmake(READ_SYMLINK-notsymlink)
|
||||||
run_cmake(INSTALL-FOLLOW_SYMLINK_CHAIN)
|
run_cmake(INSTALL-FOLLOW_SYMLINK_CHAIN)
|
||||||
run_cmake(REAL_PATH-unexpected-arg)
|
|
||||||
run_cmake(REAL_PATH-no-base-dir)
|
|
||||||
run_cmake(REAL_PATH)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
run_cmake(REAL_PATH-unexpected-arg)
|
||||||
|
run_cmake(REAL_PATH-no-base-dir)
|
||||||
|
run_cmake(REAL_PATH)
|
||||||
|
|
||||||
if(RunCMake_GENERATOR MATCHES "Ninja")
|
if(RunCMake_GENERATOR MATCHES "Ninja")
|
||||||
# Detect ninja version so we know what tests can be supported.
|
# Detect ninja version so we know what tests can be supported.
|
||||||
execute_process(
|
execute_process(
|
||||||
|
Reference in New Issue
Block a user