71 Commits
Author SHA1 Message Date
Marc Chevrier d4dc18c01b if() command: add RULE operator 2026-09-21 18:10:48 +02:00
Mickaël Germain 7192a2b798 cmake_path: An empty path is not a prefix of any path
cmake_path(IS_PREFIX) and $<PATH:IS_PREFIX> treated an empty path as a
prefix of every path, including another empty path, following
std::filesystem::path.  A prefix that is empty because a variable was
set to an empty value, or because a generator expression argument
expanded to nothing, therefore satisfied a check meant to reject it.

Return false for an empty prefix, in cmCMakePath::IsPrefix so that every
caller shares one implementation and both the plain and NORMALIZE forms
are covered.  Normalizing an empty path leaves it empty, so no separate
handling of NORMALIZE is needed.  Unlike the component comparison, which
follows std::filesystem::path deliberately, IsPrefix has no counterpart
in the standard: it borrows path iteration but the predicate itself is
defined by CMake, so an empty prefix is a gap to fill rather than a
standard answer to override.

Add policy CMP0223 and restore the old result behind it at the two
released surfaces.  The other callers of IsPrefix, source_group() and
the Makefile generator's source classification, take the new behavior
ungated: source_group() rejects an empty TREE argument before reaching
it, and the generator passes the source and binary directories.

The if(PATH_IS_PREFIX) operator, new in this same release, follows the
policy too rather than simply taking the new behavior, so that it agrees
with cmake_path(IS_PREFIX) in every policy state and the parity
assertions in its test hold unconditionally.

Fixes: #28077
2026-09-17 10:05:27 -04:00
Brad King 34bbc91e3b Merge topic 'if-PATH_IS_PREFIX'
860583ceac if: Add PATH_IS_PREFIX operator
3d53f7901b Tests: Cover cmake_path(IS_PREFIX) path semantics
59a096f73b Tests: Detect a malformed genex in the PATH:IS_PREFIX test

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !12427
2026-09-11 09:11:02 -04:00
Mickaël Germain 860583ceac if: Add PATH_IS_PREFIX operator
Testing whether one path is a prefix of another is possible today with
cmake_path(IS_PREFIX), but the idiom needs a separate statement plus a
scratch variable and takes the prefix as a variable name, so projects
reach for if(path MATCHES "^${prefix}") instead.  That is wrong whenever
the prefix contains a regex metacharacter, and it accepts siblings,
because '^/a/b' matches '/a/bc'.

Add a binary operator where the left operand is the candidate prefix and
the right is the path, matching the operand order of cmake_path(IS_PREFIX)
and $<PATH:IS_PREFIX> so that the same operation reads the same way on all
three surfaces.  Neither operand is normalized, matching the default of
cmake_path(IS_PREFIX) and the existing PATH_EQUAL operator, so '.' and
'..' are compared as ordinary components.  The test is non-strict, purely
lexical, and applies no relative-to-absolute reconciliation.

Add policy CMP0222 for compatibility, modeled on CMP0139.  The keyword
is consumed as an operator only when it appears in the second argument
slot, so a variable named PATH_IS_PREFIX keeps working in unary and
left-operand position.  What the policy covers is such a variable
appearing after another token, as in if(NOT PATH_IS_PREFIX AND other),
which becomes a configure error under NEW.

Since the operator is an if() spelling of cmake_path(IS_PREFIX) and shares
its implementation, test it by asserting the two agree over a corpus of
inputs rather than by restating expected values.  Those are pinned by the
cmake_path(IS_PREFIX) test, so the operator's tests stay limited to what
has no command equivalent, and no platform branching is needed because
parity holds whatever the host path model answers.

Fixes: #28040
2026-09-10 07:09:47 -04:00
Tyler Yankee 7350b58c16 Help: Move regex specification to cmake-language(7)
Many other places in CMake beyond the `string` command rely on our
regex syntax, so it should be documented in a more general location.

Fixes: #22270
2026-09-07 10:17:42 -04:00
Matthew Woehlke 597c573d7d if: Add DIAGNOSTIC <category> condition
Add an existence check to the `if` command for diagnostic categories,
mirroring the check for policies. Aside from being desirable for
consistency's sake, this will make it easier for users to write logic to
manipulate diagnostics from newer versions of CMake that don't exist
today.
2026-06-16 15:14:13 -04:00
Arha Gatram 2bc862bc76 Help: Document if() behavior with empty condition
Closes: #26527
2026-05-26 19:50:17 -04:00
Tyler Yankee 6ff2057b93 Help/if: Improve formatting
Consolidate the description of precedence during evaluation. Use xrefs
to improve syntax highlighting. Remove an outdated `versionadded`
directive for CMake 2.6.
2026-04-03 09:36:04 -04:00
Tyler Yankee c575d84555 Help: Use signature directive for cmake_path command
Using `signature` renders the anchor links for each sub-command, and is
consistent with the other `Help/command` pages which contain multiple
sub-commands.
2025-10-08 20:44:38 -04:00
Alexander Grund 2adfa8b0d4 Help: Fix version added for CMAKE_MATCH_<n>
This was added in 2.6.0 by commit c1b3484c2d (ENH: store the matches for
paren-delimited subexpression..., 2007-08-21, v2.6.0~1227), not in 3.9.

Only the documentation at this place was added in 3.9, by commit
eb08e1febb (Help: Document CMAKE_MATCH_<n> variables, 2017-04-18,
v3.9.0-rc1~257^2)
2025-09-11 13:09:18 -04:00
Alex Turbov bc4c71627a Help: Fix typos found by the rst-backticks hook
The corresponding `pre-commit` configuration is coming in the
separate MR.

Signed-off-by: Alex Turbov <i.zaufi@gmail.com>
2025-01-27 01:43:26 +04:00
Brad King 90d814f024 CMP0054: Remove support for OLD behavior 2025-01-20 09:46:55 -05:00
scivision 3530eef3fb Help: Clarify that if(PATH_EQUAL) does not access the filesystem
Fixes: #26421
2024-11-19 12:01:03 -05:00
Aleksei Shpakovskii 2c0d16df7b Help/command/if: fix formatting in precedence order overview
Due to extra space symbols, it was rendered as definition list inside
list item, instead of plain list item.
2024-08-27 14:07:58 +02:00
Aleksei Shpakovskii 2e634501fd Help/command/if: list all condition operators in precedence order overview
This section is near the top and so can serve as an exhaustive
table of contents for the things that `if()` can check.
2024-08-22 11:31:12 -04:00
Brad King e4a359e5d4 Help/command/if: Document variable expansion by IN_LIST
Previously this behavior was only mentioned implicitly by the command
signature.  Describe it explicitly as we do for other conditions that
automatically expand variables.

Fixes: #26234
2024-08-21 09:17:21 -04:00
Craig Scott eceb368ccc Help: Fix typos in 3.29 docs 2024-03-19 21:47:28 +11:00
Brad King 2ce6337503 Help: Reword if(EXISTS) suggestion to prefer if(IS_READABLE) 2024-02-06 09:29:11 -05:00
Marc Chevrier 337bc5662c if(): add operators IS_READABLE, IS_WRITABLE and IS_EXECUTABLE.
Offers possibility to check for file or directory permissions.
2023-11-01 14:53:31 +01:00
Brad King 5924a1f0eb Help: Document if() comparison number format
Fixes: #25237
2023-09-08 10:26:34 -04:00
Brad King 3ab132d86f Help: Document that if(EXISTS) requires paths to be readable
Issue: #25125
2023-07-26 11:06:53 -04:00
Brad King 3600be4e31 Help: Use signature directive for 'if' command 2023-03-07 13:38:39 -05:00
Brad King bedd62d52c Help: Improve sentence structure around "if so" 2023-03-07 13:38:29 -05:00
Brad King ae7c4a5ff4 Help: Add internal cross-references to 'if' command docs 2023-03-07 08:50:31 -05:00
Brad King 95bfacb8bb Help: Indent 'if' command docs more consistently 2023-03-07 08:50:31 -05:00
scivision a1dc38a567 Help: Document behavior of if(EXISTS,IS_DIRECTORY) for empty paths
Document and add explicit tests for empty string input:
`if(EXISTS "")` and `if(IS_DIRECTORY "")` are always false.
This avoids need for users to do extra checks due to
CMake non-short-circuit logic as below:

    if("${p}")
      if(EXISTS "${p}")
2023-01-24 14:13:52 -05:00
Alex Turbov cc8837606c Help: Unindent _See Also_ related commands list
To make it similar to other commands.
2022-11-07 22:55:06 +04:00
Brad King 41597025f9 Merge topic 'doc-if-PATH_EQUAL'
37e01773e4 Help: Clarify behavior of path-based equality conditions

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !7503
2022-07-26 09:22:29 -04:00
Craig Scott 37e01773e4 Help: Clarify behavior of path-based equality conditions
The docs for if(PATH_EQUAL) did not mention the component-wise
nature of the checks. It also claimed no normalization was
performed, but multiple separators are effectively collapsed
(part of normalization). Improve the wording to clarify both of
these points.

Also update the corresponding description of cmake_path(COMPARE),
which had the same inaccuracy.

Fixes: #23758
2022-07-24 16:03:20 +10:00
Markus Ferrell 033c066543 Help: Add see-also refs for flow control commands 2022-07-19 13:06:25 -04:00
Marc Chevrier be4b9e10af if command: Add PATH_EQUAL operator 2022-06-03 19:31:36 +02:00
Joachim Wuttke (h) a693da21f3 Help: from command:if, link to environment variables 2022-05-05 09:37:20 -04:00
Brad King 41adfc6b04 Help: Clarify precedence of AND and OR in 'if' conditions
The wording update in commit b74819e4fe (Help: Format 'if' command
documentation, 2013-12-18, v3.0.0-rc1~227^2~1) incorrectly implied that
`AND` has higher precedence than `OR`.  Although this is common in many
languages, it has never been true in CMake's implementation.  Revise
the wording to clarify the precedence.

Add a test case demonstrating the order.

Fixes: #23207
2022-02-09 14:24:43 -05:00
Craig Scott 6b170578b8 Help: Non-zero floating point numbers are true in if() expressions
Fixes: #22991
2022-01-04 08:45:23 +11:00
Craig Scott a45e922768 Help: Clarify behavior of if(DEFINED) for cache and non-cache variables
Fixes: #23023
2021-12-20 19:27:39 +11:00
Craig Scott 294581a443 Help: Be more explicit about the behavior of if(<string>) 2021-12-01 18:59:23 +11:00
Craig Scott 3a9695557d Help: Explicitly state that if(ENV{some_var}) is always false 2021-12-01 18:30:26 +11:00
Johel Ernesto Guerrero Peña c6a6c008f4 Help: Fix terminology for regular expression in if(MATCHES)
This was wrongly changed in commit ba90611225 (Help: Make synopsis of
if command more compact; add section headers, 2018-10-05).
2021-08-28 13:58:25 +10:00
Craig Scott 6234afdff4 Help: Document special cases for if(IS_ABSOLUTE)
The meaning of "absolute path" was previously assumed knowledge,
but a number of special cases were left unspecified. The way some of
these are handled differs to the way that cmake_path(IS_ABSOLUTE)
works, so document those special cases so that the differing behavior
between these two commands is clearly defined.
2021-04-17 19:41:53 +10:00
Michael Hirsch, Ph.D 22140f7af3 Help: Add internal links to if() docs 2021-02-18 10:20:34 -05:00
Michael Hirsch, Ph.D e63e83d2b8 Help: Document that if(EXISTS) does not expand ~
Fixes: #21729
2021-01-26 09:50:01 -05:00
Shannon Booth 55ba98556f Help: Add sections to if() conditions documentation 2021-01-09 10:03:46 +13:00
Nikita Nemkin a19058d7d8 Help: Replace some versionadded directives with versionchanged
`.. versionchanged` directive might be more appropriate when
documentation refers to previous CMake version, old behavior
or a policy, and there's no new parameter or a variable involved.

Issue: #19715
2020-11-12 09:44:01 +05:00
Nikita Nemkin c705279bae Help: Add .. versionadded directives to commands documentation
This change ony concerns directives that appear in the document body.

The guidelines for inserting version directives:

 * Baseline version is CMake 3.0, i.e. directives start at 3.1.
 * Always use `.. versionadded::` directive, avoid ad-hoc version
   references. Exception: policy pages.
 * For new command signatures, put `versionadded` on a separate line
   after the signature.
 * For a group of new signatures in a new document section,
   a single version note at the beginning of the section is sufficient.
 * For new options, put `versionadded` on a separate line before
   option description.
 * If all the option descriptions in the list are short one-liners,
   it's fine to put `versionadded` on the same line as the description.
 * If multiple option descriptions in close proximity would have
   the same ..versionadded directive, consider adding a single
   directive after the list, mentioning all added options.
 * For compact value lists and sub-option lists, put a single
  `versionadded` directive after the list mentioning all additions.
 * When a change is described in a single paragraph, put
   `versionadded` into that paragraph.
 * When only part of the paragraph has changed, separate the changed
   part if it doesn't break the flow. Otherwise, write a follow-up
   clarification paragraph and apply version directive to that.
 * When multiple version directives are close by, order earlier
   additions before later additions.
 * Indent related lists and code blocks to include them in the scope
   of `versionadded` directive.

Issue: #19715
2020-11-09 20:51:57 +05:00
Hong Xu d192caefff CMakeDependentOption: Document that 4th parameter follows if-syntax 2019-08-05 10:15:21 -04:00
Brad King 8c28e63cb4 Merge topic 'if-EXISTS-doc'
78ac8cb04a Help: clarify if(EXISTS) operation for symlinks

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3189
2019-04-04 12:51:41 -04:00
Bartosz Kosiorek 456e0fb64f Help: Improve documentation formating 2019-04-04 15:13:58 +02:00
Shoaib Meenai 78ac8cb04a Help: clarify if(EXISTS) operation for symlinks
if(EXISTS) resolves symlinks; note this explicitly in its documentation.
2019-04-03 17:25:52 -07:00
Juuso "Linda" Lapinlampi 572b4fd85b Help: Fix elseif/endif typo
In CMake 3.13.x, we had this evaluation for if() conditions:

    if(a) elseif(b) else(a) endif(a)

The sensible intention of the change in commit c2efb3efcd (Help: Revise
docs on Scripting Commands, 2018-10-16, v3.14.0-rc1~505^2) was:

> "endif", "endfunction" etc: Explain that the argument is optional and
> maintained for compatibility only

Instead of "endif", it ended up being written to the documentation as
"elseif" by the commit author (oops) to if()'s page.

    if(a) elseif(a!?) else() endif(a?)

Truthfully, endif()'s parameter should be an optional verbatim repeat
and not elseif()'s. If it wasn't, elseif() would be described to be the
same as if(). The rightful intended description is:

    if(a) elseif(b) else() endif()

Fix that typo.
2019-02-11 14:41:51 -05:00
Robert Maynard 1222f02e34 If: Support the 'DEFINED CACHE{}' syntax 2018-11-09 10:38:07 -05:00