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
This commit is contained in:
commit
6194193a8a
@ -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>)
|
||||
|
||||
|
@ -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
|
||||
=================================
|
||||
|
||||
|
20
Help/policy/CMP0152.rst
Normal file
20
Help/policy/CMP0152.rst
Normal file
@ -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
|
@ -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}")
|
||||
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}")
|
||||
# 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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) \
|
||||
|
5
Tests/RunCMake/CMP0152/CMP0152-Common.cmake
Normal file
5
Tests/RunCMake/CMP0152/CMP0152-Common.cmake
Normal file
@ -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)
|
0
Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt
Normal file
0
Tests/RunCMake/CMP0152/CMP0152-NEW-stdout.txt
Normal file
2
Tests/RunCMake/CMP0152/CMP0152-NEW.cmake
Normal file
2
Tests/RunCMake/CMP0152/CMP0152-NEW.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
cmake_policy(SET CMP0152 NEW)
|
||||
include(CMP0152-Common.cmake)
|
0
Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt
Normal file
0
Tests/RunCMake/CMP0152/CMP0152-OLD-stderr.txt
Normal file
2
Tests/RunCMake/CMP0152/CMP0152-OLD.cmake
Normal file
2
Tests/RunCMake/CMP0152/CMP0152-OLD.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
cmake_policy(SET CMP0152 OLD)
|
||||
include(CMP0152-Common.cmake)
|
27
Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt
Normal file
27
Tests/RunCMake/CMP0152/CMP0152-WARN-stderr.txt
Normal file
@ -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\.$
|
2
Tests/RunCMake/CMP0152/CMP0152-WARN.cmake
Normal file
2
Tests/RunCMake/CMP0152/CMP0152-WARN.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
include(CMP0152-Common.cmake)
|
3
Tests/RunCMake/CMP0152/CMakeLists.txt
Normal file
3
Tests/RunCMake/CMP0152/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
7
Tests/RunCMake/CMP0152/RunCMakeTest.cmake
Normal file
7
Tests/RunCMake/CMP0152/RunCMakeTest.cmake
Normal file
@ -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()
|
@ -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.
|
||||
|
@ -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()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user