[CMake] if(MATCHES) broken??
Bill Hoffman
bill.hoffman at kitware.com
Wed Nov 19 22:50:12 EST 2008
Matthew Woehlke wrote:
> Can someone explain to me:
> - why this doesn't work (prints "CFLAGS match broken!!")
> - if it's supposed to work or if this is a bug
> - a great work-around to this problem ;-)
>
> This is with cmake 2.6.2
>
> ================================================
> macro(foo bar)
> if("${bar}" MATCHES "CFLAGS")
> message(STATUS "CFLAGS matched")
> elseif("${bar}" STREQUAL "CFLAGS")
> message(STATUS "CFLAGS match broken!!!")
> endif()
> endmacro()
>
> function(nonce)
> foreach(arg ${ARGN})
> foo("${arg}")
> endforeach()
> endfunction()
>
> set(CFLAGS happyjoy)
>
> foo(CFLAGS)
>
OK, here is the explanation...
The problem is that if(something MATCHES something) works for either
strings or variable names. The way that works is by checking to see if
there is a variable defined by the string given to if. Even if that
string is in quotes, it can still be treated like a variable.
So, in this case cmake looks up "CFLAGS" and finds that there is a
variable of that name, and uses that value for the MATCHES statement.
Basically ending up with if("happyjoy" MATCHES "CFLAGS"). You can
verify this by commenting out set(CFLAGS happyjoy) so that CFLAGS does
not have a definition, then your code works.
The only work around that I can think of is to change the macro to a
function and unset the variable before the test.
function(foo bar)
set(${bar} ) # unset the variable named "${bar}"
if("${bar}" MATCHES "CFLAGS")
message(STATUS "CFLAGS matched")
elseif("${bar}" STREQUAL "CFLAGS")
message(STATUS "CFLAGS match broken!!!")
endif()
endfunction()
Use a function so bar does not get changed in the parent scope. You
could save the value into another variable if you need the value.
I agree this is confusing... Perhaps there should be some new if
arguments that are always string based, and never look up variables.
Something like:
if( string MATCHES_STRINGS string)
if( string STRLESS_STRINGS string)
if( string STREQUAL_STRINGS string)
-Bill
More information about the CMake
mailing list