mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Merge topic 'read-symlink-result'
3f3ba04d81file(READ_SYMLINK): Add RESULT option to capture errorsb5b72b0378Tests/RunCMake/file: Enable READ_SYMLINK cases on Windows when possible Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !11932
This commit is contained in:
+12
-4
@@ -43,7 +43,7 @@ Synopsis
|
||||
file(`COPY_FILE`_ <oldname> <newname> [...])
|
||||
file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...])
|
||||
file(`SIZE`_ <filename> <out-var>)
|
||||
file(`READ_SYMLINK`_ <linkname> <out-var>)
|
||||
file(`READ_SYMLINK`_ <linkname> <out-var> [...])
|
||||
file(`CREATE_LINK`_ <original> <linkname> [...])
|
||||
file(`CHMOD`_ <files>... <directories>... PERMISSIONS <permissions>... [...])
|
||||
file(`CHMOD_RECURSE`_ <files>... <directories>... PERMISSIONS <permissions>... [...])
|
||||
@@ -577,13 +577,21 @@ Filesystem
|
||||
pointing to a file and is readable.
|
||||
|
||||
.. signature::
|
||||
file(READ_SYMLINK <linkname> <variable>)
|
||||
file(READ_SYMLINK <linkname> <variable> [RESULT <result>])
|
||||
|
||||
.. versionadded:: 3.14
|
||||
|
||||
Query the symlink ``<linkname>`` and stores the path it points to
|
||||
in the result ``<variable>``. If ``<linkname>`` does not exist
|
||||
or is not a symlink, CMake issues a fatal error.
|
||||
in the result ``<variable>``.
|
||||
|
||||
The options are:
|
||||
|
||||
``RESULT <result>``
|
||||
.. versionadded:: 4.4
|
||||
|
||||
Capture the status of the operation in a ``<result>`` variable. The
|
||||
variable is set to ``0`` on success or an error message otherwise.
|
||||
If not specified, and the operation fails, a fatal error is emitted.
|
||||
|
||||
Note that this command returns the raw symlink path and does not resolve
|
||||
a relative path. The following is an example of how to ensure that an
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
read-symlink-result
|
||||
-------------------
|
||||
|
||||
* The :command:`file(READ_SYMLINK)` command gained a ``RESULT``
|
||||
option to capture errors without failing.
|
||||
@@ -3166,7 +3166,7 @@ bool HandleSizeCommand(std::vector<std::string> const& args,
|
||||
bool HandleReadSymlinkCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
if (args.size() != 3) {
|
||||
if (args.size() < 3) {
|
||||
status.SetError(
|
||||
cmStrCat(args[0], " requires a file name and output variable"));
|
||||
return false;
|
||||
@@ -3175,14 +3175,39 @@ bool HandleReadSymlinkCommand(std::vector<std::string> const& args,
|
||||
std::string const& filename = args[1];
|
||||
std::string const& outputVariable = args[2];
|
||||
|
||||
struct Arguments
|
||||
{
|
||||
std::string Result;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
cmArgumentParser<Arguments>{}.Bind("RESULT"_s, &Arguments::Result);
|
||||
|
||||
std::vector<std::string> unconsumedArgs;
|
||||
Arguments const arguments =
|
||||
parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
|
||||
if (!unconsumedArgs.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("READ_SYMLINK unknown argument:\n ", unconsumedArgs.front()));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string result;
|
||||
if (!cmSystemTools::ReadSymlink(filename, result)) {
|
||||
status.SetError(cmStrCat(
|
||||
"READ_SYMLINK requested of path that is not a symlink:\n ", filename));
|
||||
std::string const error = cmStrCat(
|
||||
"READ_SYMLINK requested of path that is not a symlink:\n ", filename);
|
||||
if (!arguments.Result.empty()) {
|
||||
status.GetMakefile().AddDefinition(arguments.Result, error);
|
||||
return true;
|
||||
}
|
||||
status.SetError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
status.GetMakefile().AddDefinition(outputVariable, result);
|
||||
if (!arguments.Result.empty()) {
|
||||
status.GetMakefile().AddDefinition(arguments.Result, "0");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
^-- result: '0'
|
||||
-- target: '[^']*/Tests/RunCMake/file/READ_SYMLINK-target.txt'$
|
||||
@@ -0,0 +1 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/READ_SYMLINK-common.cmake)
|
||||
@@ -0,0 +1,6 @@
|
||||
file(READ_SYMLINK "${link}" target RESULT result)
|
||||
if(CMAKE_HOST_WIN32)
|
||||
string(REPLACE [[\]] [[/]] target "${target}")
|
||||
endif()
|
||||
message(STATUS "result: '${result}'")
|
||||
message(STATUS "target: '${target}'")
|
||||
@@ -0,0 +1,2 @@
|
||||
-- result: 'READ_SYMLINK requested of path that is not a symlink:
|
||||
[^']*/Tests/RunCMake/file/READ_SYMLINK-noexist-capture-build/rel\.sym'
|
||||
@@ -0,0 +1,5 @@
|
||||
file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" target RESULT result)
|
||||
message(STATUS "result: '${result}'")
|
||||
if(DEFINED target)
|
||||
message(FATAL_ERROR "Target variable should not be defined on failure, got:\n '${target}'")
|
||||
endif()
|
||||
@@ -1,6 +1,6 @@
|
||||
^CMake Error at READ_SYMLINK-noexist\.cmake:[0-9]+ \(file\):
|
||||
^CMake Error at [^
|
||||
]*/Tests/RunCMake/file/READ_SYMLINK-noexist\.cmake:[0-9]+ \(file\):
|
||||
file READ_SYMLINK requested of path that is not a symlink:
|
||||
|
||||
.*/Tests/RunCMake/file/READ_SYMLINK-noexist-build/rel\.sym
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||
[^
|
||||
]*/Tests/RunCMake/file/READ_SYMLINK-noexist-build/rel\.sym$
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- result: 'READ_SYMLINK requested of path that is not a symlink:
|
||||
[^']*/Tests/RunCMake/file/READ_SYMLINK-notsymlink-capture-build/rel\.sym'
|
||||
@@ -0,0 +1,5 @@
|
||||
file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" target RESULT result)
|
||||
message(STATUS "result: '${result}'")
|
||||
if(DEFINED target)
|
||||
message(FATAL_ERROR "Target variable should not be defined on failure, got:\n '${target}'")
|
||||
endif()
|
||||
@@ -1,6 +1,6 @@
|
||||
^CMake Error at READ_SYMLINK-notsymlink\.cmake:[0-9]+ \(file\):
|
||||
^CMake Error at [^
|
||||
]*Tests/RunCMake/file/READ_SYMLINK-notsymlink\.cmake:[0-9]+ \(file\):
|
||||
file READ_SYMLINK requested of path that is not a symlink:
|
||||
|
||||
.*/Tests/RunCMake/file/READ_SYMLINK-notsymlink-build/rel\.sym
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||
[^
|
||||
]*/Tests/RunCMake/file/READ_SYMLINK-notsymlink-build/rel\.sym$
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
^-- result: '0'
|
||||
-- target: 'READ_SYMLINK-target.txt'$
|
||||
@@ -0,0 +1 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/READ_SYMLINK-common.cmake)
|
||||
@@ -1,13 +0,0 @@
|
||||
execute_process(COMMAND
|
||||
${CMAKE_COMMAND} -E create_symlink "test.txt" "${CMAKE_CURRENT_BINARY_DIR}/rel.sym")
|
||||
file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" result)
|
||||
if(NOT result STREQUAL "test.txt")
|
||||
message(SEND_ERROR "Relative symlink is \"${result}\", should be \"test.txt\"")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_BINARY_DIR}/test.txt" "${CMAKE_CURRENT_BINARY_DIR}/abs.sym")
|
||||
file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/abs.sym" result)
|
||||
if(NOT result MATCHES "^.*/Tests/RunCMake/file/READ_SYMLINK-build/test\\.txt$")
|
||||
message(SEND_ERROR "Absolute symlink is \"${result}\", should be \"*/Tests/RunCMake/file/READ_SYMLINK-build/test.txt\"")
|
||||
endif()
|
||||
@@ -86,9 +86,6 @@ if(NOT WIN32
|
||||
)
|
||||
run_cmake(GLOB_RECURSE-cyclic-recursion)
|
||||
run_cmake(INSTALL-SYMLINK)
|
||||
run_cmake(READ_SYMLINK)
|
||||
run_cmake(READ_SYMLINK-noexist)
|
||||
run_cmake(READ_SYMLINK-notsymlink)
|
||||
if(NOT CYGWIN)
|
||||
run_cmake(INSTALL-FOLLOW_SYMLINK_CHAIN)
|
||||
endif()
|
||||
@@ -96,6 +93,38 @@ if(NOT WIN32
|
||||
run_cmake(LOCK-symlink-no-truncate)
|
||||
endif()
|
||||
|
||||
# Try creating symbolic links to read below.
|
||||
# If this fails on the current filesystem, we'll skip those tests.
|
||||
block(PROPAGATE READ_SYMLINK-link-rel READ_SYMLINK-link-abs)
|
||||
set(READ_SYMLINK-dest-rel "READ_SYMLINK-target.txt")
|
||||
set(READ_SYMLINK-dest-abs "${RunCMake_BINARY_DIR}/${READ_SYMLINK-dest-rel}")
|
||||
file(WRITE "${READ_SYMLINK-dest-abs}" "")
|
||||
foreach(link IN ITEMS rel abs)
|
||||
set(READ_SYMLINK-link-${link} "${RunCMake_BINARY_DIR}/READ_SYMLINK-link-${link}.sym")
|
||||
file(REMOVE "${READ_SYMLINK-link-${link}}")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink "${READ_SYMLINK-dest-${link}}" "${READ_SYMLINK-link-${link}}"
|
||||
OUTPUT_VARIABLE create_symlink_stdout
|
||||
ERROR_VARIABLE create_symlink_stderr
|
||||
RESULT_VARIABLE create_symlink_result
|
||||
)
|
||||
if(NOT create_symlink_result EQUAL 0 OR NOT EXISTS "${READ_SYMLINK-link-${link}}")
|
||||
set(READ_SYMLINK-link-${link} "")
|
||||
endif()
|
||||
endforeach()
|
||||
endblock()
|
||||
|
||||
if(READ_SYMLINK-link-rel)
|
||||
run_cmake_script(READ_SYMLINK-rel "-Dlink=${READ_SYMLINK-link-rel}")
|
||||
endif()
|
||||
if(READ_SYMLINK-link-abs)
|
||||
run_cmake_script(READ_SYMLINK-abs "-Dlink=${READ_SYMLINK-link-abs}")
|
||||
endif()
|
||||
run_cmake_script(READ_SYMLINK-noexist)
|
||||
run_cmake_script(READ_SYMLINK-noexist-capture)
|
||||
run_cmake_script(READ_SYMLINK-notsymlink)
|
||||
run_cmake_script(READ_SYMLINK-notsymlink-capture)
|
||||
|
||||
run_cmake(REAL_PATH-non-existing)
|
||||
run_cmake(REAL_PATH-existing)
|
||||
run_cmake(REAL_PATH-unexpected-arg)
|
||||
|
||||
Reference in New Issue
Block a user