Syntax Introduction

  • CMakeLists.txt files follow a simple syntax consisting of comments, commands, and white space. A comment is indicated using the # character and runs from that character until the end of the line. A command consists of the command name, opening parenthesis, white space separated arguments and a closing parenthesis. A command can be either one of the built in commands like add_library, or a user defined macro or function. The input to CMake is a CMakeLists.txt file in the source directory. That file in turn can use the include or the add_subdirectory command to add additional input files.

    All white space (spaces, line feeds, tabs) are ignored except to separate arguments. Anything within a set of double quotes is treated as one argument as is typical for most languages. The backslash can be used to escape characters preventing the normal interpretation of them.

    Each command is evaluated in the order that it appears in the CMakeLists file. The commands have the form

      command (args...)

    where command is the name of the command, macro or function, and args is a white-space separated list of arguments. (Arguments with embedded white-space should be double quoted.) CMake is case insensitive to command names. So where you see command you could use COMMAND or Command instead.

Lists and Strings

The basic data type in CMake is a string. CMake also supports lists of strings. A list can be created with semi-colons as separators. For example these two statements set the same value in to variable VAR:

  set(VAR a;b;c)     set(VAR a b c)

Lists of strings can be iterated with the foreach command or manipulated with the list command.

Variables

CMake supports simple variables that can be either strings or lists of strings. Variables are referenced using a ${VAR} syntax. Multiple arguments can be grouped together into a list using the set command. All other commands expand the lists as if they had been passed into the command with white-space separation. For example,

  set(Foo a b c)

will result in setting the variable Foo to a b c, and if Foo is passed into another command

  command(${Foo})

it would be equivalent to

  command(a b c)

If you want to pass a list of arguments to a command as if it were a single argument simply double quote it. For example

  command("${Foo}")

would be invoked passing only one argument equivalent to command( "a b c" ).

Flow Control

In many ways writing a CMakeLists file is like a writing a program in a simple language. Like most languages CMake provides flow control structures to help you along your way. CMake provides three flow control structures:

    • conditional statements: if
    • # some_command will be called if the variable's value is not:
      # empty, 0, N, NO, OFF, FALSE, NOTFOUND, or -NOTFOUND.
      if(var)
         some_command(...)
      endif(var)

    • looping constructs: foreach and while
    • set(VAR a b c)
        # loop over a, b,c with the variable f
      foreach(f ${VAR})
          message(${f})
      endforeach(f)

    • procedure definitions: macro and function (function available in 2.6 and greater). functions create a local scope for variables, and macros use the global scope.
    • # define a macro hello
      macro(hello MESSAGE)
          message(${MESSAGE})
      endmacro(hello)
      # call the macro with the string "hello world"
      hello("hello world")
      # define a function hello
      function(hello MESSAGE)
          message(${MESSAGE})
      endfunction(hello)

For more information on flow control see the documetation for the commands if, while, foreach, macro, and function.

Quotes, Strings and Escapes

A string literal in CMake is created with by enclosing it in double quotes. Strings can be multi-line strings and will have embeded newlines in them. For example:

set (MY_STRING "this is a string with a
  newline in
  it")

You can also escape characters or use variables in a string.

set (VAR "
   hello
  world
  ")
message ( "\${VAR} = ${VAR}")
  # prints out
  ${VAR} =
    hello
    world

Standard C like escapes are also supported.

message("\n\thello world")
# prints out
hello world

A string literal is only a string literal if the charactor preceding the quote is white space. For example:

message(hell"o")   -> prints hell"o"
message(hell"o")   -> prints hell"o"
message(hell\"o\")  -> prints hell"o"

However, quotes must still be balanced, as this is an error:

    message(hell"o)   -> produces this error:
Parse error. Function missing ending ")".
Instead found unterminated string with text "o)
".

    message(hell\"o) -> prints hell"o

Regular Expressions

A few CMake commands, such as if and string, make use of regular expressions or can take a regular expression as an argument. In its simplest form, a regular-expression is a sequence of characters used to search for exact character matches. However, many times the exact sequence to be found is not known, or only a match at the beginning or end of a string is desired. Since there are a few different conventions for specifying regular expressions, CMake’s standard is described below. The description is based on the open source regular expression class from Texas Instruments that is used by CMake for parsing regular expressions.

Regular expressions can be specified by using combinations of standard alphanumeric characters and the following regular expression meta-characters:

    • ^ Matches at beginning of a line or string
    • $ Matches at end of a line or string
    • . Matches any single character other than a newline
    • [ ] Matches any character(s) inside the brackets
    • [^ ] Matches any character(s) not inside the brackets
    • [-] Matches any character in range on either side of a dash
    • * Matches preceding pattern zero or more times
    • + Matches preceding pattern one or more times
    • ? Matches preceding pattern zero or once only
    • () Saves a matched expression and uses it in a later replacement

This page was inspired by the Mastering CMake book, and from Kernigh's personal wiki describing the scripting language of CMake: Kernigh's wiki