17

In cmake, how can I check if a string token is included in another string?

In my case, I would like to know if the name of the compiler contains the string "Clang" (e.g. "clang", "AppleClang", ...). All I could do so far is:

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
...
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
...

I would like a more flexible approach, like checking for the presence of a substring.

This is what I could find in the documentation:

if( MATCHES regex) True if the given string or variable’s value matches the given regular expression.
if( LESS ) True if the given string or variable’s value is a valid number and less than that on the right.
if( GREATER ) True if the given string or variable’s value is a valid number and greater than that on the right.
if( EQUAL ) True if the given string or variable’s value is a valid number and equal to that on the right.
if( STRLESS ) True if the given string or variable’s value is lexicographically less than the string or variable on the right.
if( STRGREATER ) True if the given string or variable’s value is lexicographically greater than the string or variable on the right.
if( STREQUAL ) True if the given string or variable’s value is lexicographically equal to the string or variable on the right.

Pietro
  • 12,086
  • 26
  • 100
  • 193
  • One of the approaches you listed is going to be the final answer, but without a clear example of the token you are looking for and the string you are searching, no one is going to be able to direct you any more closely. – kdopen Feb 16 '15 at 17:51

1 Answers1

36

if(<variable|string> MATCHES regex) will probably be what you're looking for.

In this particular case (assuming you're doing the same thing inside the block for Clang and AppleClang) then you can replace:

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
...
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
...

with:

if(CMAKE_CXX_COMPILER_ID MATCHES "^(Apple)?Clang$")
Fraser
  • 74,704
  • 20
  • 238
  • 215
  • 2
    For what I have to do, this works fine: `if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")` – Pietro Feb 17 '15 at 13:45
  • And since the initial can be either upper or lowercase: `if(CMAKE_CXX_COMPILER_ID MATCHES "(C|c?)lang")` – Pietro Feb 17 '15 at 14:29
  • 4
    @Pietro That's because, although badly documented, MATCHES return true when the searched string is *contained* in the parsed string. That's at least my experience, tested in several cases, but again the documentation is far from clear on this aspect. – Antonio Mar 05 '15 at 16:25
  • @Antonio, That's because regex's, when they don't include a start/end token, will see if the regex matches anywhere in the string. In this case, "AppleClang" contains "Clang" at the end, so it's true. It's true that this isn't documented in detail in CMake's documentation (https://cmake.org/cmake/help/latest/command/string.html?highlight=regex#regex-specification), but it's pretty standard for regex. – Bronzdragon May 07 '20 at 16:36