[CMake] Variable Containing "MSVC" and MATCHES

Marek Vojtko (Firaxis) Marek.Vojtko at firaxis.com
Wed Mar 12 16:25:20 EDT 2014


Hi,

I know that MSVC is a CMake keyword and it is therefore not a good idea to use the string "MSVC" as the value for any variable, e.g. set( compiler "MSVC" ), because if you aren't careful and interpret such a variable without surrounding it with quotes (e.g. ${compier} rather than "${compiler}") you will get 0 or 1 depending on whether you are using a Visual Studio generator or not. So far so good.

However, I was caught off guard by the fact that the MATCHES directive (for regex matching) inside an IF() statement is apparently interpreting the strings passed to it. Consider the following code:

if( "MSVC11" MATCHES "MSVC[0-9]+" )
    message( STATUS "MSVC11 matches MSVC[0-9]+" )
endif()

if( "TEST11" MATCHES "TEST[0-9]+" )
    message( STATUS "TEST11 matches TEST[0-9]+" )
endif()

The first MATCHES does not enter the IF() statement, while the second does. I'm guessing that the string "MSVC11" (or the regular expression "MSVC[0-9]+") is interpreted before regular expression matching can take place and "MSVC11" becomes "111" or "true11" (or the regular expression "MSVC[0-9]+" becomes "1[0-9]+" or "true[0-9]+").

Putting either the string or the regex or both into variables doesn't help either. The only thing that prevents MSVC from being interpreted is putting extra quotes into both the string and the regexp, i.e. "\"MSVC11\"" MATCHES "\"MSVC[0-9]+\"".

Is there any type of interpretation happening on either the string or the regex in an IF( MATCHES ) statement? If this is by design, i.e. not a bug, what are the reasons for this?

Thanks,

P.S.: The following is an example CMakeLists.txt that demonstrates the problem for easy testing:

cmake_minimum_required( VERSION 2.8.12 )

set( test "MSVC11" )
message( STATUS "Start matching string \"${test}\" ..." )

message( STATUS )
set( regex "MSVC" )
message( STATUS "... against regular expression: ${regex}" )
if( "${test}" MATCHES "${regex}" )
    message( STATUS "\t\"${test}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
set( regex "MSVC." )
message( STATUS "... against regular expression: ${regex}" )
if( "${test}" MATCHES "${regex}" )
    message( STATUS "\t\"${test}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
set( regex "MSVC[0-9]" )
message( STATUS "... against regular expression: ${regex}" )
if( "${test}" MATCHES "${regex}" )
    message( STATUS "\t\"${test}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
set( regex "MSVC[0-9]+" )
message( STATUS "... against regular expression: ${regex}" )
if( "${test}" MATCHES "${regex}" )
    message( STATUS "\t\"${test}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
message( STATUS "End matching ${test} ..." )

message( STATUS )
message( STATUS )
message( STATUS )

set( test2 "test11" )
message( STATUS "Start matching ${test2} ..." )

message( STATUS )
set( regex "test" )
message( STATUS "... against regular expression: ${regex}" )
if( "${test2}" MATCHES "${regex}" )
    message( STATUS "\t\"${test2}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test2}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
set( regex "test." )
message( STATUS "... against regular expression: ${regex}" )
if( "${test2}" MATCHES "${regex}" )
    message( STATUS "\t\"${test2}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test2}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
set( regex "test[0-9]" )
message( STATUS "... against regular expression: ${regex}" )
if( "${test2}" MATCHES "${regex}" )
    message( STATUS "\t\"${test2}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test2}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
set( regex "test[0-9]+" )
message( STATUS "... against regular expression: ${regex}" )
if( "${test2}" MATCHES "${regex}" )
    message( STATUS "\t\"${test2}\" matches regular expression: ${regex}" )
else()
    message( STATUS "\t\"${test2}\" DOES NOT match regular expression: ${regex}" )
endif()

message( STATUS )
message( STATUS "End matching ${test2} ..." )
--
Marek Vojtko
mail: marek.vojtko at firaxis.com
phone: (+1) 410-229-2519




More information about the CMake mailing list