ENH: Add get_filename_component(... REALPATH)
This patch from Philip Lowman creates a REALPATH mode in the get_filename_component command. It is like ABSOLUTE, but will also resolve symlinks (which ABSOLUTE once did but was broken long ago). See issue #8423.
This commit is contained in:
parent
ca096a4596
commit
ae873d4a89
@ -75,7 +75,8 @@ bool cmGetFilenameComponentCommand
|
|||||||
{
|
{
|
||||||
result = cmSystemTools::GetFilenameWithoutExtension(filename);
|
result = cmSystemTools::GetFilenameWithoutExtension(filename);
|
||||||
}
|
}
|
||||||
else if (args[2] == "ABSOLUTE")
|
else if (args[2] == "ABSOLUTE" ||
|
||||||
|
args[2] == "REALPATH")
|
||||||
{
|
{
|
||||||
// If the path given is relative evaluate it relative to the
|
// If the path given is relative evaluate it relative to the
|
||||||
// current source directory.
|
// current source directory.
|
||||||
@ -92,6 +93,11 @@ bool cmGetFilenameComponentCommand
|
|||||||
|
|
||||||
// Collapse the path to its simplest form.
|
// Collapse the path to its simplest form.
|
||||||
result = cmSystemTools::CollapseFullPath(filename.c_str());
|
result = cmSystemTools::CollapseFullPath(filename.c_str());
|
||||||
|
if(args[2] == "REALPATH")
|
||||||
|
{
|
||||||
|
// Resolve symlinks if possible
|
||||||
|
result = cmSystemTools::GetRealPath(filename.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -68,11 +68,12 @@ public:
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
" get_filename_component(VarName FileName\n"
|
" get_filename_component(VarName FileName\n"
|
||||||
" PATH|ABSOLUTE|NAME|EXT|NAME_WE\n"
|
" PATH|ABSOLUTE|NAME|EXT|NAME_WE|REALPATH\n"
|
||||||
" [CACHE])\n"
|
" [CACHE])\n"
|
||||||
"Set VarName to be the path (PATH), file name (NAME), file "
|
"Set VarName to be the path (PATH), file name (NAME), file "
|
||||||
"extension (EXT), file name without extension (NAME_WE) of FileName, "
|
"extension (EXT), file name without extension (NAME_WE) of FileName, "
|
||||||
"or the full path (ABSOLUTE). "
|
"the full path (ABSOLUTE), or the full path with all symlinks "
|
||||||
|
"resolved (REALPATH). "
|
||||||
"Note that the path is converted to Unix slashes format and has no "
|
"Note that the path is converted to Unix slashes format and has no "
|
||||||
"trailing slashes. The longest file extension is always considered. "
|
"trailing slashes. The longest file extension is always considered. "
|
||||||
"If the optional CACHE argument is specified, the result variable is "
|
"If the optional CACHE argument is specified, the result variable is "
|
||||||
|
@ -14,6 +14,7 @@ AddCMakeTest(VariableWatch "")
|
|||||||
AddCMakeTest(Include "")
|
AddCMakeTest(Include "")
|
||||||
AddCMakeTest(FindBase "")
|
AddCMakeTest(FindBase "")
|
||||||
AddCMakeTest(Toolchain "")
|
AddCMakeTest(Toolchain "")
|
||||||
|
AddCMakeTest(GetFilenameComponentRealpath "")
|
||||||
|
|
||||||
SET(GetPrerequisites_PreArgs
|
SET(GetPrerequisites_PreArgs
|
||||||
"-DCTEST_CONFIGURATION_TYPE:STRING=\\\${CTEST_CONFIGURATION_TYPE}"
|
"-DCTEST_CONFIGURATION_TYPE:STRING=\\\${CTEST_CONFIGURATION_TYPE}"
|
||||||
|
57
Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in
Normal file
57
Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
set(bindir ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test nonexistent REALPATH & ABSOLUTE resolution
|
||||||
|
#
|
||||||
|
get_filename_component(nonexistent1 ${bindir}/THIS_IS_A_NONEXISTENT_FILE REALPATH)
|
||||||
|
get_filename_component(nonexistent2 ${bindir}/THIS_IS_A_NONEXISTENT_FILE ABSOLUTE)
|
||||||
|
if(NOT nonexistent1 STREQUAL "${bindir}/THIS_IS_A_NONEXISTENT_FILE")
|
||||||
|
message(FATAL_ERROR "REALPATH is not preserving nonexistent files")
|
||||||
|
endif()
|
||||||
|
if(NOT nonexistent2 STREQUAL "${bindir}/THIS_IS_A_NONEXISTENT_FILE")
|
||||||
|
message(FATAL_ERROR "ABSOLUTE is not preserving nonexistent files")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test symbolic link resolution
|
||||||
|
#
|
||||||
|
if(UNIX)
|
||||||
|
# file1 => file2 => file3 (real)
|
||||||
|
file(WRITE ${bindir}/file3 "test file")
|
||||||
|
|
||||||
|
find_program(LN NAMES "ln")
|
||||||
|
if(LN)
|
||||||
|
# Create symlinks using "ln -s"
|
||||||
|
if(NOT EXISTS ${bindir}/file2)
|
||||||
|
execute_process(COMMAND ${LN} "-s" "${bindir}/file3" "${bindir}/file2")
|
||||||
|
endif()
|
||||||
|
if(NOT EXISTS ${bindir}/file1)
|
||||||
|
execute_process(COMMAND ${LN} "-s" "${bindir}/file2" "${bindir}/file1")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_filename_component(file1 ${bindir}/file1 REALPATH)
|
||||||
|
get_filename_component(file2 ${bindir}/file2 REALPATH)
|
||||||
|
get_filename_component(file3 ${bindir}/file3 REALPATH)
|
||||||
|
|
||||||
|
if(NOT file3 STREQUAL "${bindir}/file3")
|
||||||
|
message(FATAL_ERROR "CMake fails resolving REALPATH file file3")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT file2 STREQUAL "${bindir}/file3")
|
||||||
|
message(FATAL_ERROR "CMake fails resolving simple symlink")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT file1 STREQUAL "${bindir}/file3")
|
||||||
|
message(FATAL_ERROR "CMake fails resolving double symlink")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
file(REMOVE ${bindir}/file1)
|
||||||
|
file(REMOVE ${bindir}/file2)
|
||||||
|
if(EXISTS file1 OR EXISTS file2)
|
||||||
|
message(FATAL_ERROR "removal of file1 or file2 failed")
|
||||||
|
endif()
|
||||||
|
endif(LN)
|
||||||
|
|
||||||
|
file(REMOVE ${bindir}/file3)
|
||||||
|
endif()
|
Loading…
x
Reference in New Issue
Block a user