

Set Normal Variable ¶
Set or unset <variable> in the current function or directory scope:
If at least one <value>... is given, set the variable to that value.
If no value is given, unset the variable. This is equivalent to unset(<variable>) .
If the PARENT_SCOPE option is given the variable will be set in the scope above the current scope. Each new directory or function() command creates a new scope. A scope can also be created with the block() command. set(PARENT_SCOPE) will set the value of a variable into the parent directory, calling function, or encompassing scope (whichever is applicable to the case at hand). The previous state of the variable's value stays the same in the current scope (e.g., if it was undefined before, it is still undefined and if it had a value, it is still that value).
The block(PROPAGATE) and return(PROPAGATE) commands can be used as an alternate method to the set(PARENT_SCOPE) and unset(PARENT_SCOPE) commands to update the parent scope.
When evaluating Variable References of the form ${VAR} , CMake first searches for a normal variable with that name. If no such normal variable exists, CMake will then search for a cache entry with that name. Because of this, unsetting a normal variable can expose a cache variable that was previously hidden . To force a variable reference of the form ${VAR} to return an empty string, use set(<variable> "") , which clears the normal variable but leaves it defined.
Set Cache Entry ¶
Sets the given cache <variable> (cache entry). Since cache entries are meant to provide user-settable values this does not overwrite existing cache entries by default. Use the FORCE option to overwrite existing entries.
The <type> must be specified as one of:
BOOL Boolean ON/OFF value. cmake-gui(1) offers a checkbox. FILEPATH Path to a file on disk. cmake-gui(1) offers a file dialog. PATH Path to a directory on disk. cmake-gui(1) offers a file dialog. STRING A line of text. cmake-gui(1) offers a text field or a drop-down selection if the STRINGS cache entry property is set. INTERNAL A line of text. cmake-gui(1) does not show internal entries. They may be used to store variables persistently across runs. Use of this type implies FORCE .
The <docstring> must be specified as a line of text providing a quick summary of the option for presentation to cmake-gui(1) users.
If the cache entry does not exist prior to the call or the FORCE option is given then the cache entry will be set to the given value.
The content of the cache variable will not be directly accessible if a normal variable of the same name already exists (see rules of variable evaluation ). If policy CMP0126 is set to OLD , any normal variable binding in the current scope will be removed.
It is possible for the cache entry to exist prior to the call but have no type set if it was created on the cmake(1) command line by a user through the -D<var>=<value> option without specifying a type. In this case the set command will add the type. Furthermore, if the <type> is PATH or FILEPATH and the <value> provided on the command line is a relative path, then the set command will treat the path as relative to the current working directory and convert it to an absolute path.
Set Environment Variable ¶
Sets an Environment Variable to the given value. Subsequent calls of $ENV{<variable>} will return this new value.
This command affects only the current CMake process, not the process from which CMake was called, nor the system environment at large, nor the environment of subsequent build or test processes.
If no argument is given after ENV{<variable>} or if <value> is an empty string, then this command will clear any existing value of the environment variable.
Arguments after <value> are ignored. If extra arguments are found, then an author warning is issued.
Table of Contents
- Set Normal Variable
- Set Cache Entry
- Set Environment Variable
Previous topic
separate_arguments
set_directory_properties
- Show Source
Quick search

The Eclectic Coder
Sean bone's portfolio.
- Build systems
- Software Development
Using CMake to set preprocessor directives
Preprocessor flags.
C++ preprocessor directives are useful for many things. One use is to set flags from the command line in order to compile the program in different ways. For instance, we could have a DEBUG flag which, if set, gives us some extra feedback useful for debugging:
These options could be set from the command line when compiling the program, by prefixing their name with -D :
This is the equivalent of setting #define DEBUG at the beginning of main.cpp . You can also give it a value:
Is equivalent to writing #define DEBUG 1 in main.cpp .
Setting flags with CMake
If you use CMake however, you’re not writing the compilation command yourself. So, how can we achieve the same effect?
First, we will use CMake’s option() function to add a command-line option when running the cmake command:
Now we can set this option to ON when running CMake:
Then, we’ll use CMake’s add_definitions() function to set the corresponding preprocessor flag in our C++ program:
That’s all there is to it. Below you can find a sample CMake file with this functionality built into it:
Saladin's dev odyssey

Using Cmake defined variables in c++ code
C++ project versioning.

Table of contents
1. cmake variables, 2. definitions to the compiler command line, which method to take.
Cmake is a wonderful tool for generating building systems for projects. One of the applications that Cmake facilitates, is configuring the project version from within a CMakeLists.txt file.
This can be easily done by defining the version components as either, cmake variables or as definitions to the compiler command line. This article will give an overview of both methods.
Semantic versioning which is one of the popular methods used to version software gives the project a version number composed of 3 components: Major , Minor and the patch . Details on the meaning of each number go out of this article's scope but it can be checked on this link .
The simplest way of defining a project version is by defining a header file containing the version components as global variables. This header file can then be included to make variables available for various uses. Doing things this way leaves us with the problem of maintaining these variables at the code level instead of aggregating this task to the build system.
So how can we avoid defining the project version in multiple locations? In the code (if we need it there), in the build system or the source packaging.
The idea behind the first method is to use configure_file() command to copy an input file to another location and modify its content. The configuration file can be a .h header file that contains the definition of the project version. All variables with the decoration @cmake_variable@ will be replaced with their values given in the CMakeLists.txt file.
Cmake variables can be defined in the CMakeLists.txt using the set() command. For our tutorial, it is sufficient to have them of normal type. The following CMakeLists.txt file shows how to set them:
The command configure_file() will copy the content of the file version.h.in and creates a new file called version.h in ${CMAKE_CURRENT_SOURCE_DIR} which is the location where the source files of the project are located. Since we added the argument @ONLY to the configure_file() call. The content of version.h will be similar to version.h.in except that all references of the form @variable@ will be replaced with what has been set in the CMakeLists.txt . Of course, this happens during the build (running make command).
configure_file() can be checked here .
@ONLY Restrict variable replacement to references of the form @VAR@ . This is useful for configuring scripts that use ${VAR} syntax.
The content of the version.h.in :
version.h will be the following:
Finally, we can include version.h and use the project versions in main.cpp like this:
The idea behind the second method is to pass the project version components as pre-processor directives to the compiler which will translate them during compilation and replace them in the target.
For such a purpose we can rely on the #define pre-processor in c++. This pre-processor will allow us to create a c++ macro. The macro is "simply" a word that will be replaced during compilation time with the value given to it.
The same main.cpp of the first method can be transformed into:
During the compilation VERSION_MAJOR , for example, will take the value _VERSION_MAJOR and when executing the target, it is as if we have written _VERSION_MAJOR in the std::cout .
Of course, the compiler does not have any definition for _VERSION_MAJOR yet. These definitions can be passed to the compiler via the flag -D or equivalently to the CMakeLists.txt as follow:
I should draw the reader's attention that this is not the only cmake command cable of adding compilation definitions as you may read in this link .
Which method to take? does not have a big impact. Depending on the project size and the number of libraries used it may be preferable to use the config_file() approach as this will keep the call to the compiler small. (refer to this thread )
https://cmake.org/cmake/help/latest/command/add_definitions.html
https://stackoverflow.com/questions/3781222/add-definitions-vs-configure-file
https://evileg.com/en/post/536/
- Community forum
- Keyboard shortcuts ?
- Submit feedback
- Contribute to GitLab
add_definitions of a variable containing multiple "-DXXX" preprocessor is used as flags and not preprocessor defines
Hi all CMake is Windows 64 bit cmake version 3.12.3
Adding compiler definitions with
add_definitions(-DFOO)
set(FOO_VAR "-DFOO")
add_definitions(${FOO_VAR})
Correctly add -DFOO in the list of compiler preprocessor define list (properties COMPILE_DEFINITIONS) But if I setup a variable such:
set(FOO_AR "-DFOO -DTEST")
the -DFOO and -DTEST are not add to COMPILE_DEFINITIOS but to target flags, with the result that they are added to the ASM compiler also, causing error for ASM compiler that does not support -D (such armasm)
add_definition(-DFOO -DTEST)
works, but this prevent to use cmake variables

IMAGES
COMMENTS
In mathematics, a well-defined set clearly indicates what is a member of the set and what is not. For example, a set that is identified as “the set of even whole numbers between 1 and 11” is a well-defined set because it is possible to iden...
A subordinate character can be defined as a character with an important role in a story who is not actually the story’s protagonist. Subordinate characters often either motivate the protagonist or set out obstacles that the protagonist must...
Any profession has a specific set of skills and tools to help workers in that field do a good job, and for writers, those skills include narrative elements and literary devices. Narrative elements are terms of storytelling while literary de...
Definitions with non-trivial values may be left in the set of flags instead of being converted for
target_compile_definitions sets the value for WHOLE executable/library, where as 'set_source_files_properties` sets the value for only the
Adds preprocessor definitions to the compiler command line. The preprocessor definitions are added to the COMPILE_DEFINITIONS directory property for the
В CMake проставление #define-ов через компилятор делается с помощью add_definitions, которая добавляет флаги компилятора ко всему текущему
To force a variable reference of the form ${VAR} to return an empty string, use set(<variable> "") , which clears the normal variable but leaves it defined. Set
Is equivalent to writing #define DEBUG 1 in main.cpp . Setting flags with CMake. If you use CMake however, you're not writing the compilation
I want to have a preprocessor symbol (GEN_OUTFILES) defined for all build configurations except one (ReleaseNoOutfiles). Before I added the · Initially I didn't
1. Cmake variables. The idea behind the first method is to use configure_file() command to copy an input file to another location and modify its
Calling cmake -DVARIABLE sets a CMake variable, it will not automatically add the compile definition to every (or any) target. You could pass it
Hi all CMake is Windows 64 bit cmake version 3.12.3 Adding compiler definitions with add_definitions(-DFOO) or set(FOO_VAR "-DFOO")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNEQUALSOFTENINGS -DPEANOHILBERT -DWALLCLOCK -DSYNCHRONIZATION -DPMGRID=128") it does not work. How to