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);
|
||||
}
|
||||
else if (args[2] == "ABSOLUTE")
|
||||
else if (args[2] == "ABSOLUTE" ||
|
||||
args[2] == "REALPATH")
|
||||
{
|
||||
// If the path given is relative evaluate it relative to the
|
||||
// current source directory.
|
||||
|
@ -92,6 +93,11 @@ bool cmGetFilenameComponentCommand
|
|||
|
||||
// Collapse the path to its simplest form.
|
||||
result = cmSystemTools::CollapseFullPath(filename.c_str());
|
||||
if(args[2] == "REALPATH")
|
||||
{
|
||||
// Resolve symlinks if possible
|
||||
result = cmSystemTools::GetRealPath(filename.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -68,11 +68,12 @@ public:
|
|||
{
|
||||
return
|
||||
" get_filename_component(VarName FileName\n"
|
||||
" PATH|ABSOLUTE|NAME|EXT|NAME_WE\n"
|
||||
" PATH|ABSOLUTE|NAME|EXT|NAME_WE|REALPATH\n"
|
||||
" [CACHE])\n"
|
||||
"Set VarName to be the path (PATH), file name (NAME), file "
|
||||
"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 "
|
||||
"trailing slashes. The longest file extension is always considered. "
|
||||
"If the optional CACHE argument is specified, the result variable is "
|
||||
|
|
|
@ -14,6 +14,7 @@ AddCMakeTest(VariableWatch "")
|
|||
AddCMakeTest(Include "")
|
||||
AddCMakeTest(FindBase "")
|
||||
AddCMakeTest(Toolchain "")
|
||||
AddCMakeTest(GetFilenameComponentRealpath "")
|
||||
|
||||
SET(GetPrerequisites_PreArgs
|
||||
"-DCTEST_CONFIGURATION_TYPE:STRING=\\\${CTEST_CONFIGURATION_TYPE}"
|
||||
|
|
|
@ -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…
Reference in New Issue