Search code examples
cmakeoperator-precedence

In what order does CMake evaluate OR and AND in compound 'if' condition?


The CMake documentation states:

The following syntax applies to the condition argument of the if, elseif and while() clauses.

Compound conditions are evaluated in the following order of precedence: Innermost parentheses are evaluated first. Next come unary tests such as EXISTS, COMMAND, and DEFINED. Then binary tests such as EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, STREQUAL, STRLESS, STRLESS_EQUAL, STRGREATER, STRGREATER_EQUAL, VERSION_EQUAL, VERSION_LESS, VERSION_LESS_EQUAL, VERSION_GREATER, VERSION_GREATER_EQUAL, and MATCHES. Then the boolean operators in the order NOT, AND, and finally OR.

But the following prints 'FALSE':

cmake_minimum_required(VERSION 3.22)

project(Test)

if(YES OR NO AND NO)
    message("TRUE")
else()
    message("FALSE")
endif()

I'd expect the expression to evaluate as YES OR (NO AND NO). What's going on?


Solution

  • This is unfortunately not a bug in the implementation, but in the documentation. CMake is (mis)designed to evaluate AND and OR at the same precedence, and from left to right.

    See the MR that will update the documentation here: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/6970