Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake variable expansion using "@" vs. "${}"

Consider the following:

SET(TEST_DIR, "test")
INSTALL(PROGRAMS scripts/foo.py DESTINATION ${TEST_DIR})
INSTALL(PROGRAMS scripts/foo.py DESTINATION @TEST_DIR@)

The first INSTALL command does not work. The second does. Why is that? What is the difference between those two? I have not found any reference to @@ expansion except in the context of creation of configuration files. Everything else only uses ${} expansion.

UPDATE: OK, obvious bug in the above. My SET() command has an extraneous comma. Removing it, such that it looks like:

    SET(TEST_DIR "test")

results in both @@ and ${} expansions working. Still wondering (a) what is the meaning of @@ as opposed to ${}, and why only the former worked with my incorrect SET() statement.

like image 499
Jeet Avatar asked Apr 20 '13 23:04

Jeet


People also ask

Why can't I add quotes to a variable in CMake?

If your variable contains a list you normally don't add quotes. Reasoning: If you give something like a file list to an CMake command it normally expect a list of strings and not one string containing a list. The difference you can see e.g. in the foreach () command accepting ITEMS or LISTS.

How do I set a global variable in CMake?

Variables and the Global Variables Cache Mostly you will use "normal variables": set (VAR TRUE) set (VAR "main.cpp") set (VAR1 $ {VAR2}) But CMake does also know global "cached variables" (persisted in CMakeCache.txt).

Where can I find information on internal variables in CMake?

For general information on variables, see the Variables section in the cmake-language manual. begin with _ followed by the name of any CMake Command. CMake has many internal variables. Most of them are undocumented. Some of them, however, were at some point described as normal variables, and therefore may be encountered in legacy code.

How does CMake differentiate between normal strings and list variables?

CMake differentiates between normal strings and list variables (strings with semicolon delimiters) There are some rules of thumb you should consider: a) When your variable contains text - especially one that could contain semicolons - you should add quotes. Reasoning: A semicolon is a delimiter for list elements in CMake.


2 Answers

According to the documentation for the configure_file() command when configuring a file both the ${VAR} form and @VAR@ form will be replaced VAR's value. Based on your experience above and some testing I did both forms are replaced when CMake evaluates your CMakeLists.txt, too. Since this is not documented I would recommend against using the @VAR@ from in your CMakeLists.txt

Note that when using configure_file() you can restrict replacement to only the @VAR@ form by using the @ONLY argument.

like image 75
j3lamp Avatar answered Oct 02 '22 10:10

j3lamp


As far as I know, the @VAR@ syntax is only used when replacing variables with the configure_file command.

Note that the configure_file command allows for an extra option @ONLY. Using it you can specify that only the @VAR@'s are replaced, but that the ${VAR}'s are kept.

As an example, this can be useful when generating e.g. a cmake-file which is later to be used with CMake again. E.g. when building your project, the @VAR@ will be replaced when using configure_file. After you distributed your project and someone else uses the generated UseProject.cmake file, the ${VAR}$ entries will be replaced.

like image 32
André Avatar answered Oct 02 '22 09:10

André