# block(PROPAGATE) doesn't set in the parent directory?

**URL:** <https://discourse.cmake.org/t/block-propagate-doesnt-set-in-the-parent-directory/9853>\
**Category:** Code\
**Created:** [January 15, 2024, 11:26am UTC](https://discourse.cmake.org/t/block-propagate-doesnt-set-in-the-parent-directory/9853 "2024-01-15T11:26:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![tambre](https://discourse.cmake.org/user_avatar/discourse.cmake.org/tambre/32/5127_2.png) [@tambre](https://discourse.cmake.org/u/tambre)\
**Post date:** [January 15, 2024, 11:26am UTC](https://discourse.cmake.org/t/block-propagate-doesnt-set-in-the-parent-directory/9853/1 "2024-01-15T11:26:48Z")

</div>

The documentation for `set()` says:

> The [`block(PROPAGATE)`](https://cmake.org/cmake/help/latest/command/block.html#command:block) and [`return(PROPAGATE)`](https://cmake.org/cmake/help/latest/command/return.html#command:return) commands can be used as an alternate method to the [`set(PARENT_SCOPE)`](https://cmake.org/cmake/help/latest/command/set.html#command:set) and [`unset(PARENT_SCOPE)`](https://cmake.org/cmake/help/latest/command/unset.html#command:unset) commands to update the parent scope.

Which to me sounds like I can replace code in a subdirectory of the from:

```auto
set(example value)
set(example ${example} PARENT_SCOPE)

```

with:

```auto
block(PROPAGATE example)
	set(example value)
endblock()

```

This however creates a new block scope and propagates `example` to the surrounding scope, not the parent directory scope. [propagate\_example.tar](https://discourse.cmake.org/uploads/short-url/1Tv5CYxnrPd1r3pMvQaeB7NjtOu.tar)

Do I understand correctly that the documentation simply suggests `PROPAGATE` as an alternative to `set(PARENT_SCOPE)` in `block()` and there’s no cleaner alternative to `set()`+`set(PARENT_SCOPE)` for use in subdirectories?

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [January 15, 2024, 5:18pm UTC](https://discourse.cmake.org/t/block-propagate-doesnt-set-in-the-parent-directory/9853/2 "2024-01-15T17:18:36Z")

</div>

The `PROPAGATE` option ensure the listed variables are propagated to the parent scope of the scope created by the `block()` command.

So the following two snippets are equivalents:

```cmake
block()
  set(MY_VAR "some value")
  set(MY_VAR "${MY_VAR}" PARENT_SCOPE)
endblock()
# here, MY_VAR has value "some value"

```

and

```cmake
block(PROPAGATE MY_VAR)
  set(MY_VAR "some value")
endblock()
# here, MY_VAR has value "some value"

```

To propagate variables to the parent directory scope, `return(PROPAGATE)` command can be used.

---

<div class="post-metadata">

**Author:** ![tambre](https://discourse.cmake.org/user_avatar/discourse.cmake.org/tambre/32/5127_2.png) [@tambre](https://discourse.cmake.org/u/tambre)\
**Post date:** [January 18, 2024, 10:11am UTC](https://discourse.cmake.org/t/block-propagate-doesnt-set-in-the-parent-directory/9853/3 "2024-01-18T10:11:21Z")

</div>

> [@marc.chevrier](#):
>
> To propagate variables to the parent directory scope, `return(PROPAGATE)` command can be used.

That would be perfect except it causes warnings when the `CMakeLists.txt` using `return(PROPAGATE)` is the top-level one.

As such I’ve gone with the following macro:

```auto
macro(set_propagate variable value)
	set(${variable} ${value})

	# Avoid warnings
	if(NOT PROJECT_IS_TOP_LEVEL)
		set(${variable} ${value} PARENT_SCOPE)
	endif()
endmacro()

```

Basically I have a project that should be able to built separately, but also included as a Git submodule in other projects as `add_subdirectory()`.
