CMake:VariablesListsStrings: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
No edit summary
(Add explicit preformat markup)
Line 5: Line 5:
src/foo/CMakeLists.txt:
src/foo/CMakeLists.txt:


<pre>
   set(SomeVariable "Hello world")
   set(SomeVariable "Hello world")
</pre>


This creates (if it didn't exist yet) the variable <tt>SomeVariable</tt>.  
This creates (if it didn't exist yet) the variable <tt>SomeVariable</tt>.  
Line 17: Line 19:
If a string contains semicolons, these semicolons can be interpreted as separators of string values.
If a string contains semicolons, these semicolons can be interpreted as separators of string values.


<pre>
  set(MyString "Hello world")
  set(MyString "Hello world")
</pre>


This sets MyString to "Hello world", which is always only one string.
This sets MyString to "Hello world", which is always only one string.


<pre>
  set(MyList Hello world)
  set(MyList Hello world)
</pre>


This sets MyList to a list with the items "Hello" and "world". It will be stored as a string "Hello;world".
This sets MyList to a list with the items "Hello" and "world". It will be stored as a string "Hello;world".
Line 31: Line 37:
Let's say you'd like to do the following:
Let's say you'd like to do the following:


<pre>
  void InsertIntoMap(string key, string value)
  void InsertIntoMap(string key, string value)
  {
  {
     MyMap[key]=value;
     MyMap[key]=value;
  }
  }
 
  string k = "foo";
  string k = "foo";
  string v = "bar";
  string v = "bar";
  InsertIntoMap(k, v);  
  InsertIntoMap(k, v);  
</pre>


you can do the following in CMake:
you can do the following in CMake:


<pre>
  MACRO(INSERT_INTO_MAP _KEY _VALUE)
  MACRO(INSERT_INTO_MAP _KEY _VALUE)
   SET("MyMap_${_KEY}" "${_VALUE}")
   SET("MyMap_${_KEY}" "${_VALUE}")
Line 49: Line 58:
  SET(MyValue "bar")
  SET(MyValue "bar")
  INSERT_INTO_MAP("${MyKey}" "${MyValue}")
  INSERT_INTO_MAP("${MyKey}" "${MyValue}")
</pre>


You can test for the existence of a key using IF(DEFINED ...)
You can test for the existence of a key using IF(DEFINED ...)
Line 81: Line 91:
* In a regex, inside of [] you do not need anything.  [$] is fine.
* In a regex, inside of [] you do not need anything.  [$] is fine.
* In a non-regex string, in front of a curly bracket you need \${
* In a non-regex string, in front of a curly bracket you need \${
<pre>
   set(blah "whatever but \${do_not_evaluate}")
   set(blah "whatever but \${do_not_evaluate}")
</pre>
* In a regex string, in front of a curly bracket you need \\\${
* In a regex string, in front of a curly bracket you need \\\${
<pre>
   string(REGEX REPLACE
   string(REGEX REPLACE
     ".*whatever but \\\${do not evaluate}"
     ".*whatever but \\\${do not evaluate}"
</pre>


==The CMake cache==
==The CMake cache==

Revision as of 18:33, 24 April 2018

Scope of variables in CMake

In CMake variables don't have to be declared, they are created upon their first usage:

src/foo/CMakeLists.txt:

  set(SomeVariable "Hello world")

This creates (if it didn't exist yet) the variable SomeVariable. All variables in CMake are global. Global means that the variables exist in the file where they have been created, in all subdirectories connected using ADD_SUBDIRECTORY() or SUBDIRS(), and in all included files in any of these directories. They don't propagate up to the parent directories. Also if the value of a variable is changed in a subdirectory, the change doesn't propagate up to the variable in the parent directory.

Strings vs. lists

In CMake all variables are of the type string. Nevertheless CMake can deal also with lists. If a string contains semicolons, these semicolons can be interpreted as separators of string values.

 set(MyString "Hello world")

This sets MyString to "Hello world", which is always only one string.

 set(MyList Hello world)

This sets MyList to a list with the items "Hello" and "world". It will be stored as a string "Hello;world".

Emulating maps

Since CMake only has the string type (and somewhat lists), you can't use maps directly, but you can emulate them.

Let's say you'd like to do the following:

 void InsertIntoMap(string key, string value)
 {
    MyMap[key]=value;
 }
 
 string k = "foo";
 string v = "bar";
 InsertIntoMap(k, v); 

you can do the following in CMake:

 MACRO(INSERT_INTO_MAP _KEY _VALUE)
   SET("MyMap_${_KEY}" "${_VALUE}")
 ENDMACRO(INSERT_INTO_MAP)
 
 SET(MyKey "foo")
 SET(MyValue "bar")
 INSERT_INTO_MAP("${MyKey}" "${MyValue}")

You can test for the existence of a key using IF(DEFINED ...)

Boolean values in CMake

The following values are interpreted as false by CMake. Upper/lower casing doesn't matter:

  • OFF
  • FALSE
  • N
  • NO
  • 0
  • "" (empty string)
  • a null variable, such as produced by "set(variable)".
  • NOTFOUND
  • any string ending in -NOTFOUND

True:

  • ON
  • TRUE
  • Y
  • YE
  • YES
  • 1
  • everything not listed under false

Using CMake regexps

Escaping

Sometimes you need to escape a $

  • In a regex, outside of [] you need \\$
  • In a regex, inside of [] you do not need anything. [$] is fine.
  • In a non-regex string, in front of a curly bracket you need \${
  set(blah "whatever but \${do_not_evaluate}")
  • In a regex string, in front of a curly bracket you need \\\${
  string(REGEX REPLACE
    ".*whatever but \\\${do not evaluate}"

The CMake cache

CMake uses an on-disk cache file to store variables and their values for later runs. This file is located in CMAKE_BINARY_DIR and is named CMakeCache.txt. The variables in this file are global to the whole build tree.

Most configure-checks save their result in this file, so they don't have to be executed again on later CMake runs.



CMake: [Welcome | Site Map]