diff options
author | Brad King <brad.king@kitware.com> | 2023-07-24 12:43:15 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2023-07-24 12:43:19 (GMT) |
commit | 6194193a8a0a476539590aabbb27094d1aff136a (patch) | |
tree | 7b56eea1985a37978b58b64c35c53bf4c682d571 | |
parent | e61a51b5a247bec564cb48184b499d17386c0470 (diff) | |
parent | 6b5f2dbbfe453f9bafe46ee420e657735ff16fb0 (diff) | |
download | CMake-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.rst | 5 | ||||
-rw-r--r-- | Help/manual/cmake-policies.7.rst | 8 | ||||
-rw-r--r-- | Help/policy/CMP0152.rst | 20 | ||||
-rw-r--r-- | Modules/FindCUDAToolkit.cmake | 15 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 56 | ||||
-rw-r--r-- | Source/cmPolicies.h | 6 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMP0152-Common.cmake | 5 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt | 0 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMP0152-NEW.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt | 0 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMP0152-OLD.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt | 27 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMP0152-WARN.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0152/RunCMakeTest.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/file/REAL_PATH.cmake | 37 |
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() |