# \`cmake\_policy\` get overwritten by \`cmake\_minimum\_required()\`

**URL:** https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097
**Category:** Usage
**Created:** [April 7, 2021, 7:25pm UTC](https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097 "2021-04-07T19:25:57Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Kerstin\_Keller](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kerstin_keller/32/180_2.png) [@Kerstin\_Keller](https://discourse.cmake.org/u/Kerstin_Keller)
#### Post date: [April 7, 2021, 7:25pm UTC](https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097/1 "2021-04-07T19:25:57Z")

</div>

I have the usecase that I want to include a subproject, and set some variables for options of that subproject. With policy 0077 set to new, I can do that. However I am experiencing some problems, that somehow setting the policy gets overwritten by the `cmake_minimum_required` of the subpreject.  
I narrowed it to a minimal example:

CMakeLists.txt

```auto
cmake_minimum_required(VERSION 3.15)

project(base)

cmake_policy(SET CMP0077 NEW)
cmake_policy(GET CMP0077 _POLICY_0077)
message(STATUS "POLICY is ${_POLICY_0077}")

set(MY_OPTION OFF)

add_subdirectory(project)

```

project/CMakeLists.txt

```auto
cmake_minimum_required(VERSION 3.5)

project(my_proj)

cmake_policy(GET CMP0077 _POLICY_0077)
message(STATUS "POLICY is ${_POLICY_0077}")

option(MY_OPTION ON)
message(STATUS "MY_OPTION ${MY_OPTION}")

```

Running CMake prints:

```auto
-- POLICY is NEW
-- POLICY is
CMake Warning (dev) at project/CMakeLists.txt:8 (option):
  Policy CMP0077 is not set: option() honors normal variables. Run "cmake
  --help-policy CMP0077" for policy details. Use the cmake_policy command to
  set the policy and suppress this warning.

  For compatibility with older versions of CMake, option is clearing the
  normal variable 'MY_OPTION'.
This warning is for project developers. Use -Wno-dev to suppress it.
-- MY_OPTION OFF

```

I would expect that setting the policy in the top level CMake file would persist over all files included with `add_subdirectory()`.  
Thus I would expect that CMake should twice print `POLICY is NEW`, and not only once.  
Obviously, I cannot change the `project/CMakeLists.txt` when including e.g. a thirdparty library or such.

And the weirdest thing is, that apparently, it does actually honor the variable, since the output prints “OFF”.  
Any thougths?

---

<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: [April 7, 2021, 8:48pm UTC](https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097/2 "2021-04-07T20:48:17Z")

</div>

Yes, [the docs](https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html#policy-settings) mention that:

> The cmake\_minimum\_required(VERSION) command implicitly invokes the cmake\_policy(VERSION) command to specify that the current project code is written for the given range of CMake versions.

so it can “unset” policies that you have set to `NEW` within its policy scope (which doesn’t necessarily match directory or function scope).

---

<div class="post-metadata">

### Author: ![Kerstin\_Keller](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kerstin_keller/32/180_2.png) [@Kerstin\_Keller](https://discourse.cmake.org/u/Kerstin_Keller)
#### Post date: [April 7, 2021, 9:53pm UTC](https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097/3 "2021-04-07T21:53:18Z")

</div>

Ok, so then what exactly is the `policy_scope`?

And one thing especially strikes me: while the warning suggests that the option is honored (which would result in `MY_OPTION ON`), the CMake output `MY_OPTION OFF` suggests that the variable is honored instead.

So what now? Why is there a warning if it doesn’t behave according to the warning, or am I getting things wrong here?

---

<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: [April 8, 2021, 12:09am UTC](https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097/4 "2021-04-08T00:09:55Z")

</div>

> [@Kerstin\_Keller](#):
>
> Ok, so then what exactly is the `policy_scope`?

Honestly, I can’t say that I really understand it either. I know that `cmake_policy(PUSH)` and `cmake_policy(POP)`. They’re also “sticky” to function/macro definitions rather than inheriting. Generally, I avoid calling `cmake_minimum_required` more than once in a project if at all possible, but when importing third party code, it gets patched (for various reasons) anyways, so it’s “just another thing to do” there.

> [@Kerstin\_Keller](#):
>
> And one thing especially strikes me: while the warning suggests that the option is honored (which would result in `MY_OPTION ON`), the CMake output `MY_OPTION OFF` suggests that the variable is honored instead.

Cache behavior on first vs. second configure is very odd. I suspect that’s where the behavior actually gets confusing. See [this issue](https://gitlab.kitware.com/cmake/cmake/-/issues/22038) for discussion on (finally) changing this behavior.

---

<div class="post-metadata">

### Author: ![Kerstin\_Keller](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kerstin_keller/32/180_2.png) [@Kerstin\_Keller](https://discourse.cmake.org/u/Kerstin_Keller)
#### Post date: [April 8, 2021, 12:02pm UTC](https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097/5 "2021-04-08T12:02:34Z")

</div>

Thanks for clarifying. Any idea what to do when i can’t patch the subproject? Probably the old “overwrite with a macro” trick?

```auto
macro(cmake_minimum_required)
endmacro()

```

Though I do hate that approach (and obiously, only re/un-define after the first call). We ofthen do that “trick” with redefining the `find_package` command, to opt in / out on submole builds.

However, my usecase is a bit special here, as I will be generating the top level CMake file.  
Maybe I can get around this by instead using the new CMakePresets.json file. Then I won’t need to set variables to override options, but instead pass options through the CMakePresets.json file.

---

<div class="post-metadata">

### Author: ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)
#### Post date: [April 8, 2021, 12:56pm UTC](https://discourse.cmake.org/t/cmake-policy-get-overwritten-by-cmake-minimum-required/3097/6 "2021-04-08T12:56:38Z")

</div>

Depending on your CMake version this might help:  
[https://cmake.org/cmake/help/latest/variable/CMAKE\_PROJECT\_PROJECT-NAME\_INCLUDE\_BEFORE.html](https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.html)
