cmake_path¶
New in version 3.19.
Filesystem path manipulation command.
This command is dedicated to the manipulation of objects of type path which represent paths on a filesystem. Only syntactic aspects of paths are handled: the pathname may represent a non-existing path or even one that is not allowed to exist on the current file system or OS.
For operations involving the filesystem, have a look at the file()
command.
The path name has the following syntax:
root-name(optional): identifies the root on a filesystem with multiple roots (such as"C:"or"//myserver").root-directory(optional): a directory separator that, if present, marks this path as absolute. If it is missing (and the first element other than theroot-nameis aitem-name), then the path is relative.
Zero or more of the following:
item-name: sequence of characters that aren’t directory separators. This name may identify a file, a hard link, a symbolic link, or a directory. Two specialitem-namesare recognized:dot: the item name consisting of a single dot character.is a directory name that refers to the current directory.dot-dot: the item name consisting of two dot characters..is a directory name that refers to the parent directory.
directory-separator: the forward slash character/. If this character is repeated, it is treated as a single directory separator:/usr///////libis the same as/usr/lib.
A path has a filename if it does not ends with a directory-separator. The
filename is the last item-name of the path.
A filename can have an extension. By default, the
extension is defined as the sub-string beginning at the leftmost period
(including the period) and until the end of the pathname. When the option
LAST_ONLY is specified, the extension is the sub-string beginning at the
rightmost period.
The following exceptions apply:
If the first character in the filename is a period, that period is ignored (a filename like
".profile"is not treated as an extension).If the pathname is either
.or...
Note
cmake_path command handles paths in the format of the build system, not
the target system. So this is not generally applicable to the target system
in cross-compiling environment.
For all commands, <path> placeholder expect a variable name. An error will
be raised if the variable does not exist, except for APPEND and
CMAKE_PATH sub-commands. <input> placeholder expect a string literal.
[<input>...] placeholder expect zero or more arguments. <output>
placeholder expect a variable name.
Note
cmake_path command does not support list of paths. The <path>
placeholder must store only one path name.
To initialize a path variable, three possibilities can be used:
set()command.cmake_path(APPEND) command. Can be used to build a path from already available path fragments.
cmake_path(CMAKE_PATH) command. Mainly used to build a path variable from a native path.
# To build the path "${CMAKE_CURRENT_SOURCE_DIR}/data" set (path1 "${CMAKE_CURRENT_SOURCE_DIR}/data") cmake_path(APPEND path2 "${CMAKE_CURRENT_SOURCE_DIR}" "data") cmake_path(CMAKE_PATH path3 "${CMAKE_CURRENT_SOURCE_DIR}/data")
Modification and Generation sub-commands store the result in-place or in
the variable specified by OUTPUT_VARIABLE option. All other sub-commands,
except CMAKE_PATH, store the result in the required <output> variable.
Sub-commands supporting NORMALIZE option will normalize
the path.
Synopsis¶
Decomposition cmake_path(GET <path> ROOT_NAME <output>) cmake_path(GET <path> ROOT_DIRECTORY <output>) cmake_path(GET <path> ROOT_PATH <output>) cmake_path(GET <path> FILENAME <output>) cmake_path(GET <path> EXTENSION [LAST_ONLY] <output>) cmake_path(GET <path> STEM [LAST_ONLY] <output>) cmake_path(GET <path> RELATIVE_PATH <output>) cmake_path(GET <path> PARENT_PATH <output>) Modification cmake_path(APPEND <path> [<input>...] [OUTPUT_VARIABLE <output>]) cmake_path(CONCAT <path> [<input>...] [OUTPUT_VARIABLE <output>]) cmake_path(REMOVE_FILENAME <path> [OUTPUT_VARIABLE <output>]) cmake_path(REPLACE_FILENAME <path> <input> [OUTPUT_VARIABLE <output>]) cmake_path(REMOVE_EXTENSION <path> [LAST_ONLY] [OUTPUT_VARIABLE <output>]) cmake_path(REPLACE_EXTENSION <path> [LAST_ONLY] <input> [OUTPUT_VARIABLE <output>]) Generation cmake_path(NORMAL_PATH <path> [OUTPUT_VARIABLE <output>]) cmake_path(RELATIVE_PATH <path> [BASE_DIRECTORY <path>] [OUTPUT_VARIABLE <output>]) cmake_path(PROXIMATE_PATH <path> [BASE_DIRECTORY <path>] [OUTPUT_VARIABLE <output>]) cmake_path(ABSOLUTE_PATH <path> [BASE_DIRECTORY <path>] [NORMALIZE] [OUTPUT_VARIABLE <output>]) Conversion cmake_path(CMAKE_PATH <path> [NORMALIZE] <input>) cmake_path(NATIVE_PATH <path> [NORMALIZE] <output>) cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <output>) cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <output>) Comparison cmake_path(COMPARE <path> <OP> <input> <output>) Query cmake_path(HAS_ROOT_NAME <path> <output>) cmake_path(HAS_ROOT_DIRECTORY <path> <output>) cmake_path(HAS_ROOT_PATH <path> <output>) cmake_path(HAS_FILENAME <path> <output>) cmake_path(HAS_EXTENSION <path> <output>) cmake_path(HAS_STEM <path> <output>) cmake_path(HAS_RELATIVE_PATH <path> <output>) cmake_path(HAS_PARENT_PATH <path> <output>) cmake_path(IS_ABSOLUTE <path> <output>) cmake_path(IS_RELATIVE <path> <output>) cmake_path(IS_PREFIX <path> <input> [NORMALIZE] <output>) Hashing cmake_path(HASH <path> [NORMALIZE] <output>)
Decomposition¶
cmake_path(GET <path> ROOT_NAME <output>)
Returns the root name of the path. If the path does not include a root name, returns an empty path.
Note
Only Windows system has the concept of root-name, so on all other
systems, it is always an empty path.
For example:
set (path "c:/a") cmake_path (GET path ROOT_NAME output) message ("Root name is \"${output}\"")Will display:
Root name is "c:"
cmake_path(GET <path> ROOT_DIRECTORY <output>)
Returns the root directory of the path. If the path does not include a root directory, returns an empty path.
For example:
set (path "c:/a") cmake_path (GET path ROOT_DIRECTORY output) message ("Root directory is \"${output}\"")Will display:
Root directory is "/"
cmake_path(GET <path> ROOT_PATH <output>)
Returns the root path of the path. If the path does not include a root path, returns an empty path.
Effectively, returns the following: root-name root-directory.
For example:
set (path "c:/a") cmake_path (GET path ROOT_PATH output) message ("Root path is \"${output}\"")Will display:
Root path is "c:/"
cmake_path(GET <path> FILENAME <output>)
Returns the filename component of the path. If the path
ends with a directory-separator, there is no filename, so returns an empty
path.
For example:
set (path "/a") cmake_path (GET path FILENAME output) message ("First filename is \"${output}\"") set (path "/a/") cmake_path (GET path FILENAME output) message ("Second filename is \"${output}\"")Will display:
First filename is "a" Second filename is ""
cmake_path(GET <path> EXTENSION [LAST_ONLY] <output>)
Returns the extension of the filename component.
If the filename component of the path contains a period
(.), and is not one of the special filesystem elements dot or
dot-dot, then the extension is returned.
For example:
set (path "name.ext1.ext2") cmake_path (GET path EXTENSION result) message ("Full extension is \"${result}\"") cmake_path (GET path EXTENSION LAST_ONLY result) message ("Last extension is \"${result}\"")Will display:
Full extension is ".ext1.ext2" Last extension is ".ext2"
The following exceptions apply:
If the first character in the filename is a period, that period is ignored (a filename like
".profile"is not treated as an extension).If the pathname is either
.or.., or if filename component does not contain the.character, then an empty path is returned.
cmake_path(GET <path> STEM [LAST_ONLY] <output>)
Returns the filename component of the path stripped of its extension.
For Example:
set (path "name.ext1.ext2") cmake_path (GET path STEM result) message ("Filename without the extension is \"${result}\"") cmake_path (GET path STEM LAST_ONLY result) message ("Filename whiteout the last extension is \"${result}\"")Will display:
Filename without the extension is "name" Filename without the last extension is "name.ext1"
The following exceptions apply:
If the first character in the filename is a period, that period is ignored (a filename like
".profile"is not treated as an extension).If the filename is one of the special filesystem components
dotordot-dot, or if it has no periods, the function returns the entire filename component.
cmake_path(GET <path> RELATIVE_PATH <output>)
Returns path relative to root-path, that is, a pathname composed of
every component of <path> after root-path. If <path> is an empty
path, returns an empty path.
For Example:
set (path "/a/b") cmake_path (GET path RELATIVE_PATH result) message ("Relative path is \"${result}\"") set (path "/") cmake_path (GET path RELATIVE_PATH result) message ("Relative path is \"${result}\"")Will display:
Relative path is "a/b" Relative path is ""
cmake_path(GET <path> PARENT_PATH <output>)
Returns the path to the parent directory.
If HAS_RELATIVE_PATH sub-command returns false, the result is a copy of
<path>. Otherwise, the result is <path> with one fewer element.
For Example:
set (path "c:/a/b") cmake_path (GET path PARENT_PATH result) message ("Parent path is \"${result}\"") set (path "c:/") cmake_path (GET path PARENT_PATH result) message ("Parent path is \"${result}\"")Will display:
Parent path is "c:/a" Relative path is "c:/"
Modification¶
cmake_path(APPEND <path> [<input>...] [OUTPUT_VARIABLE <output>])
Append all the <input> arguments to the <path> using / as
directory-separator.
For each <input> argument, the following algorithm (pseudo-code) applies:
IF (<input>.is_absolute() OR (<input>.has_root_name() AND NOT <input>.root_name() STREQUAL <path>.root_name())) replaces <path> with <input> RETURN() ENDIF() IF (<input>.has_root_directory()) remove any root-directory and the entire relative path from <path> ELSEIF (<path>.has_filename() OR (NOT <path>.has_root_directory() OR <path>.is_absolute())) appends directory-separator to <path> ENDIF() appends <input> omitting any root-name to <path>
cmake_path(CONCAT <path> [<input>...] [OUTPUT_VARIABLE <output>])
Concatenates all the <input> arguments to the <path> without
directory-separator.
cmake_path(REMOVE_FILENAME <path> [OUTPUT_VARIABLE <output>])
Removes the filename component (as returned by
GET … FILENAME) from <path>.
After this function returns, if change is done in-place, HAS_FILENAME
returns false for <path>.
For Example:
set (path "/a/b") cmake_path (REMOVE_FILENAME path) message ("First path is \"${path}\"") cmake_path (REMOVE_FILENAME path) message ("Second path is \"${result}\"")Will display:
First path is "/a/" Second path is "/a/"
cmake_path(REPLACE_FILENAME <path> <input> [OUTPUT_VARIABLE <output>])
Replaces the filename component from <path> with
<input>.
If <path> has no filename component (HAS_FILENAME returns false), the
path is unchanged.
Equivalent to the following:
cmake_path(HAS_FILENAME path has_filename) if (has_filename) cmake_path(REMOVE_FILENAME path) cmake_path(APPEND path "replacement"); endif()
cmake_path(REMOVE_EXTENSION <path> [LAST_ONLY] [OUTPUT_VARIABLE <output>])
Removes the extension, if any, from <path>.
cmake_path(REPLACE_EXTENSION <path> [LAST_ONLY] <input>
[OUTPUT_VARIABLE <output>])
Replaces the extension with <input>.
If
<path>has an extension (HAS_EXTENSION is true), it is removed.A
dotcharacter is appended to<path>, if<input>is not empty or does not begin with adotcharacter.
<input>is appended as if CONCAT was used.
Equivalent to the following:
cmake_path(REMOVE_EXTENSION path) if (NOT "input" MATCHES "^\\.") cmake_path(CONCAT path ".") endif() cmake_path(CONCAT path "input");
Generation¶
cmake_path(NORMAL_PATH <path> [OUTPUT_VARIABLE <output>])
Normalize <path>.
A path can be normalized by following this algorithm:
If the path is empty, stop (normal form of an empty path is an empty path).
Replace each
directory-separator(which may consist of multiple separators) with a single/.Replace each
directory-separatorcharacter in theroot-namewith/.Remove each
dotand any immediately followingdirectory-separator.Remove each non-dot-dot filename immediately followed by a
directory-separatorand adot-dot, along with any immediately followingdirectory-separator.If there is
root-directory, remove alldot-dotsand anydirectory-separatorsimmediately following them.If the last filename is
dot-dot, remove any trailingdirectory-separator.If the path is empty, add a
dot(normal form of./is.).
cmake_path(RELATIVE_PATH <path> [BASE_DIRECTORY <path>]
[OUTPUT_VARIABLE <output>])
Returns <path> made relative to BASE_DIRECTORY argument. If
BASE_DIRECTORY is not specified, the default base directory will be
CMAKE_CURRENT_SOURCE_DIR.
For reference, the algorithm used to compute the relative path is described here.
cmake_path(PROXIMATE_PATH <path> [BASE_DIRECTORY <path>]
[OUTPUT_VARIABLE <output>])
If the value of RELATIVE_PATH is not an empty path, return
it. Otherwise return <path>.
If BASE_DIRECTORY is not specified, the default base directory will be
CMAKE_CURRENT_SOURCE_DIR.
cmake_path(ABSOLUTE_PATH <path> [BASE_DIRECTORY <path>] [NORMALIZE]
[OUTPUT_VARIABLE <output>])
If <path> is a relative path (IS_RELATIVE is true), it is evaluated
relative to the given base directory specified by BASE_DIRECTORY option.
If BASE_DIRECTORY is not specifired, the default base directory will be
CMAKE_CURRENT_SOURCE_DIR.
When NORMALIZE option is specified, the path is normalized after the path computation.
Because cmake_path does not access to the filesystem, symbolic links are
not resolved. To compute a real path, use file(REAL_PATH)
command.
Conversion¶
cmake_path(CMAKE_PATH <path> [NORMALIZE] <input>)
Converts a native <input> path into cmake-style path with forward-slashes
(/). On Windows, the long filename marker is taken into account.
When NORMALIZE option is specified, the path is normalized before the conversion.
For Example:
set (native_path "c:\\a\\b/..\\c") cmake_path (CMAKE_PATH path "${native_path}") message ("CMake path is \"${path}\"") cmake_path (CMAKE_PATH path NORMALIZE "${native_path}") message ("Normalized CMake path is \"${path}\"")Will display:
CMake path is "c:/a/b/../c" Normalized CMake path is "c:/a/c"
cmake_path(NATIVE_PATH <path> [NORMALIZE] <output>)
Converts a cmake-style <path> into a native
path with platform-specific slashes (\ on Windows and / elsewhere).
When NORMALIZE option is specified, the path is normalized before the conversion.
cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <output> [NORMALIZE])
Converts a native <input> path into cmake-style path with forward-slashes
(/). On Windows, the long filename marker is taken into account. The input can
be a single path or a system search path like $ENV{PATH}. A search path
will be converted to a cmake-style list separated by ; characters. The
result of the conversion is stored in the <output> variable.
When NORMALIZE option is specified, the path is normalized before the conversion.
cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <output> [NORMALIZE])
Converts a cmake-style <input> path into a native path with
platform-specific slashes (\ on Windows and / elsewhere). The input can
be a single path or a cmake-style list. A list will be converted into a native
search path. The result of the conversion is stored in the <output>
variable.
When NORMALIZE option is specified, the path is normalized before the conversion.
For Example:
set (paths "/a/b/c" "/x/y/z") cmake_path (CONVERT "${paths}" TO_NATIVE_PATH_LIST native_paths) message ("Native path list is \"${native_paths}\"")Will display, on Windows:
Native path list is "\a\b\c;\x\y\z"And on the all other systems:
Native path list is "/a/b/c:/x/y/z"
Comparison¶
cmake_path(COMPARE <path> EQUAL <input> <output>)
cmake_path(COMPARE <path> NOT_EQUAL <input> <output>)
Compares the lexical representations of the path and another path.
For testing equality, the following algorithm (pseudo-code) apply:
IF (NOT <path>.root_name() STREQUAL <input>.root_name()) returns FALSE ELSEIF (<path>.has_root_directory() XOR <input>.has_root_directory()) returns FALSE ENDIF() returns TRUE or FALSE if the relative portion of <path> is lexicographically equal or not to the relative portion of <input>. Comparison is performed path component-wise
Query¶
cmake_path(HAS_ROOT_NAME <path> <output>)
Checks if <path> has root-name.
cmake_path(HAS_ROOT_DIRECTORY <path> <output>)
Checks if <path> has root-directory.
cmake_path(HAS_ROOT_PATH <path> <output>)
Checks if <path> has root path.
Effectively, checks if <path> has root-name and root-directory.
cmake_path(HAS_FILENAME <path> <output>)
Checks if <path> has a filename.
cmake_path(HAS_EXTENSION <path> <output>)
Checks if <path> has an extension. If the first
character in the filename is a period, it is not treated as an extension (for
example “.profile”).
cmake_path(HAS_STEM <path> <output>)
Checks if <path> has stem (GET … STEM returns a non
empty path).
cmake_path(HAS_RELATIVE_PATH <path> <output>)
Checks if <path> has relative path (GET_RELATIVE_PATH returns a
non-empty path).
cmake_path(HAS_PARENT_PATH <path> <output>)
Checks if <path> has parent path. The result is true except if the path is
only composed of a filename.
cmake_path(IS_ABSOLUTE <path> <output>)
Checks if <path> is absolute.
An absolute path is a path that unambiguously identifies the location of a file without reference to an additional starting location.
cmake_path(IS_RELATIVE <path> <output>)
Checks if path is relative (i.e. not absolute).
cmake_path(IS_PREFIX <path> <input> [NORMALIZE] <output>)
Checks if <path> is the prefix of <input>.
When NORMALIZE option is specified, the paths are normalized before the check.
Hashing¶
cmake_path(HASH <path> [NORMALIZE] <output>)
Compute hash value of <path> such that if for two paths (p1 and p2)
are equal (COMPARE … EQUAL) then hash value of p1 is equal
to hash value of p2.
When NORMALIZE option is specified, the paths are normalized before the check.