if() command: add RULE operator

This commit is contained in:
Marc Chevrier
2026-09-21 18:10:48 +02:00
parent c512ae97ce
commit d4dc18c01b
5 changed files with 45 additions and 2 deletions
+9 -2
View File
@@ -44,8 +44,8 @@ Compound conditions are evaluated in the following order of precedence:
2. Unary tests such as:
* The `Existence Checks`_ :cref:`COMMAND`, :cref:`DEFINED`,
:cref:`DIAGNOSTIC`, :cref:`EXISTS`, :cref:`POLICY`, :cref:`TARGET`, and
:cref:`TEST`.
:cref:`DIAGNOSTIC`, :cref:`EXISTS`, :cref:`POLICY`, :cref:`RULE`,
:cref:`TARGET`, and :cref:`TEST`.
* The `File Operations`_ :cref:`IS_READABLE`, :cref:`IS_WRITABLE`,
:cref:`IS_EXECUTABLE`, :cref:`IS_DIRECTORY`, :cref:`IS_SYMLINK`, and
:cref:`IS_ABSOLUTE`.
@@ -142,6 +142,13 @@ Existence Checks
True if the given name is an existing policy (of the form ``CMP<NNNN>``).
.. signature:: if(RULE <rule-name>)
.. versionadded:: 4.5
True if the given name is an existing rule created by a call to the
:command:`add_custom_rule` command and is visible in the current directory.
.. signature:: if(TARGET <target-name>)
True if the given name is an existing logical target name created
+5
View File
@@ -0,0 +1,5 @@
if-RULE-operator
----------------
* The :command:`if` command gained a ``RULE`` operator to check if a rule
exists.
+7
View File
@@ -53,6 +53,7 @@ auto const keyOR = "OR"_s;
auto const keyParenL = "("_s;
auto const keyParenR = ")"_s;
auto const keyPOLICY = "POLICY"_s;
auto const keyRULE = "RULE"_s;
auto const keySTREQUAL = "STREQUAL"_s;
auto const keySTRGREATER = "STRGREATER"_s;
auto const keySTRGREATER_EQUAL = "STRGREATER_EQUAL"_s;
@@ -515,6 +516,12 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
newArgs.ReduceOneArg(
cmPolicies::GetPolicyID(args.next->GetValue().c_str(), pid), args);
}
// does a rule exist
else if (this->IsKeyword(keyRULE, *args.current)) {
newArgs.ReduceOneArg(
static_cast<bool>(this->Makefile.FindRuleToUse(args.next->GetValue())),
args);
}
// does a target exist
else if (this->IsKeyword(keyTARGET, *args.current)) {
newArgs.ReduceOneArg(static_cast<bool>(this->Makefile.FindTargetToUse(
@@ -0,0 +1,22 @@
enable_language(C)
if(RULE foo)
message(SEND_ERROR "RULE 'foo' unexpectedly found")
endif()
add_custom_rule(foo OUTPUT out COMMAND cmd)
if(NOT RULE foo)
message(SEND_ERROR "RULE 'foo' unexpectedly not found")
endif()
add_library(foo)
add_subdirectory(subdir2)
if(RULE simple)
message(SEND_ERROR "RULE 'simple' from 'subdir2' unexpectedly found")
endif()
add_subdirectory(subdir1)
if(NOT RULE simple)
message(SEND_ERROR "RULE 'simple' from 'subdir1' unexpectedly not found")
endif()
@@ -24,3 +24,5 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|MSVC|SunPro|XL|HP")
run_configure_and_build(Configurators)
run_configure_and_build(DerivedRule)
endif()
run_cmake(ExistenceCheck)