How to determine when set(var ... PARENT_SCOPE) will work?

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?
set(parent_var value PARENT_SCOPE)

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.

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.

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.

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.

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.

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.