# How to determine when set(var ... PARENT\_SCOPE) will work?

**URL:** <https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795>\
**Category:** Code\
**Created:** [September 8, 2020, 3:43pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795 "2020-09-08T15:43:10Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![webbtrail](https://discourse.cmake.org/user_avatar/discourse.cmake.org/webbtrail/32/818_2.png) [@webbtrail](https://discourse.cmake.org/u/webbtrail)\
**Post date:** [September 8, 2020, 3:43pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795/1 "2020-09-08T15:43:10Z")

</div>

I want an included .cmake file to pass/update variables in the PARENT\_SCOPE. What is the best way to determine that set(var value PARENT\_SCOPE) will work before it is used?  
has\_parent(HAS\_PARENT)  
if(HAS\_PARENT)  
set(parent\_var value PARENT\_SCOPE)  
endif()

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [September 8, 2020, 3:52pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795/2 "2020-09-08T15:52:31Z")

</div>

You could probably whip up something based on `if(CMAKE_CURRENT_LIST_FILE STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt")`, that is, check if the currently processed file is `CMakeLists.txt` in the current project directory. If not, it should be a file `include()`d from somewhere.

---

<div class="post-metadata">

**Author:** ![webbtrail](https://discourse.cmake.org/user_avatar/discourse.cmake.org/webbtrail/32/818_2.png) [@webbtrail](https://discourse.cmake.org/u/webbtrail)\
**Post date:** [September 8, 2020, 3:54pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795/3 "2020-09-08T15:54:15Z")

</div>

Shouldn’t an include file from an included file also be able to set(… PARENT\_SCOPE)? I have tried that method and it doesn’t supported a nested approach.

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [September 8, 2020, 3:55pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795/4 "2020-09-08T15:55:33Z")

</div>

Odd, that should work. The condition I wrote should only hold if you’re NOT in an included file. If you are in an included file (however deep), it should be FALSE.

---

<div class="post-metadata">

**Author:** ![webbtrail](https://discourse.cmake.org/user_avatar/discourse.cmake.org/webbtrail/32/818_2.png) [@webbtrail](https://discourse.cmake.org/u/webbtrail)\
**Post date:** [September 8, 2020, 4:20pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795/5 "2020-09-08T16:20:00Z")

</div>

A file can be parsed as part of add\_directory() or include(). Either of these entry points can in turn use include(). Within the included file ‘${CMAKE\_CURRENT\_LIST\_FILE}’ would be the name of the file being included (e.g., foo.cmake).  
A file include()'d by the top-most CMakeLists.txt file **Can Not** use set(… PARENT\_SCOPE) without a warning, and ‘${CMAKE\_CURRENT\_SOURCE\_DIR}/CMakeLists.txt’ would point to that top-most CMakeLists.txt file.  
After a single add\_directory(), the same include()'d file, **Can** use set(… PARENT\_SCOPE) without a warning, and ‘${CMAKE\_CURRENT\_SOURCE\_DIR}/CMakeLists.txt’ would point to the main file of that add\_directory() sub-folder.  
Scripting Mode is also being used my project, and it can also include() a file which might want to set(… PARENT\_SCOPE).  
I would like a general solution. I have a hacked together working instance at the moment.  
Thx

---

<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:** [September 8, 2020, 10:18pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795/6 "2020-09-08T22:18:49Z")

</div>

You could try `CMAKE_PARENT_LIST_FILE`, although I don’t recall what it does for the top level directory. I seem to recall hitting what seemed like a bug related to it many years ago but never got the chance to follow up on it. You could try it out and see if it helps for your use case.

---

<div class="post-metadata">

**Author:** ![fdk17](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/ea666f/32.png) [@fdk17](https://discourse.cmake.org/u/fdk17)\
**Post date:** [September 9, 2020, 3:31pm UTC](https://discourse.cmake.org/t/how-to-determine-when-set-var-parent-scope-will-work/1795/7 "2020-09-09T15:31:46Z")

</div>

According to CMake Variable documentation you have Directory, Function, and cache scope. Using `include()` doesn’t create a new scope it is supposed to keep the current directory scope. `add_subdirectory()` is supposed to add an new Directory level.

So in a function PARENT\_SCOPE should always work.

That leaves tracking if the current directory is the same as the top level directory. So if `CMAKE_CURRENT_SOURCE_DIR` is equal to `CMAKE_SOURCE_DIR` then there is no parent.

From the documentation of `include`:  
Loads and runs CMake code from the file given. Variable reads and writes access the scope of the caller (dynamic scoping).

I’ve checked that `CMAKE_CURRENT_SOURCE_DIR` keeps the correct directory name in files that were included using the `include()` command as expected, the variable `CMAKE_CURRENT_LIST_DIR` is updated to track the directory of the included file.

But if this item could be included in both a function or a normal directory then you need to sort out if you are running in the context of a function. `CMAKE_CURRENT_FUNCTION` may be helpful in that case.
