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:
parent
63ffe21036
commit
e4b793c614
@ -687,7 +687,8 @@ When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
|
||||
<Normalization>` after the path computation.
|
||||
|
||||
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.
|
||||
|
||||
Native Conversion
|
||||
|
@ -50,7 +50,7 @@ Synopsis
|
||||
file(`CHMOD_RECURSE`_ <files>... <directories>... PERMISSIONS <permissions>... [...])
|
||||
|
||||
`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({`TO_CMAKE_PATH`_ | `TO_NATIVE_PATH`_} <path> <out-var>)
|
||||
|
||||
@ -924,16 +924,26 @@ Path Conversion
|
||||
|
||||
.. 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
|
||||
|
||||
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`.
|
||||
``BASE_DIRECTORY <dir>``
|
||||
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`.
|
||||
|
||||
``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:
|
||||
|
||||
|
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
|
||||
{
|
||||
std::string BaseDirectory;
|
||||
bool ExpandTilde = false;
|
||||
};
|
||||
static auto const parser = cmArgumentParser<Arguments>{}.Bind(
|
||||
"BASE_DIRECTORY"_s, &Arguments::BaseDirectory);
|
||||
static auto const parser =
|
||||
cmArgumentParser<Arguments>{}
|
||||
.Bind("BASE_DIRECTORY"_s, &Arguments::BaseDirectory)
|
||||
.Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde);
|
||||
|
||||
std::vector<std::string> unparsedArguments;
|
||||
std::vector<std::string> keywordsMissingValue;
|
||||
@ -1270,7 +1273,21 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
|
||||
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();
|
||||
auto realPath = cmSystemTools::GetRealPath(path.GenericString());
|
||||
|
||||
|
@ -1,14 +1,36 @@
|
||||
|
||||
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)
|
||||
if (NOT WIN32 OR CYGWIN)
|
||||
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")
|
||||
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()
|
||||
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\"")
|
||||
|
||||
If (WIN32)
|
||||
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()
|
||||
|
@ -96,11 +96,12 @@ 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()
|
||||
|
||||
run_cmake(REAL_PATH-unexpected-arg)
|
||||
run_cmake(REAL_PATH-no-base-dir)
|
||||
run_cmake(REAL_PATH)
|
||||
|
||||
if(RunCMake_GENERATOR MATCHES "Ninja")
|
||||
# Detect ninja version so we know what tests can be supported.
|
||||
execute_process(
|
||||
|
Loading…
Reference in New Issue
Block a user