Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake: difference between ${} and "${}"

Tags:

cmake

What is the difference, in cmake, between something like:

set(any_new_var ${old_var})

and

set(any_new_var "${old_var}")

Any important difference? When have I to use one or the other form?

For example, I try with the next mini test

# test.cmake

# Variable 'a' isn't defined.
set(hola "${a}")

# message(${hola})
message("${hola}")

The output of this mini-test (cmake -P test.cmake) is a empty line (because 'a' isn't defined). If I uncomment the first message, cmake throws an message error:

CMake Error at prueba.cmake:6 (message):
  message called with incorrect number of arguments

Why in the second case it doesn't throw and error but an empty line?

like image 686
Peregring-lk Avatar asked Nov 27 '12 10:11

Peregring-lk


People also ask

What is ${} in CMake?

You access a variable by using ${} , such as ${MY_VARIABLE} . 1. CMake has the concept of scope; you can access the value of the variable after you set it as long as you are in the same scope. If you leave a function or a file in a sub directory, the variable will no longer be defined.

How to Comment out in CMake?

There is no notion of a block comment in CMake syntax. However, to comment several lines at once, select the required lines and hit CTRL + Q . If the file is a . txt file (e.g. CMakeLists.

Where are CMake variables defined?

Options and variables are defined on the CMake command line like this: $ cmake -DVARIABLE=value path/to/source You can set a variable after the initial `CMake` invocation to change its value. You can also undefine a variable: $ cmake -UVARIABLE path/to/source Variables are stored in the `CMake` cache.


1 Answers

In CMake strings can be interpreted as lists. The rule is simple: to form the list split the string at semicolons. For example, the string value one;two;three can be thought of as a list of three elements: one, two, and three.

To invoke a command you write the command name and some words between parentheses. However, these words do not correspond to the arguments the command receive in a one-to-one fashion. Each word become zero or more arguments, and all the arguments get concatenated together. Unless a word is quoted, it is treated as a list and is expanded to multiple arguments. A quoted word always becomes a single argument.

For example, assume that X is bound to one;two;three, Y is bound to the empty string, and Z is bound to foo. The following command invocation has three words, but the command receives four arguments:

some_command(${X} ${Y} ${Z})
# The command receives four arguments:
# 1. one
# 2. two
# 3. three
# 4. foo

If we would have quoted the words, the command would have received three arguments:

some_command("${X}" "${Y}" "${Z}")
# The command receives three arguments:
# 1. one;two;three
# 2. (the empty list)
# 3. foo

To return to your original question: the message command can receive a varying number of arguments. It takes all its arguments, concatenates them together into one string, and then prints that string. For some unknown reason it does not accept zero arguments, though.

The behavior message has with multiple arguments is not very useful, so you tend to use a single quoted argument with it:

set(SOURCES foo.c hoo.h)
message(${SOURCES})   # prints foo.cfoo.h
message("${SOURCES}") # prints foo.c;foo.h

Also, when set receives multiple arguments it builds a string of the arguments separated by semicolons. The variable is then set to that string.

like image 92
raek Avatar answered Oct 22 '22 21:10

raek