file: Add READ_SYMLINK sub-command

This commit is contained in:
Kyle Edwards
2018-12-05 15:27:08 -05:00
parent 81bea69bd1
commit 98a39be6cf
12 changed files with 93 additions and 0 deletions

View File

@@ -26,6 +26,7 @@ Synopsis
file(`MAKE_DIRECTORY`_ [<dir>...])
file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...])
file(`SIZE`_ <filename> <out-var>)
file(`READ_SYMLINK`_ <filename> <out-var>)
`Path Conversion`_
file(`RELATIVE_PATH`_ <out-var> <directory> <file>)
@@ -344,6 +345,29 @@ Determine the file size of the ``<filename>`` and put the result in
``<variable>`` variable. Requires that ``<filename>`` is a valid path
pointing to a file and is readable.
.. _READ_SYMLINK:
.. code-block:: cmake
file(READ_SYMLINK <filename> <variable>)
Read the symlink at ``<filename>`` and put the result in ``<variable>``.
Requires that ``<filename>`` is a valid path pointing to a symlink. If
``<filename>`` does not exist, or is not a symlink, an error is thrown.
Note that this command returns the raw symlink path and does not resolve
relative symlinks. If you want to resolve the relative symlink yourself, you
could do something like this:
.. code-block:: cmake
set(filename "/path/to/foo.sym")
file(READ_SYMLINK "${filename}" result)
if(NOT IS_ABSOLUTE "${result}")
get_filename_component(dir "${filename}" DIRECTORY)
set(result "${dir}/${result}")
endif()
Path Conversion
^^^^^^^^^^^^^^^

View File

@@ -0,0 +1,5 @@
file-read_symlink
-----------------
* The :command:`file` command learned a new sub-command, ``READ_SYMLINK``,
which can be used to determine the path that a symlink points to.

View File

@@ -180,6 +180,9 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "SIZE") {
return this->HandleSizeCommand(args);
}
if (subCommand == "READ_SYMLINK") {
return this->HandleReadSymlinkCommand(args);
}
std::string e = "does not recognize sub-command " + subCommand;
this->SetError(e);
@@ -3638,3 +3641,30 @@ bool cmFileCommand::HandleSizeCommand(std::vector<std::string> const& args)
return true;
}
bool cmFileCommand::HandleReadSymlinkCommand(
std::vector<std::string> const& args)
{
if (args.size() != 3) {
std::ostringstream e;
e << args[0] << " requires a file name and output variable";
this->SetError(e.str());
return false;
}
const std::string& filename = args[1];
const std::string& outputVariable = args[2];
std::string result;
if (!cmSystemTools::ReadSymlink(filename, result)) {
std::ostringstream e;
e << "READ_SYMLINK requested of path that is not a symlink:\n "
<< filename;
this->SetError(e.str());
return false;
}
this->Makefile->AddDefinition(outputVariable, result.c_str());
return true;
}

View File

@@ -60,6 +60,7 @@ protected:
bool HandleGenerateCommand(std::vector<std::string> const& args);
bool HandleLockCommand(std::vector<std::string> const& args);
bool HandleSizeCommand(std::vector<std::string> const& args);
bool HandleReadSymlinkCommand(std::vector<std::string> const& args);
private:
void AddEvaluationFile(const std::string& inputName,

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,6 @@
^CMake Error at 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\)$

View File

@@ -0,0 +1 @@
file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" result)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,6 @@
^CMake Error at 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\)$

View File

@@ -0,0 +1,2 @@
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" "")
file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" result)

View File

@@ -0,0 +1,13 @@
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()

View File

@@ -55,6 +55,9 @@ run_cmake_command(GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE ${CMAKE_COMMAND} -P
if(NOT WIN32 OR CYGWIN)
run_cmake(GLOB_RECURSE-cyclic-recursion)
run_cmake(INSTALL-SYMLINK)
run_cmake(READ_SYMLINK)
run_cmake(READ_SYMLINK-noexist)
run_cmake(READ_SYMLINK-notsymlink)
endif()
if(RunCMake_GENERATOR STREQUAL "Ninja")