[CMake] set(a b); set(b c); if(a STREQUAL b OR a STREQUAL c) ...

Ruslan Baratov ruslan_baratov at yahoo.com
Thu Sep 4 05:08:19 EDT 2014


On 04-Sep-14 09:58, Clark Wang wrote:
> On Thu, Sep 4, 2014 at 1:44 PM, Clark Wang <dearvoid at gmail.com 
> <mailto:dearvoid at gmail.com>> wrote:
>
>     On Thu, Sep 4, 2014 at 1:36 PM, Chuck Atkins
>     <chuck.atkins at kitware.com <mailto:chuck.atkins at kitware.com>> wrote:
>
>         Hi Clark
>
>         The expression inside the if statement has it's variables
>         dereferenced before evaluating and the non-variables are
>         treated as constant expressions.  In this case, a resolves to
>         "b", b resolves to "c", and c is not a variable so it's
>         treated as the constant expression "c".  Thus
>
>
>         if(a STREQUAL b OR a STREQUAL c)
>
>         gets evaluated as
>
>         if( ("b" STREQUAL "c") OR ("b" STREQUAL "c") )
>
>
>     Thanks a lot. It's clear now. But is there a way to check if the
>     value of the variable a equals to "b" or "c"?
>
>
> Found 
> http://stackoverflow.com/questions/19982340/cmake-compare-to-empty-string-with-strequal-failed 
> which suggests to use if(a MATCHES "^b$").
The core of the problem is that command "if(... STREQUAL ...)" has 
ambiguous syntax `<variable|string>`. So the result depends on what the 
left/right side is (if variable -> use variable value, if not, use 
string as-is).
Command `if(a MATCHES ...)` has the same flaw: `if(<variable|string> 
MATCHES regex)`:

# MYSTRING undefined
if(MYSTRING MATCHES "^MYSTRING$")
   # go here even MYSTRING is not defined (string "MYSTRING" used)
endif()

set(MYSTRING "B")
set(A "MYSTRING")
if("${A}" MATCHES "^MYSTRING$")
   # do *not* go here even A is MYSTRING (use *variable* MYSTRING)
endif()

One of the solution that doesn't suffer from ambiguity is 
`string(COMPARE EQUAL <string1> <string2> <output variable>)`:
string(COMPARE EQUAL "${MYSTRING}" "MYSTRING" is_equal)
if(is_equal)
   # only if MYSTRING defined and is "MYSTRING"
endif()

string(COMPARE EQUAL "${A}" "MYSTRING" is_equal)
if(is_equal)
   # only if A defined and is a string "MYSTRING" (works even if 
MYSTRING variable defined)
endif()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20140904/71e03d1b/attachment.html>


More information about the CMake mailing list