1cmake_path 2---------- 3 4.. versionadded:: 3.20 5 6This command is for the manipulation of paths. Only syntactic aspects of 7paths are handled, there is no interaction of any kind with any underlying 8file system. The path may represent a non-existing path or even one that 9is not allowed to exist on the current file system or platform. 10For operations that do interact with the filesystem, see the :command:`file` 11command. 12 13.. note:: 14 15 The ``cmake_path`` command handles paths in the format of the build system 16 (i.e. the host platform), not the target system. When cross-compiling, 17 if the path contains elements that are not representable on the host 18 platform (e.g. a drive letter when the host is not Windows), the results 19 will be unpredictable. 20 21Synopsis 22^^^^^^^^ 23 24.. parsed-literal:: 25 26 `Conventions`_ 27 28 `Path Structure And Terminology`_ 29 30 `Normalization`_ 31 32 `Decomposition`_ 33 cmake_path(`GET`_ <path-var> :ref:`ROOT_NAME <GET_ROOT_NAME>` <out-var>) 34 cmake_path(`GET`_ <path-var> :ref:`ROOT_DIRECTORY <GET_ROOT_DIRECTORY>` <out-var>) 35 cmake_path(`GET`_ <path-var> :ref:`ROOT_PATH <GET_ROOT_PATH>` <out-var>) 36 cmake_path(`GET`_ <path-var> :ref:`FILENAME <GET_FILENAME>` <out-var>) 37 cmake_path(`GET`_ <path-var> :ref:`EXTENSION <GET_EXTENSION>` [LAST_ONLY] <out-var>) 38 cmake_path(`GET`_ <path-var> :ref:`STEM <GET_STEM>` [LAST_ONLY] <out-var>) 39 cmake_path(`GET`_ <path-var> :ref:`RELATIVE_PART <GET_RELATIVE_PART>` <out-var>) 40 cmake_path(`GET`_ <path-var> :ref:`PARENT_PATH <GET_PARENT_PATH>` <out-var>) 41 42 `Query`_ 43 cmake_path(`HAS_ROOT_NAME`_ <path-var> <out-var>) 44 cmake_path(`HAS_ROOT_DIRECTORY`_ <path-var> <out-var>) 45 cmake_path(`HAS_ROOT_PATH`_ <path-var> <out-var>) 46 cmake_path(`HAS_FILENAME`_ <path-var> <out-var>) 47 cmake_path(`HAS_EXTENSION`_ <path-var> <out-var>) 48 cmake_path(`HAS_STEM`_ <path-var> <out-var>) 49 cmake_path(`HAS_RELATIVE_PART`_ <path-var> <out-var>) 50 cmake_path(`HAS_PARENT_PATH`_ <path-var> <out-var>) 51 cmake_path(`IS_ABSOLUTE`_ <path-var> <out-var>) 52 cmake_path(`IS_RELATIVE`_ <path-var> <out-var>) 53 cmake_path(`IS_PREFIX`_ <path-var> <input> [NORMALIZE] <out-var>) 54 cmake_path(`COMPARE`_ <input1> <OP> <input2> <out-var>) 55 56 `Modification`_ 57 cmake_path(:ref:`SET <cmake_path-SET>` <path-var> [NORMALIZE] <input>) 58 cmake_path(`APPEND`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) 59 cmake_path(`APPEND_STRING`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) 60 cmake_path(`REMOVE_FILENAME`_ <path-var> [OUTPUT_VARIABLE <out-var>]) 61 cmake_path(`REPLACE_FILENAME`_ <path-var> <input> [OUTPUT_VARIABLE <out-var>]) 62 cmake_path(`REMOVE_EXTENSION`_ <path-var> [LAST_ONLY] [OUTPUT_VARIABLE <out-var>]) 63 cmake_path(`REPLACE_EXTENSION`_ <path-var> [LAST_ONLY] <input> [OUTPUT_VARIABLE <out-var>]) 64 65 `Generation`_ 66 cmake_path(`NORMAL_PATH`_ <path-var> [OUTPUT_VARIABLE <out-var>]) 67 cmake_path(`RELATIVE_PATH`_ <path-var> [BASE_DIRECTORY <input>] [OUTPUT_VARIABLE <out-var>]) 68 cmake_path(`ABSOLUTE_PATH`_ <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] [OUTPUT_VARIABLE <out-var>]) 69 70 `Native Conversion`_ 71 cmake_path(`NATIVE_PATH`_ <path-var> [NORMALIZE] <out-var>) 72 cmake_path(`CONVERT`_ <input> `TO_CMAKE_PATH_LIST`_ <out-var> [NORMALIZE]) 73 cmake_path(`CONVERT`_ <input> `TO_NATIVE_PATH_LIST`_ <out-var> [NORMALIZE]) 74 75 `Hashing`_ 76 cmake_path(`HASH`_ <path-var> <out-var>) 77 78Conventions 79^^^^^^^^^^^ 80 81The following conventions are used in this command's documentation: 82 83``<path-var>`` 84 Always the name of a variable. For commands that expect a ``<path-var>`` 85 as input, the variable must exist and it is expected to hold a single path. 86 87``<input>`` 88 A string literal which may contain a path, path fragment, or multiple paths 89 with a special separator depending on the command. See the description of 90 each command to see how this is interpreted. 91 92``<input>...`` 93 Zero or more string literal arguments. 94 95``<out-var>`` 96 The name of a variable into which the result of a command will be written. 97 98 99Path Structure And Terminology 100^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 101 102A path has the following structure (all components are optional, with some 103constraints): 104 105:: 106 107 root-name root-directory-separator (item-name directory-separator)* filename 108 109``root-name`` 110 Identifies the root on a filesystem with multiple roots (such as ``"C:"`` 111 or ``"//myserver"``). It is optional. 112 113``root-directory-separator`` 114 A directory separator that, if present, indicates that this path is 115 absolute. If it is missing and the first element other than the 116 ``root-name`` is an ``item-name``, then the path is relative. 117 118``item-name`` 119 A sequence of characters that aren't directory separators. This name may 120 identify a file, a hard link, a symbolic link, or a directory. Two special 121 cases are recognized: 122 123 * The item name consisting of a single dot character ``.`` is a 124 directory name that refers to the current directory. 125 126 * The item name consisting of two dot characters ``..`` is a 127 directory name that refers to the parent directory. 128 129 The ``(...)*`` pattern shown above is to indicate that there can be zero 130 or more item names, with multiple items separated by a 131 ``directory-separator``. The ``()*`` characters are not part of the path. 132 133``directory-separator`` 134 The only recognized directory separator is a forward slash character ``/``. 135 If this character is repeated, it is treated as a single directory 136 separator. In other words, ``/usr///////lib`` is the same as ``/usr/lib``. 137 138.. _FILENAME_DEF: 139.. _EXTENSION_DEF: 140.. _STEM_DEF: 141 142``filename`` 143 A path has a ``filename`` if it does not end with a ``directory-separator``. 144 The ``filename`` is effectively the last ``item-name`` of the path, so it 145 can also be a hard link, symbolic link or a directory. 146 147 A ``filename`` can have an *extension*. By default, the extension is 148 defined as the sub-string beginning at the left-most period (including 149 the period) and until the end of the ``filename``. In commands that 150 accept a ``LAST_ONLY`` keyword, ``LAST_ONLY`` changes the interpretation 151 to the sub-string beginning at the right-most period. 152 153 The following exceptions apply to the above interpretation: 154 155 * If the first character in the ``filename`` is a period, that period is 156 ignored (i.e. a ``filename`` like ``".profile"`` is treated as having 157 no extension). 158 159 * If the ``filename`` is either ``.`` or ``..``, it has no extension. 160 161 The *stem* is the part of the ``filename`` before the extension. 162 163Some commands refer to a ``root-path``. This is the concatenation of 164``root-name`` and ``root-directory-separator``, either or both of which can 165be empty. A ``relative-part`` refers to the full path with any ``root-path`` 166removed. 167 168 169Creating A Path Variable 170^^^^^^^^^^^^^^^^^^^^^^^^ 171 172While a path can be created with care using an ordinary :command:`set` 173command, it is recommended to use :ref:`cmake_path(SET) <cmake_path-SET>` 174instead, as it automatically converts the path to the required form where 175required. The :ref:`cmake_path(APPEND) <APPEND>` subcommand may 176be another suitable alternative where a path needs to be constructed by 177joining fragments. The following example compares the three methods for 178constructing the same path: 179 180.. code-block:: cmake 181 182 set(path1 "${CMAKE_CURRENT_SOURCE_DIR}/data") 183 184 cmake_path(SET path2 "${CMAKE_CURRENT_SOURCE_DIR}/data") 185 186 cmake_path(APPEND path3 "${CMAKE_CURRENT_SOURCE_DIR}" "data") 187 188`Modification`_ and `Generation`_ sub-commands can either store the result 189in-place, or in a separate variable named after an ``OUTPUT_VARIABLE`` 190keyword. All other sub-commands store the result in a mandatory ``<out-var>`` 191variable. 192 193.. _Normalization: 194 195Normalization 196^^^^^^^^^^^^^ 197 198Some sub-commands support *normalizing* a path. The algorithm used to 199normalize a path is as follows: 200 2011. If the path is empty, stop (the normalized form of an empty path is 202 also an empty path). 2032. Replace each ``directory-separator``, which may consist of multiple 204 separators, with a single ``/`` (``/a///b --> /a/b``). 2053. Remove each solitary period (``.``) and any immediately following 206 ``directory-separator`` (``/a/./b/. --> /a/b``). 2074. Remove each ``item-name`` (other than ``..``) that is immediately 208 followed by a ``directory-separator`` and a ``..``, along with any 209 immediately following ``directory-separator`` (``/a/b/../c --> a/c``). 2105. If there is a ``root-directory``, remove any ``..`` and any 211 ``directory-separators`` immediately following them. The parent of the 212 root directory is treated as still the root directory (``/../a --> /a``). 2136. If the last ``item-name`` is ``..``, remove any trailing 214 ``directory-separator`` (``../ --> ..``). 2157. If the path is empty by this stage, add a ``dot`` (normal form of ``./`` 216 is ``.``). 217 218 219Decomposition 220^^^^^^^^^^^^^ 221 222.. _GET: 223.. _GET_ROOT_NAME: 224.. _GET_ROOT_DIRECTORY: 225.. _GET_ROOT_PATH: 226.. _GET_FILENAME: 227.. _GET_EXTENSION: 228.. _GET_STEM: 229.. _GET_RELATIVE_PART: 230.. _GET_PARENT_PATH: 231 232The following forms of the ``GET`` subcommand each retrieve a different 233component or group of components from a path. See 234`Path Structure And Terminology`_ for the meaning of each path component. 235 236:: 237 238 cmake_path(GET <path-var> ROOT_NAME <out-var>) 239 cmake_path(GET <path-var> ROOT_DIRECTORY <out-var>) 240 cmake_path(GET <path-var> ROOT_PATH <out-var>) 241 cmake_path(GET <path-var> FILENAME <out-var>) 242 cmake_path(GET <path-var> EXTENSION [LAST_ONLY] <out-var>) 243 cmake_path(GET <path-var> STEM [LAST_ONLY] <out-var>) 244 cmake_path(GET <path-var> RELATIVE_PART <out-var>) 245 cmake_path(GET <path-var> PARENT_PATH <out-var>) 246 247If a requested component is not present in the path, an empty string will be 248stored in ``<out-var>``. For example, only Windows systems have the concept 249of a ``root-name``, so when the host machine is non-Windows, the ``ROOT_NAME`` 250subcommand will always return an empty string. 251 252For ``PARENT_PATH``, if the `HAS_RELATIVE_PART`_ subcommand returns false, 253the result is a copy of ``<path-var>``. Note that this implies that a root 254directory is considered to have a parent, with that parent being itself. 255Where `HAS_RELATIVE_PART`_ returns true, the result will essentially be 256``<path-var>`` with one less element. 257 258Root examples 259""""""""""""" 260 261.. code-block:: cmake 262 263 set(path "c:/a") 264 265 cmake_path(GET path ROOT_NAME rootName) 266 cmake_path(GET path ROOT_DIRECTORY rootDir) 267 cmake_path(GET path ROOT_PATH rootPath) 268 269 message("Root name is \"${rootName}\"") 270 message("Root directory is \"${rootDir}\"") 271 message("Root path is \"${rootPath}\"") 272 273:: 274 275 Root name is "c:" 276 Root directory is "/" 277 Root path is "c:/" 278 279Filename examples 280""""""""""""""""" 281 282.. code-block:: cmake 283 284 set(path "/a/b") 285 cmake_path(GET path FILENAME filename) 286 message("First filename is \"${filename}\"") 287 288 # Trailing slash means filename is empty 289 set(path "/a/b/") 290 cmake_path(GET path FILENAME filename) 291 message("Second filename is \"${filename}\"") 292 293:: 294 295 First filename is "b" 296 Second filename is "" 297 298Extension and stem examples 299""""""""""""""""""""""""""" 300 301.. code-block:: cmake 302 303 set(path "name.ext1.ext2") 304 305 cmake_path(GET path EXTENSION fullExt) 306 cmake_path(GET path STEM fullStem) 307 message("Full extension is \"${fullExt}\"") 308 message("Full stem is \"${fullStem}\"") 309 310 # Effect of LAST_ONLY 311 cmake_path(GET path EXTENSION LAST_ONLY lastExt) 312 cmake_path(GET path STEM LAST_ONLY lastStem) 313 message("Last extension is \"${lastExt}\"") 314 message("Last stem is \"${lastStem}\"") 315 316 # Special cases 317 set(dotPath "/a/.") 318 set(dotDotPath "/a/..") 319 set(someMorePath "/a/.some.more") 320 cmake_path(GET dotPath EXTENSION dotExt) 321 cmake_path(GET dotPath STEM dotStem) 322 cmake_path(GET dotDotPath EXTENSION dotDotExt) 323 cmake_path(GET dotDotPath STEM dotDotStem) 324 cmake_path(GET dotMorePath EXTENSION someMoreExt) 325 cmake_path(GET dotMorePath STEM someMoreStem) 326 message("Dot extension is \"${dotExt}\"") 327 message("Dot stem is \"${dotStem}\"") 328 message("Dot-dot extension is \"${dotDotExt}\"") 329 message("Dot-dot stem is \"${dotDotStem}\"") 330 message(".some.more extension is \"${someMoreExt}\"") 331 message(".some.more stem is \"${someMoreStem}\"") 332 333:: 334 335 Full extension is ".ext1.ext2" 336 Full stem is "name" 337 Last extension is ".ext2" 338 Last stem is "name.ext1" 339 Dot extension is "" 340 Dot stem is "." 341 Dot-dot extension is "" 342 Dot-dot stem is ".." 343 .some.more extension is ".more" 344 .some.more stem is ".some" 345 346Relative part examples 347"""""""""""""""""""""" 348 349.. code-block:: cmake 350 351 set(path "c:/a/b") 352 cmake_path(GET path RELATIVE_PART result) 353 message("Relative part is \"${result}\"") 354 355 set(path "c/d") 356 cmake_path(GET path RELATIVE_PART result) 357 message("Relative part is \"${result}\"") 358 359 set(path "/") 360 cmake_path(GET path RELATIVE_PART result) 361 message("Relative part is \"${result}\"") 362 363:: 364 365 Relative part is "a/b" 366 Relative part is "c/d" 367 Relative part is "" 368 369Path traversal examples 370""""""""""""""""""""""" 371 372.. code-block:: cmake 373 374 set(path "c:/a/b") 375 cmake_path(GET path PARENT_PATH result) 376 message("Parent path is \"${result}\"") 377 378 set(path "c:/") 379 cmake_path(GET path PARENT_PATH result) 380 message("Parent path is \"${result}\"") 381 382:: 383 384 Parent path is "c:/a" 385 Parent path is "c:/" 386 387 388Query 389^^^^^ 390 391Each of the ``GET`` subcommands has a corresponding ``HAS_...`` 392subcommand which can be used to discover whether a particular path 393component is present. See `Path Structure And Terminology`_ for the 394meaning of each path component. 395 396.. _HAS_ROOT_NAME: 397.. _HAS_ROOT_DIRECTORY: 398.. _HAS_ROOT_PATH: 399.. _HAS_FILENAME: 400.. _HAS_EXTENSION: 401.. _HAS_STEM: 402.. _HAS_RELATIVE_PART: 403.. _HAS_PARENT_PATH: 404 405:: 406 407 cmake_path(HAS_ROOT_NAME <path-var> <out-var>) 408 cmake_path(HAS_ROOT_DIRECTORY <path-var> <out-var>) 409 cmake_path(HAS_ROOT_PATH <path-var> <out-var>) 410 cmake_path(HAS_FILENAME <path-var> <out-var>) 411 cmake_path(HAS_EXTENSION <path-var> <out-var>) 412 cmake_path(HAS_STEM <path-var> <out-var>) 413 cmake_path(HAS_RELATIVE_PART <path-var> <out-var>) 414 cmake_path(HAS_PARENT_PATH <path-var> <out-var>) 415 416Each of the above follows the predictable pattern of setting ``<out-var>`` 417to true if the path has the associated component, or false otherwise. 418Note the following special cases: 419 420* For ``HAS_ROOT_PATH``, a true result will only be returned if at least one 421 of ``root-name`` or ``root-directory`` is non-empty. 422 423* For ``HAS_PARENT_PATH``, the root directory is also considered to have a 424 parent, which will be itself. The result is true except if the path 425 consists of just a :ref:`filename <FILENAME_DEF>`. 426 427.. _IS_ABSOLUTE: 428 429:: 430 431 cmake_path(IS_ABSOLUTE <path-var> <out-var>) 432 433Sets ``<out-var>`` to true if ``<path-var>`` is absolute. An absolute path 434is a path that unambiguously identifies the location of a file without 435reference to an additional starting location. On Windows, this means the 436path must have both a ``root-name`` and a ``root-directory-separator`` to be 437considered absolute. On other platforms, just a ``root-directory-separator`` 438is sufficient. Note that this means on Windows, ``IS_ABSOLUTE`` can be 439false while ``HAS_ROOT_DIRECTORY`` can be true. 440 441.. _IS_RELATIVE: 442 443:: 444 445 cmake_path(IS_RELATIVE <path-var> <out-var>) 446 447This will store the opposite of ``IS_ABSOLUTE`` in ``<out-var>``. 448 449.. _IS_PREFIX: 450 451:: 452 453 cmake_path(IS_PREFIX <path-var> <input> [NORMALIZE] <out-var>) 454 455Checks if ``<path-var>`` is the prefix of ``<input>``. 456 457When the ``NORMALIZE`` option is specified, ``<path-var>`` and ``<input>`` 458are :ref:`normalized <Normalization>` before the check. 459 460.. code-block:: cmake 461 462 set(path "/a/b/c") 463 cmake_path(IS_PREFIX path "/a/b/c/d" result) # result = true 464 cmake_path(IS_PREFIX path "/a/b" result) # result = false 465 cmake_path(IS_PREFIX path "/x/y/z" result) # result = false 466 467 set(path "/a/b") 468 cmake_path(IS_PREFIX path "/a/c/../b" NORMALIZE result) # result = true 469 470.. _COMPARE: 471 472:: 473 474 cmake_path(COMPARE <input1> EQUAL <input2> <out-var>) 475 cmake_path(COMPARE <input1> NOT_EQUAL <input2> <out-var>) 476 477Compares the lexical representations of two paths provided as string literals. 478No normalization is performed on either path. Equality is determined 479according to the following pseudo-code logic: 480 481:: 482 483 if(NOT <input1>.root_name() STREQUAL <input2>.root_name()) 484 return FALSE 485 486 if(<input1>.has_root_directory() XOR <input2>.has_root_directory()) 487 return FALSE 488 489 Return FALSE if a relative portion of <input1> is not lexicographically 490 equal to the relative portion of <input2>. This comparison is performed path 491 component-wise. If all of the components compare equal, then return TRUE. 492 493.. note:: 494 Unlike most other ``cmake_path()`` subcommands, the ``COMPARE`` subcommand 495 takes literal strings as input, not the names of variables. 496 497 498Modification 499^^^^^^^^^^^^ 500 501.. _cmake_path-SET: 502 503:: 504 505 cmake_path(SET <path-var> [NORMALIZE] <input>) 506 507Assign the ``<input>`` path to ``<path-var>``. If ``<input>`` is a native 508path, it is converted into a cmake-style path with forward-slashes 509(``/``). On Windows, the long filename marker is taken into account. 510 511When the ``NORMALIZE`` option is specified, the path is :ref:`normalized 512<Normalization>` before the conversion. 513 514For example: 515 516.. code-block:: cmake 517 518 set(native_path "c:\\a\\b/..\\c") 519 cmake_path(SET path "${native_path}") 520 message("CMake path is \"${path}\"") 521 522 cmake_path(SET path NORMALIZE "${native_path}") 523 message("Normalized CMake path is \"${path}\"") 524 525Output:: 526 527 CMake path is "c:/a/b/../c" 528 Normalized CMake path is "c:/a/c" 529 530.. _APPEND: 531 532:: 533 534 cmake_path(APPEND <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) 535 536Append all the ``<input>`` arguments to the ``<path-var>`` using ``/`` as 537the ``directory-separator``. Depending on the ``<input>``, the previous 538contents of ``<path-var>`` may be discarded. For each ``<input>`` argument, 539the following algorithm (pseudo-code) applies: 540 541:: 542 543 # <path> is the contents of <path-var> 544 545 if(<input>.is_absolute() OR 546 (<input>.has_root_name() AND 547 NOT <input>.root_name() STREQUAL <path>.root_name())) 548 replace <path> with <input> 549 return() 550 endif() 551 552 if(<input>.has_root_directory()) 553 remove any root-directory and the entire relative path from <path> 554 elseif(<path>.has_filename() OR 555 (NOT <path-var>.has_root_directory() OR <path>.is_absolute())) 556 append directory-separator to <path> 557 endif() 558 559 append <input> omitting any root-name to <path> 560 561.. _APPEND_STRING: 562 563:: 564 565 cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) 566 567Append all the ``<input>`` arguments to the ``<path-var>`` without adding any 568``directory-separator``. 569 570.. _REMOVE_FILENAME: 571 572:: 573 574 cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>]) 575 576Removes the :ref:`filename <FILENAME_DEF>` component (as returned by 577:ref:`GET ... FILENAME <GET_FILENAME>`) from ``<path-var>``. After removal, 578any trailing ``directory-separator`` is left alone, if present. 579 580If ``OUTPUT_VARIABLE`` is not given, then after this function returns, 581`HAS_FILENAME`_ returns false for ``<path-var>``. 582 583For example: 584 585.. code-block:: cmake 586 587 set(path "/a/b") 588 cmake_path(REMOVE_FILENAME path) 589 message("First path is \"${path}\"") 590 591 # filename is now already empty, the following removes nothing 592 cmake_path(REMOVE_FILENAME path) 593 message("Second path is \"${result}\"") 594 595Output:: 596 597 First path is "/a/" 598 Second path is "/a/" 599 600.. _REPLACE_FILENAME: 601 602:: 603 604 cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>]) 605 606Replaces the :ref:`filename <FILENAME_DEF>` component from ``<path-var>`` 607with ``<input>``. If ``<path-var>`` has no filename component (i.e. 608`HAS_FILENAME`_ returns false), the path is unchanged. The operation is 609equivalent to the following: 610 611.. code-block:: cmake 612 613 cmake_path(HAS_FILENAME path has_filename) 614 if(has_filename) 615 cmake_path(REMOVE_FILENAME path) 616 cmake_path(APPEND path input); 617 endif() 618 619.. _REMOVE_EXTENSION: 620 621:: 622 623 cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY] 624 [OUTPUT_VARIABLE <out-var>]) 625 626Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``. 627 628.. _REPLACE_EXTENSION: 629 630:: 631 632 cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input> 633 [OUTPUT_VARIABLE <out-var>]) 634 635Replaces the :ref:`extension <EXTENSION_DEF>` with ``<input>``. Its effect 636is equivalent to the following: 637 638.. code-block:: cmake 639 640 cmake_path(REMOVE_EXTENSION path) 641 if(NOT "input" MATCHES "^\\.") 642 cmake_path(APPEND_STRING path ".") 643 endif() 644 cmake_path(APPEND_STRING path "input") 645 646 647Generation 648^^^^^^^^^^ 649 650.. _NORMAL_PATH: 651 652:: 653 654 cmake_path(NORMAL_PATH <path-var> [OUTPUT_VARIABLE <out-var>]) 655 656Normalize ``<path-var>`` according the steps described in :ref:`Normalization`. 657 658.. _cmake_path-RELATIVE_PATH: 659.. _RELATIVE_PATH: 660 661:: 662 663 cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>] 664 [OUTPUT_VARIABLE <out-var>]) 665 666Modifies ``<path-var>`` to make it relative to the ``BASE_DIRECTORY`` argument. 667If ``BASE_DIRECTORY`` is not specified, the default base directory will be 668:variable:`CMAKE_CURRENT_SOURCE_DIR`. 669 670For reference, the algorithm used to compute the relative path is the same 671as that used by C++ 672`std::filesystem::path::lexically_relative 673<https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_. 674 675.. _ABSOLUTE_PATH: 676 677:: 678 679 cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] 680 [OUTPUT_VARIABLE <out-var>]) 681 682If ``<path-var>`` is a relative path (`IS_RELATIVE`_ is true), it is evaluated 683relative to the given base directory specified by ``BASE_DIRECTORY`` option. 684If ``BASE_DIRECTORY`` is not specified, the default base directory will be 685:variable:`CMAKE_CURRENT_SOURCE_DIR`. 686 687When the ``NORMALIZE`` option is specified, the path is :ref:`normalized 688<Normalization>` after the path computation. 689 690Because ``cmake_path()`` does not access the filesystem, symbolic links are 691not resolved and any leading tilde is not expanded. To compute a real path 692with symbolic links resolved and leading tildes expanded, use the 693:command:`file(REAL_PATH)` command instead. 694 695Native Conversion 696^^^^^^^^^^^^^^^^^ 697 698For commands in this section, *native* refers to the host platform, not the 699target platform when cross-compiling. 700 701.. _cmake_path-NATIVE_PATH: 702.. _NATIVE_PATH: 703 704:: 705 706 cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>) 707 708Converts a cmake-style ``<path-var>`` into a native path with 709platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere). 710 711When the ``NORMALIZE`` option is specified, the path is :ref:`normalized 712<Normalization>` before the conversion. 713 714.. _CONVERT: 715.. _cmake_path-TO_CMAKE_PATH_LIST: 716.. _TO_CMAKE_PATH_LIST: 717 718:: 719 720 cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <out-var> [NORMALIZE]) 721 722Converts a native ``<input>`` path into a cmake-style path with forward 723slashes (``/``). On Windows hosts, the long filename marker is taken into 724account. The input can be a single path or a system search path like 725``$ENV{PATH}``. A search path will be converted to a cmake-style list 726separated by ``;`` characters (on non-Windows platforms, this essentially 727means ``:`` separators are replaced with ``;``). The result of the 728conversion is stored in the ``<out-var>`` variable. 729 730When the ``NORMALIZE`` option is specified, the path is :ref:`normalized 731<Normalization>` before the conversion. 732 733.. note:: 734 Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand 735 takes a literal string as input, not the name of a variable. 736 737.. _cmake_path-TO_NATIVE_PATH_LIST: 738.. _TO_NATIVE_PATH_LIST: 739 740:: 741 742 cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <out-var> [NORMALIZE]) 743 744Converts a cmake-style ``<input>`` path into a native path with 745platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere). 746The input can be a single path or a cmake-style list. A list will be 747converted into a native search path (``;``-separated on Windows, 748``:``-separated on other platforms). The result of the conversion is 749stored in the ``<out-var>`` variable. 750 751When the ``NORMALIZE`` option is specified, the path is :ref:`normalized 752<Normalization>` before the conversion. 753 754.. note:: 755 Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand 756 takes a literal string as input, not the name of a variable. 757 758For example: 759 760.. code-block:: cmake 761 762 set(paths "/a/b/c" "/x/y/z") 763 cmake_path(CONVERT "${paths}" TO_NATIVE_PATH_LIST native_paths) 764 message("Native path list is \"${native_paths}\"") 765 766Output on Windows:: 767 768 Native path list is "\a\b\c;\x\y\z" 769 770Output on all other platforms:: 771 772 Native path list is "/a/b/c:/x/y/z" 773 774Hashing 775^^^^^^^ 776 777.. _HASH: 778 779:: 780 781 cmake_path(HASH <path-var> <out-var>) 782 783Compute a hash value of ``<path-var>`` such that for two paths ``p1`` and 784``p2`` that compare equal (:ref:`COMPARE ... EQUAL <COMPARE>`), the hash 785value of ``p1`` is equal to the hash value of ``p2``. The path is always 786:ref:`normalized <Normalization>` before the hash is computed. 787