[CMake] comparing strings

Shaun Williams shaunewilliams at gmail.com
Thu Feb 14 17:26:34 EST 2013


I'm slowly realizing the gravity of this behavior:

if(build_system STREQUAL "windows")
...
endif()

If someone creates a variable named "windows", then this code will not work
as intended.

I'm starting to convert our scripts to use this hopefully foolproof
alternative:

string(COMPARE EQUAL "${build_system}" windows _cmp)
if (_cmp)
...
endif()

It will make it ugly to create a nested if else block, but it'll work.

On Thu, Feb 14, 2013 at 4:20 PM, Matthew Woehlke <
matthew.woehlke at kitware.com> wrote:

>
>
> On 2013-02-14 16:44, Shaun Williams wrote:
>
>> I learned something very valuable today about cmake after getting an
>> unexpected result with STREQUAL:
>>
>> set(foo bar)
>> ...
>> set(baz foo)
>> ...
>> if("${baz}" STREQUAL "bar") # This evaluates to true.
>> ...
>>
>> I expected it to be false, because I was trying to get baz's value ("foo")
>> to compare with "bar".  I thought that parameters explicitly quoted were
>> treated as strings.
>>
>> Then I learned that the interpreter is the only one that sees quotes
>> around
>> parameters, for the sole purpose of string interpolation and preventing
>> whitespace from splitting a parameter.  Cmake commands do not see these
>> quotes. Therefore, STREQUAL can never know the difference between "baz"
>> and
>> baz.
>>
>> So, STREQUAL treats a parameter as a variable name if it is defined, but
>> as
>> a string value if it is not.  (I verified this in cmIfCommand.cxx)
>>
>> Is this quote behavior well-known among cmake users?  For others like me,
>> I'd like this behavior to be emphasized in the cmake docs for STREQUAL.
>>
>
> Yes, it is :-/.
>
> This is why I take a page from autotools and try to always write:
>   if("x_${baz}" STREQUAL "x_bar")
>
> (Or you can write 'if(baz STREQUAL'... er... well if your RHS for sure
> cannot be a variable name - e.g. is empty, contains spaces, etc. - then you
> can write your constructs assuming that auto-expansion will occur.
> Personally, I'm going to stick with explicit expansion - guaranteeing an
> empty value in case the variable is not set - and adding something to make
> it unlikely that either side expands to a variable name to prevent
> auto-expansion...)
>
> --
> Matthew
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20130214/4d412a2c/attachment.htm>


More information about the CMake mailing list