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

The documentation for set() says:

The block(PROPAGATE) and return(PROPAGATE) commands can be used as an alternate method to the set(PARENT_SCOPE) and unset(PARENT_SCOPE) commands to update the parent scope.

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

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

with:

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

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?

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:

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

and

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.

1 Like

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:

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().