summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2018-12-05 20:27:08 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2018-12-06 15:11:51 (GMT)
commit98a39be6cfb7b229ff78f7045c6d5bcd6b6c7509 (patch)
tree1f9810b45b6d79710d89457d2db530cf5be24613
parent81bea69bd1d52977c3782d26560f34563394f487 (diff)
downloadCMake-98a39be6cfb7b229ff78f7045c6d5bcd6b6c7509.zip
CMake-98a39be6cfb7b229ff78f7045c6d5bcd6b6c7509.tar.gz
CMake-98a39be6cfb7b229ff78f7045c6d5bcd6b6c7509.tar.bz2
file: Add READ_SYMLINK sub-command
-rw-r--r--Help/command/file.rst24
-rw-r--r--Help/release/dev/file-read_symlink.rst5
-rw-r--r--Source/cmFileCommand.cxx30
-rw-r--r--Source/cmFileCommand.h1
-rw-r--r--Tests/RunCMake/file/READ_SYMLINK-noexist-result.txt1
-rw-r--r--Tests/RunCMake/file/READ_SYMLINK-noexist-stderr.txt6
-rw-r--r--Tests/RunCMake/file/READ_SYMLINK-noexist.cmake1
-rw-r--r--Tests/RunCMake/file/READ_SYMLINK-notsymlink-result.txt1
-rw-r--r--Tests/RunCMake/file/READ_SYMLINK-notsymlink-stderr.txt6
-rw-r--r--Tests/RunCMake/file/READ_SYMLINK-notsymlink.cmake2
-rw-r--r--Tests/RunCMake/file/READ_SYMLINK.cmake13
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake3
12 files changed, 93 insertions, 0 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 26a9ae2..6e2a6dd 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -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
^^^^^^^^^^^^^^^
diff --git a/Help/release/dev/file-read_symlink.rst b/Help/release/dev/file-read_symlink.rst
new file mode 100644
index 0000000..718802e
--- /dev/null
+++ b/Help/release/dev/file-read_symlink.rst
@@ -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.
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 73ff5a1..7fc717d 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -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;
+}
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 01e007d..fe05c98 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -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,
diff --git a/Tests/RunCMake/file/READ_SYMLINK-noexist-result.txt b/Tests/RunCMake/file/READ_SYMLINK-noexist-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/READ_SYMLINK-noexist-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/READ_SYMLINK-noexist-stderr.txt b/Tests/RunCMake/file/READ_SYMLINK-noexist-stderr.txt
new file mode 100644
index 0000000..32b3e85
--- /dev/null
+++ b/Tests/RunCMake/file/READ_SYMLINK-noexist-stderr.txt
@@ -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\)$
diff --git a/Tests/RunCMake/file/READ_SYMLINK-noexist.cmake b/Tests/RunCMake/file/READ_SYMLINK-noexist.cmake
new file mode 100644
index 0000000..9e57e4b
--- /dev/null
+++ b/Tests/RunCMake/file/READ_SYMLINK-noexist.cmake
@@ -0,0 +1 @@
+file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" result)
diff --git a/Tests/RunCMake/file/READ_SYMLINK-notsymlink-result.txt b/Tests/RunCMake/file/READ_SYMLINK-notsymlink-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/READ_SYMLINK-notsymlink-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/READ_SYMLINK-notsymlink-stderr.txt b/Tests/RunCMake/file/READ_SYMLINK-notsymlink-stderr.txt
new file mode 100644
index 0000000..63e32ed
--- /dev/null
+++ b/Tests/RunCMake/file/READ_SYMLINK-notsymlink-stderr.txt
@@ -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\)$
diff --git a/Tests/RunCMake/file/READ_SYMLINK-notsymlink.cmake b/Tests/RunCMake/file/READ_SYMLINK-notsymlink.cmake
new file mode 100644
index 0000000..a9798b6
--- /dev/null
+++ b/Tests/RunCMake/file/READ_SYMLINK-notsymlink.cmake
@@ -0,0 +1,2 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" "")
+file(READ_SYMLINK "${CMAKE_CURRENT_BINARY_DIR}/rel.sym" result)
diff --git a/Tests/RunCMake/file/READ_SYMLINK.cmake b/Tests/RunCMake/file/READ_SYMLINK.cmake
new file mode 100644
index 0000000..865a2e9
--- /dev/null
+++ b/Tests/RunCMake/file/READ_SYMLINK.cmake
@@ -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()
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index b9d76bf..b872824 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -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")