# Which variables are not meant to be set in the CMakeLists.txt?

**URL:** <https://discourse.cmake.org/t/which-variables-are-not-meant-to-be-set-in-the-cmakelists-txt/1424>\
**Category:** Code\
**Created:** [June 22, 2020, 12:24am UTC](https://discourse.cmake.org/t/which-variables-are-not-meant-to-be-set-in-the-cmakelists-txt/1424 "2020-06-22T00:24:59Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)\
**Post date:** [June 22, 2020, 12:24am UTC](https://discourse.cmake.org/t/which-variables-are-not-meant-to-be-set-in-the-cmakelists-txt/1424/1 "2020-06-22T00:24:59Z")

</div>

I understand that some variables are not meant to be `set()` in the CMakeLists.txt file, but _are_ allowed to be set at the command line or in a toolchain file. Which variables are these? Are they documented anywhere?

For instance, `CMAKE_CURRENT_BINARY_DIR` is not what I’m talking about, since there’s no reason to set it manually. On the other hand, the common advice is to not set `CMAKE_<LANG>_FLAGS_<CONFIG>`, but instead to either set it at the command line or from the gui, or set `CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` in a toolchain file (but that is the only place this variable should be set).

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [June 22, 2020, 1:07pm UTC](https://discourse.cmake.org/t/which-variables-are-not-meant-to-be-set-in-the-cmakelists-txt/1424/2 "2020-06-22T13:07:48Z")

</div>

I think that all variables can be used with `set()`. With this said, this is not documented because there is no such limitation per se (there are no read-only variables).

For every variable you must understand how to use it correctly:

```cmake
set( CMAKE_CURRENT_BINARY_DIR "hello world" )

```

While this is a valid instruction their application is completely nonsense. The documentation explains exactly how this variable is being set, what information it contains and for which scope it applies. This doesn’t mean above instruction is forbidden.

For all variables, generally speaking they must be defined in their scope before being used. This includes build-in commands like `project`, `enable_language`, as well, which is why

- Language variables like `CMAKE_<lang>`, `*_INIT` must be defined before the language is enabled
- Variables like `CPACK_` must be defined before `cpack` is called
- etc

The build-in commands make this process as convenient as possible. They automatically set the correct variables for the user. You should generally always use the build-in commands as much as possible. For general usage you do not need to manipulate any of these variables. For anything that is not supported otherwise you’ll have to rely on the documentation.

There are some books or block articles that go into this topic in some more detail, I don’t think there is any complete answer anywhere, though.
