summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-06-16 13:05:41 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-06-16 13:05:52 (GMT)
commit8d5eb04e85259e9d1b650a8327fd915b872b4e3d (patch)
treedeb0baee3975f3e19a6bceb7070efd2ea4f17b2e
parent7787c6f7c0b7f5f2cd8f63f8a521b3005a43923b (diff)
parent9d45a8be085490a6c3ce4db27968247297a8bdd2 (diff)
downloadCMake-8d5eb04e85259e9d1b650a8327fd915b872b4e3d.zip
CMake-8d5eb04e85259e9d1b650a8327fd915b872b4e3d.tar.gz
CMake-8d5eb04e85259e9d1b650a8327fd915b872b4e3d.tar.bz2
Merge topic 'find_program-exe-no-read'
9d45a8be08 find_program: Find programs that are executable but not readable Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !4896
-rw-r--r--Help/manual/cmake-policies.7.rst8
-rw-r--r--Help/policy/CMP0109.rst22
-rw-r--r--Help/release/dev/find_program-exe-no-read.rst5
-rw-r--r--Source/cmFindProgramCommand.cxx48
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Tests/RunCMake/find_program/CMP0109-Common.cmake (renamed from Tests/RunCMake/find_program/ExeNoRead.cmake)3
-rw-r--r--Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt2
-rw-r--r--Tests/RunCMake/find_program/CMP0109-NEW.cmake2
-rw-r--r--Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt2
-rw-r--r--Tests/RunCMake/find_program/CMP0109-OLD.cmake2
-rw-r--r--Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt29
-rw-r--r--Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt2
-rw-r--r--Tests/RunCMake/find_program/CMP0109-WARN.cmake1
-rw-r--r--Tests/RunCMake/find_program/ExeNoRead-stdout.txt1
-rw-r--r--Tests/RunCMake/find_program/RunCMakeTest.cmake4
15 files changed, 132 insertions, 4 deletions
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index e98038a..3ceb1df 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,14 @@ Policies Introduced by CMake 3.18
.. toctree::
:maxdepth: 1
+ CMP0109: find_program() requires permission to execute but not to read. </policy/CMP0109>
+
+Policies Introduced by CMake 3.18
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
CMP0108: A target cannot link to itself through an alias. </policy/CMP0108>
CMP0107: An ALIAS target cannot overwrite another target. </policy/CMP0107>
CMP0106: The Documentation module is removed. </policy/CMP0106>
diff --git a/Help/policy/CMP0109.rst b/Help/policy/CMP0109.rst
new file mode 100644
index 0000000..7542c8f
--- /dev/null
+++ b/Help/policy/CMP0109.rst
@@ -0,0 +1,22 @@
+CMP0109
+-------
+
+:command:`find_program` requires permission to execute but not to read.
+
+In CMake 3.18 and below, the :command:`find_program` command on UNIX
+would find files that are readable without requiring execute permission,
+and would not find files that are executable without read permission.
+In CMake 3.19 and above, ``find_program`` now prefers to require execute
+permission but not read permission. This policy provides compatibility
+with projects that have not been updated to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for ``find_program`` to require
+read permission but not execute permission.
+The ``NEW`` behavior for this policy is for ``find_program`` to require
+execute permission but not read permission.
+
+This policy was introduced in CMake version 3.19. CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/find_program-exe-no-read.rst b/Help/release/dev/find_program-exe-no-read.rst
new file mode 100644
index 0000000..161b5db
--- /dev/null
+++ b/Help/release/dev/find_program-exe-no-read.rst
@@ -0,0 +1,5 @@
+find_program-exe-no-read
+------------------------
+
+* The :command:`find_program` command now requires permission to execute
+ but not to read the file found. See policy :policy:`CMP0109`.
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 4f3fcdd..77728ec 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -4,6 +4,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -19,6 +20,7 @@ struct cmFindProgramHelper
cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
: DebugSearches("find_program", base)
, Makefile(makefile)
+ , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
{
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
// Consider platform-specific extensions.
@@ -48,6 +50,8 @@ struct cmFindProgramHelper
cmFindBaseDebugState DebugSearches;
cmMakefile* Makefile;
+ cmPolicies::PolicyStatus PolicyCMP0109;
+
void AddName(std::string const& name) { this->Names.push_back(name); }
void SetName(std::string const& name)
{
@@ -85,7 +89,7 @@ struct cmFindProgramHelper
this->TestNameExt = cmStrCat(name, ext);
this->TestPath =
cmSystemTools::CollapseFullPath(this->TestNameExt, path);
- bool exists = cmSystemTools::FileExists(this->TestPath, true);
+ bool exists = this->FileIsExecutable(this->TestPath);
exists ? this->DebugSearches.FoundAt(this->TestPath)
: this->DebugSearches.FailedAt(this->TestPath);
if (exists) {
@@ -95,6 +99,48 @@ struct cmFindProgramHelper
}
return false;
}
+ bool FileIsExecutable(std::string const& file) const
+ {
+ switch (this->PolicyCMP0109) {
+ case cmPolicies::OLD:
+ return cmSystemTools::FileExists(file, true);
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ return cmSystemTools::FileIsExecutable(file);
+ default:
+ break;
+ }
+ bool const isExeOld = cmSystemTools::FileExists(file, true);
+ bool const isExeNew = cmSystemTools::FileIsExecutable(file);
+ if (isExeNew == isExeOld) {
+ return isExeNew;
+ }
+ if (isExeNew) {
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+ "\n"
+ "The file\n"
+ " ",
+ file,
+ "\n"
+ "is executable but not readable. "
+ "CMake is ignoring it for compatibility."));
+ } else {
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+ "\n"
+ "The file\n"
+ " ",
+ file,
+ "\n"
+ "is readable but not executable. "
+ "CMake is using it for compatibility."));
+ }
+ return isExeOld;
+ }
};
cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a82f421..49dadc7 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -320,7 +320,10 @@ class cmMakefile;
SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
3, 18, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0108, "A target cannot link to itself through an alias.", \
- 3, 18, 0, cmPolicies::WARN)
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0109, \
+ "find_program() requires permission to execute but not to read.", 3, \
+ 19, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Tests/RunCMake/find_program/ExeNoRead.cmake b/Tests/RunCMake/find_program/CMP0109-Common.cmake
index 7e22dc5..525413a 100644
--- a/Tests/RunCMake/find_program/ExeNoRead.cmake
+++ b/Tests/RunCMake/find_program/CMP0109-Common.cmake
@@ -1,4 +1,7 @@
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead" "#!/bin/sh\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ReadNoExe" "#ReadNoExe")
execute_process(COMMAND chmod -r+x "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead")
find_program(ExeNoRead_EXECUTABLE NAMES ExeNoRead NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
message(STATUS "ExeNoRead_EXECUTABLE='${ExeNoRead_EXECUTABLE}'")
+find_program(ReadNoExe_EXECUTABLE NAMES ReadNoExe NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "ReadNoExe_EXECUTABLE='${ReadNoExe_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
new file mode 100644
index 0000000..2744463
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-NEW-build/ExeNoRead'
+-- ReadNoExe_EXECUTABLE='ReadNoExe_EXECUTABLE-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW.cmake b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
new file mode 100644
index 0000000..b4a4033
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 NEW)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
new file mode 100644
index 0000000..1a0e2a8
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-OLD-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD.cmake b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
new file mode 100644
index 0000000..8260161
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 OLD)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
new file mode 100644
index 0000000..202fc6d
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
@@ -0,0 +1,29 @@
+^CMake Warning \(dev\) at CMP0109-Common.cmake:4 \(find_program\):
+ Policy CMP0109 is not set: find_program\(\) requires permission to execute
+ but not to read. Run "cmake --help-policy CMP0109" for policy details.
+ Use the cmake_policy command to set the policy and suppress this warning.
+
+ The file
+
+ .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ExeNoRead
+
+ is executable but not readable. CMake is ignoring it for compatibility.
+Call Stack \(most recent call first\):
+ CMP0109-WARN.cmake:1 \(include\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0109-Common.cmake:6 \(find_program\):
+ Policy CMP0109 is not set: find_program\(\) requires permission to execute
+ but not to read. Run "cmake --help-policy CMP0109" for policy details.
+ Use the cmake_policy command to set the policy and suppress this warning.
+
+ The file
+
+ .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe
+
+ is readable but not executable. CMake is using it for compatibility.
+Call Stack \(most recent call first\):
+ CMP0109-WARN.cmake:1 \(include\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
new file mode 100644
index 0000000..baf560f
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN.cmake b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
new file mode 100644
index 0000000..a3d59af
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/ExeNoRead-stdout.txt b/Tests/RunCMake/find_program/ExeNoRead-stdout.txt
deleted file mode 100644
index f231178..0000000
--- a/Tests/RunCMake/find_program/ExeNoRead-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
--- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
index 0a732ee..3e23920 100644
--- a/Tests/RunCMake/find_program/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -17,7 +17,9 @@ else()
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT "${uid}" STREQUAL "0")
- run_cmake(ExeNoRead)
+ run_cmake(CMP0109-WARN)
+ run_cmake(CMP0109-OLD)
+ run_cmake(CMP0109-NEW)
endif()
endif()