6

To make values available to the whole CMake environment from within a subdirectory one may set a cache variable using the set(VARIABLE_NAME Value CACHE INTERNAL "") syntax or set a global property using the set_property(GLOBAL PROPERTY VARIABLE_NAME Value) syntax (see also this very good answer about variables in CMake).

Using the latter has the advantages that you are not "polluting" the CMake cache for something it is not designed for and that you are not dependent on the cache being deleted when not using the FORCE parameter.

But the syntax to use the variable value is not that user-friendly as you have to retrieve the value using get_property instead of simply using the ${...} notation.

Is there a simpler syntax to use instead of get_property (some kind of syntactic sugar)?

Community
  • 1
  • 1
Roland Sarrazin
  • 1,203
  • 11
  • 29
  • 1
    `"polluting" the CMake cache for something it is not designed for` - CMake cache **is designed** for internal cache variables (among other caches). `not dependent on the cache being deleted when not using the FORCE parameter` - `INTERNAL` **implies** `FORCE`. So, it is perfectly OK to use `CACHE INTERNAL` variables as global ones, and this is recommended way. – Tsyvarev Dec 15 '15 at 14:21
  • 1
    @Tsyvarev Thanks for the `INTERNAL` cache variable type hint. [My answer](http://stackoverflow.com/questions/31037882/whats-the-cmake-syntax-to-set-and-use-variables/31044116#31044116) is unclear there and I've updated it accordingly. The main reason I'm preferring `GLOBAL` properties is that it makes testing easier (there is no difference between the first and all consecutive runs). – Florian Dec 15 '15 at 20:48
  • @Roland Sarrazin Can you give an example where you need to retrieve the value of a global property? There is no direct access to properties like with variables, but there are some shortcuts that makes life easier like the `set_property(GLOBAL APPEND PROPERTY ...)` syntax to append to a list property (instead of getting, appending and the setting it). – Florian Dec 15 '15 at 20:55
  • @Florian Typically I would set a path in one subdirectory that is needed by another subdirectory, hence the need for a global variable to be set and read. So from your comment I read that there is no specific syntactic sugar. – Roland Sarrazin Dec 16 '15 at 12:33
  • @Tsyvarev We are facing issues with our complex CMake setup about cached variables that don't behave well when repeatedly building while changing the cached *values*. Honestly we thought it relates to our forgetting the FORCE parameter, but this doesn't seem to apply since you state that INTERNAL implicates a FORCE behavior. – Roland Sarrazin Dec 16 '15 at 12:34
  • 1
    @RolandSarrazin Could you please be more specific what kind of path you need in the other subdirectory? And what CMake version you are using? The properties - not only the `GLOBAL` ones - are very powerful (see e.g. [here](http://stackoverflow.com/questions/33828855)). Let's say we are talking about include directories: `set_property(DIRECTORY "${CMAKE_SOURCE_DIR}" APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}")` to append to the main scope, `set_property(TARGET Lib1 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}")` append to target, ... – Florian Dec 16 '15 at 20:58
  • 1
    @RolandSarrazin If you start your `CMakeLists.txt` by explicitly clearing all your internal cache variables (`set(VAR "" CACHE INTERNAL ""`) then there should be no difference between repeated runs. – tamas.kenez Dec 20 '15 at 00:08

1 Answers1

3

Let's summarize the comments.

To my actual question: There is no specific shortcut to use get_property.

Useful comments:

  • As CACHE INTERNAL implies FORCE it is okay to use cached variables to make variables globally accessible.
  • It is good practice to start the CMake file by explicitly cleaning / setting the internal cache variables to avoid unpredictable behavior at repeated runs.
Roland Sarrazin
  • 1,203
  • 11
  • 29
  • What if you can't clear the internal variables? I think that cmake itself should clear all internal cache variables every time it is newly invoked. But it doesn't. See https://stackoverflow.com/questions/61024065/how-to-print-a-message-exactly-once-per-cmake-invocation – Carlo Wood Apr 04 '20 at 05:33
  • My (own) answer is a few years old so I'm not completely sure what I meant with the second bullet point at that time. Probably I meant that the internal cache variable shall be set at the very beginning to ensure it is not used before being set at first run. – Roland Sarrazin Apr 05 '20 at 17:11