From e89ea3d190492e41b37425ff021311c2b471f1b9 Mon Sep 17 00:00:00 2001 From: James Johnston Date: Mon, 17 Aug 2015 23:55:38 -0400 Subject: [PATCH] get_filename_component: Teach new BASE_DIR parameter. In the get_filename_component command, add a new BASE_DIR parameter to use with the ABSOLUTE and REALPATH options. This will be used when finding an absolute path from a relative path. --- Help/command/get_filename_component.rst | 37 ++++++++++++++++--- .../dev/get-filename-component-base-dir.rst | 6 +++ Source/cmGetFilenameComponentCommand.cxx | 20 ++++++++-- .../KnownComponents.cmake | 33 +++++++++++++++++ 4 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 Help/release/dev/get-filename-component-base-dir.rst diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst index 60488dad5..82f912002 100644 --- a/Help/command/get_filename_component.rst +++ b/Help/command/get_filename_component.rst @@ -3,6 +3,8 @@ get_filename_component Get a specific component of a full filename. +------------------------------------------------------------------------------ + :: get_filename_component( [CACHE]) @@ -15,8 +17,6 @@ Set ```` to a component of ````, where ```` is one of: NAME = File name without directory EXT = File name longest extension (.b.c from d/a.b.c) NAME_WE = File name without directory or longest extension - ABSOLUTE = Full path to file - REALPATH = Full path to existing file with symlinks resolved PATH = Legacy alias for DIRECTORY (use for CMake <= 2.8.11) Paths are returned with forward slashes and have no trailing slahes. @@ -24,14 +24,41 @@ The longest file extension is always considered. If the optional ``CACHE`` argument is specified, the result variable is added to the cache. +------------------------------------------------------------------------------ + :: - get_filename_component( FileName + get_filename_component( + [BASE_DIR ] + [CACHE]) + +Set ```` to the absolute path of ````, where ```` is one +of: + +:: + + ABSOLUTE = Full path to file + REALPATH = Full path to existing file with symlinks resolved + +If the provided ```` is a relative path, it is evaluated relative +to the given base directory ````. If no base directory is +provided, the default base directory will be +:variable:`CMAKE_CURRENT_SOURCE_DIR`. + +Paths are returned with forward slashes and have no trailing slahes. If the +optional ``CACHE`` argument is specified, the result variable is added to the +cache. + +------------------------------------------------------------------------------ + +:: + + get_filename_component( PROGRAM [PROGRAM_ARGS ] [CACHE]) -The program in ``FileName`` will be found in the system search path or +The program in ```` will be found in the system search path or left as a full path. If ``PROGRAM_ARGS`` is present with ``PROGRAM``, then -any command-line arguments present in the ``FileName`` string are split +any command-line arguments present in the ```` string are split from the program name and stored in ````. This is used to separate a program name from its arguments in a command line string. diff --git a/Help/release/dev/get-filename-component-base-dir.rst b/Help/release/dev/get-filename-component-base-dir.rst new file mode 100644 index 000000000..c0df759da --- /dev/null +++ b/Help/release/dev/get-filename-component-base-dir.rst @@ -0,0 +1,6 @@ +get-filename-component-base-dir +------------------------------- + +* The :command:`get_filename_component` command learned a new ``BASE_DIR`` + subcommand. This is used to specify a base directory when calculating an + absolute path from a relative path. diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index 13a9afbe7..0f56c8e8f 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -93,11 +93,23 @@ bool cmGetFilenameComponentCommand else if (args[2] == "ABSOLUTE" || args[2] == "REALPATH") { + // If the path given is relative, evaluate it relative to the + // current source directory unless the user passes a different + // base directory. + std::string baseDir = this->Makefile->GetCurrentSourceDirectory(); + for(unsigned int i=3; i < args.size(); ++i) + { + if(args[i] == "BASE_DIR") + { + ++i; + if(i < args.size()) + { + baseDir = args[i]; + } + } + } // Collapse the path to its simplest form. - // If the path given is relative evaluate it relative to the - // current source directory. - result = cmSystemTools::CollapseFullPath( - filename, this->Makefile->GetCurrentSourceDirectory()); + result = cmSystemTools::CollapseFullPath(filename, baseDir); if(args[2] == "REALPATH") { // Resolve symlinks if possible diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake index 386109f56..d82225864 100644 --- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake +++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake @@ -38,6 +38,39 @@ check("ABSOLUTE .. in windows root" "${test_absolute}" "c:/path/to/filename.ext. list(APPEND non_cache_vars test_absolute) +# Test finding absolute paths from various base directories. + +get_filename_component(test_abs_base "testdir1" ABSOLUTE) +check("ABSOLUTE .. from default base" "${test_abs_base}" + "${CMAKE_CURRENT_SOURCE_DIR}/testdir1") + +get_filename_component(test_abs_base "../testdir2" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir") +check("ABSOLUTE .. from dummy base to parent" "${test_abs_base}" + "${CMAKE_CURRENT_SOURCE_DIR}/testdir2") + +get_filename_component(test_abs_base "testdir3" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir") +check("ABSOLUTE .. from dummy base to child" "${test_abs_base}" + "${CMAKE_CURRENT_SOURCE_DIR}/dummydir/testdir3") + +list(APPEND non_cache_vars test_abs_base) + +# Test finding absolute paths with CACHE parameter. (Note that more +# rigorous testing of the CACHE parameter comes later with PROGRAM). + +get_filename_component(test_abs_base_1 "testdir4" ABSOLUTE CACHE) +check("ABSOLUTE CACHE 1" "${test_abs_base_1}" + "${CMAKE_CURRENT_SOURCE_DIR}/testdir4") +list(APPEND cache_vars test_abs_base_1) + +get_filename_component(test_abs_base_2 "testdir5" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir" + CACHE) +check("ABSOLUTE CACHE 2" "${test_abs_base_2}" + "${CMAKE_CURRENT_SOURCE_DIR}/dummydir/testdir5") +list(APPEND cache_vars test_abs_base_2) + # Test the PROGRAM component type. get_filename_component(test_program_name "/ arg1 arg2" PROGRAM) check("PROGRAM with no args output" "${test_program_name}" "/")