# Referencing an undefined option() is different between first & subsequent CMake runs

**URL:** https://discourse.cmake.org/t/referencing-an-undefined-option-is-different-between-first-subsequent-cmake-runs/6696
**Category:** Code
**Created:** [October 19, 2022, 11:10pm UTC](https://discourse.cmake.org/t/referencing-an-undefined-option-is-different-between-first-subsequent-cmake-runs/6696 "2022-10-19T23:10:51Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![steven-johnson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/steven-johnson/32/448_2.png) [@steven-johnson](https://discourse.cmake.org/u/steven-johnson)
#### Post date: [October 19, 2022, 11:10pm UTC](https://discourse.cmake.org/t/referencing-an-undefined-option-is-different-between-first-subsequent-cmake-runs/6696/1 "2022-10-19T23:10:52Z")

</div>

Consider a CMake script something like:

```auto
cmake_dependent_option(
    MYPROJECT_ENABLE_COOL_FEATURE 
    "Enable cool feature (requires MYPROJECT_ENABLES_EXCEPTIONS=ON)" ON
    "MYPROJECT_ENABLE_EXCEPTIONS" OFF
)

...

option(MYPROJECT_ENABLE_EXCEPTIONS "Enable exceptions" ON)

```

The idea here is obvious: an option to enable exceptions, and a dependent option to enable another feature.

There’s a subtle bug here, though: CMake apparently treats not-yet-defined `option()` as `false`, so the _first_ time you use this to configure your project, `MYPROJECT_ENABLE_COOL_FEATURE` will always be `OFF`, because it relies on the not-yet-defined `MYPROJECT_ENABLE_EXCEPTIONS` option.

Subsequent builds will be ‘correct’ since (apparently) the `option()` values are already cached. This makes for really subtle, hard-to-find build issues.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [October 19, 2022, 11:23pm UTC](https://discourse.cmake.org/t/referencing-an-undefined-option-is-different-between-first-subsequent-cmake-runs/6696/2 "2022-10-19T23:23:04Z")

</div>

I know this probably isn’t all that helpful, but I try _very_ hard to never use `cmake_dependent_option()` in projects I work on. The idea of dependent options and the desire to use that sort of structure is understandable, but it leads to issues like this where it can take two CMake runs for options to be set the way you expect/want. Users rarely expect that, and they shouldn’t have to know that or be subjected to such requirements.

In many cases, you can get the configurability you’re after without having to use `cmake_dependent_option()`. Sure, you might see some things visible in the CMake cache that won’t be used anyway, but that’s a penalty I’ll pay every time if the benefit is a more robust build. Also, some things don’t need to be cache options. They can sometimes be ordinary variables that are either undefined or only defined as regular variables in the project. This would be appropriate for things that are fully dependent on other things rather than being something a user can modify directly.

---

<div class="post-metadata">

### Author: ![steven-johnson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/steven-johnson/32/448_2.png) [@steven-johnson](https://discourse.cmake.org/u/steven-johnson)
#### Post date: [October 19, 2022, 11:56pm UTC](https://discourse.cmake.org/t/referencing-an-undefined-option-is-different-between-first-subsequent-cmake-runs/6696/3 "2022-10-19T23:56:08Z")

</div>

Heh, so it sounds like you’re saying it’s basically a footgun that should ~never be used… so I have to ask, why does it exist in the first place?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [October 20, 2022, 5:21pm UTC](https://discourse.cmake.org/t/referencing-an-undefined-option-is-different-between-first-subsequent-cmake-runs/6696/4 "2022-10-20T17:21:54Z")

</div>

For another view…I use it all the time. I don’t mind having users have to configure multiple times to make things appear. The alternative is to have things like `message(FATAL_ERROR)` if an incompatible flag setup is encountered. I prefer for cache variables to have concrete effects rather than being silently ignored (see below) because I’ve gotten a lot of reports over time asking “why doesn’t this flag I found in the editor seem to do anything?” when the answer ends up being “it’s ignored because it makes no sense given that you also disabled feature X”.

Below: Of course, this doesn’t help `-D` on the command line from being ignored, but scripted cases should have more doc-based research behind their decisions…
