summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-07-24 12:43:15 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-07-24 12:43:19 (GMT)
commit6194193a8a0a476539590aabbb27094d1aff136a (patch)
tree7b56eea1985a37978b58b64c35c53bf4c682d571
parente61a51b5a247bec564cb48184b499d17386c0470 (diff)
parent6b5f2dbbfe453f9bafe46ee420e657735ff16fb0 (diff)
downloadCMake-6194193a8a0a476539590aabbb27094d1aff136a.zip
CMake-6194193a8a0a476539590aabbb27094d1aff136a.tar.gz
CMake-6194193a8a0a476539590aabbb27094d1aff136a.tar.bz2
Merge topic 'file-REAL_PATH-relative'
6b5f2dbbfe file(REAL_PATH): resolve symlinks before '..' components Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !8605
-rw-r--r--Help/command/file.rst5
-rw-r--r--Help/manual/cmake-policies.7.rst8
-rw-r--r--Help/policy/CMP0152.rst20
-rw-r--r--Modules/FindCUDAToolkit.cmake15
-rw-r--r--Source/cmFileCommand.cxx56
-rw-r--r--Source/cmPolicies.h6
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-Common.cmake5
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt0
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-NEW.cmake2
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt0
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt27
-rw-r--r--Tests/RunCMake/CMP0152/CMP0152-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0152/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0152/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/file/REAL_PATH.cmake37
17 files changed, 189 insertions, 10 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 30a7f4d..f9d1a79 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -981,6 +981,11 @@ Path Conversion
if ``USERPROFILE`` is not defined. On all other platforms, only ``HOME``
is used.
+ .. versionchanged:: 3.28
+
+ All symlinks are resolved before collapsing ``../`` components.
+ See policy :policy:`CMP0152`.
+
.. signature::
file(RELATIVE_PATH <variable> <directory> <file>)
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 7c48806..89b7924 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
+Policies Introduced by CMake 3.28
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0152: file(REAL_PATH) resolves symlinks before collapsing ../ components. </policy/CMP0152>
+
Policies Introduced by CMake 3.27
=================================
diff --git a/Help/policy/CMP0152.rst b/Help/policy/CMP0152.rst
new file mode 100644
index 0000000..d7e8692
--- /dev/null
+++ b/Help/policy/CMP0152.rst
@@ -0,0 +1,20 @@
+CMP0152
+-------
+
+.. versionadded:: 3.28
+
+:command:`file(REAL_PATH)` resolves symlinks before collapsing ../ components.
+
+In CMake 3.27 and below, :command:`file(REAL_PATH)` collapsed any ``../``
+components in a path before resolving symlinks. This produced incorrect
+results when the ``../`` collapsed away a symlink.
+
+The ``OLD`` behavior for this policy is to collapse ``../`` components before
+resolving symlinks.
+The ``NEW`` behavior for this policy is to resolve all symlinks before
+collapsing ``../`` components.
+
+This policy was introduced in CMake version 3.28. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index c2627e7..e9b7ae4 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -965,12 +965,15 @@ if(CUDAToolkit_FOUND)
# search paths without symlinks
if(CUDAToolkit_LIBRARY_DIR MATCHES ".*/cuda/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64$")
# Search location for math_libs/
- file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../" _cmake_search_dir)
- list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
-
- # Search location for extras like cupti
- file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../" _cmake_search_dir)
- list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
+ block(SCOPE_FOR POLICIES)
+ cmake_policy(SET CMP0152 NEW)
+ file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../../../" _cmake_search_dir)
+ list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
+
+ # Search location for extras like cupti
+ file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../" _cmake_search_dir)
+ list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
+ endblock()
endif()
# If no `CUDAToolkit_LIBRARY_ROOT` exists set it based on CUDAToolkit_LIBRARY_DIR
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index def09fe..f4fbf75 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -30,6 +30,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
+#include "cmCMakePath.h"
#include "cmCryptoHash.h"
#include "cmELF.h"
#include "cmExecutionStatus.h"
@@ -1278,9 +1279,58 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
}
}
- auto realPath =
- cmSystemTools::CollapseFullPath(input, *arguments.BaseDirectory);
- realPath = cmSystemTools::GetRealPath(realPath);
+ bool warnAbout152 = false;
+ bool use152New = true;
+ cmPolicies::PolicyStatus policyStatus =
+ status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0152);
+ switch (policyStatus) {
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ break;
+ case cmPolicies::WARN:
+ use152New = false;
+ warnAbout152 = true;
+ break;
+ case cmPolicies::OLD:
+ use152New = false;
+ warnAbout152 = false;
+ break;
+ }
+
+ auto computeNewPath = [=](std::string const& in, std::string& result) {
+ auto path = cmCMakePath{ in };
+ if (path.IsRelative()) {
+ auto basePath = cmCMakePath{ *arguments.BaseDirectory };
+ path = basePath.Append(path);
+ }
+ result = cmSystemTools::GetActualCaseForPath(
+ cmSystemTools::GetRealPath(path.String()));
+ };
+
+ std::string realPath;
+ if (use152New) {
+ computeNewPath(input, realPath);
+ } else {
+ std::string oldPolicyPath =
+ cmSystemTools::CollapseFullPath(input, *arguments.BaseDirectory);
+ oldPolicyPath = cmSystemTools::GetRealPath(oldPolicyPath);
+ if (warnAbout152) {
+ computeNewPath(input, realPath);
+ if (oldPolicyPath != realPath) {
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0152), '\n',
+ "From input path:\n ", input,
+ "\nthe policy OLD behavior produces path:\n ", oldPolicyPath,
+ "\nbut the policy NEW behavior produces path:\n ", realPath,
+ "\nSince the policy is not set, CMake is using the OLD "
+ "behavior for compatibility."));
+ }
+ }
+ realPath = oldPolicyPath;
+ }
status.GetMakefile().AddDefinition(args[2], realPath);
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a0030d3..25af6a8 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -459,7 +459,11 @@ class cmMakefile;
SELECT(POLICY, CMP0151, \
"AUTOMOC include directory is a system include directory by " \
"default.", \
- 3, 27, 0, cmPolicies::WARN)
+ 3, 27, 0, cmPolicies::WARN) \
+ SELECT( \
+ POLICY, CMP0152, \
+ "file(REAL_PATH) resolves symlinks before collapsing ../ components.", 3, \
+ 28, 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/CMP0152/CMP0152-Common.cmake b/Tests/RunCMake/CMP0152/CMP0152-Common.cmake
new file mode 100644
index 0000000..6429cca
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-Common.cmake
@@ -0,0 +1,5 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin/")
+file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin" "${CMAKE_CURRENT_BINARY_DIR}/dir/bin" SYMBOLIC)
+file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../" real_path)
diff --git a/Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt b/Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt
diff --git a/Tests/RunCMake/CMP0152/CMP0152-NEW.cmake b/Tests/RunCMake/CMP0152/CMP0152-NEW.cmake
new file mode 100644
index 0000000..86a3b55
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0152 NEW)
+include(CMP0152-Common.cmake)
diff --git a/Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt b/Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt
diff --git a/Tests/RunCMake/CMP0152/CMP0152-OLD.cmake b/Tests/RunCMake/CMP0152/CMP0152-OLD.cmake
new file mode 100644
index 0000000..62ac300
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0152 OLD)
+include(CMP0152-Common.cmake)
diff --git a/Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt b/Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt
new file mode 100644
index 0000000..8d63168
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt
@@ -0,0 +1,27 @@
+^CMake Warning \(dev\) at CMP0152-Common\.cmake:[0-9]+ \(file\):
+ Policy CMP0152 is not set: file\(REAL_PATH\) resolves symlinks before
+ collapsing \.\./ components\. Run "cmake --help-policy CMP0152" for policy
+ details\. Use the cmake_policy command to set the policy and suppress this
+ warning\.
+
+ From input path:
+
+ [^
+]*/Tests/RunCMake/CMP0152/CMP0152-WARN-build/dir/bin/\.\./
+
+ the policy OLD behavior produces path:
+
+ [^
+]*/Tests/RunCMake/CMP0152/CMP0152-WARN-build/dir
+
+ but the policy NEW behavior produces path:
+
+ [^
+]*/Tests/RunCMake/CMP0152/CMP0152-WARN-build/dir/nested
+
+ Since the policy is not set, CMake is using the OLD behavior for
+ compatibility.
+Call Stack \(most recent call first\):
+ CMP0152-WARN\.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers\. Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/CMP0152/CMP0152-WARN.cmake b/Tests/RunCMake/CMP0152/CMP0152-WARN.cmake
new file mode 100644
index 0000000..e85589e
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMP0152-WARN.cmake
@@ -0,0 +1,2 @@
+
+include(CMP0152-Common.cmake)
diff --git a/Tests/RunCMake/CMP0152/CMakeLists.txt b/Tests/RunCMake/CMP0152/CMakeLists.txt
new file mode 100644
index 0000000..5ff8d3e
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.23)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0152/RunCMakeTest.cmake b/Tests/RunCMake/CMP0152/RunCMakeTest.cmake
new file mode 100644
index 0000000..7a9bab3
--- /dev/null
+++ b/Tests/RunCMake/CMP0152/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+if(NOT CMAKE_GENERATOR_NO_COMPILER_ENV)
+ run_cmake(CMP0152-WARN)
+ run_cmake(CMP0152-OLD)
+ run_cmake(CMP0152-NEW)
+endif()
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index b278cef..608a4d9 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -165,6 +165,10 @@ if(GIT_EXECUTABLE)
add_RunCMake_test(CMP0150)
endif()
+if(NOT WIN32 OR CYGWIN)
+ add_RunCMake_test(CMP0152)
+endif()
+
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
# generators ignore. The policy will have no effect on those generators.
diff --git a/Tests/RunCMake/file/REAL_PATH.cmake b/Tests/RunCMake/file/REAL_PATH.cmake
index 9c5d4ea..08d400d 100644
--- a/Tests/RunCMake/file/REAL_PATH.cmake
+++ b/Tests/RunCMake/file/REAL_PATH.cmake
@@ -13,6 +13,43 @@ if (NOT WIN32 OR CYGWIN)
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(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/")
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/")
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin/")
+ file(CREATE_LINK "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin" "${CMAKE_CURRENT_BINARY_DIR}/dir/bin" SYMBOLIC)
+
+ cmake_policy(SET CMP0152 NEW)
+ file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../" real_path)
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested\"")
+ endif()
+
+ file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../bin" real_path)
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin\"")
+ endif()
+
+ file(REAL_PATH "dir/bin/../bin" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin\"")
+ endif()
+
+ file(REAL_PATH "../bin" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/" )
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested/bin\"")
+ endif()
+
+ cmake_policy(SET CMP0152 OLD)
+ file(REAL_PATH "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/../" real_path)
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir/nested\"")
+ endif()
+ file(REAL_PATH "../" real_path BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dir/bin/")
+ if (NOT real_path STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/dir")
+ message(SEND_ERROR "real path is \"${real_path}\", should be \"${CMAKE_CURRENT_BINARY_DIR}/dir\"")
+ endif()
+
endif()