Introduce a cmake policy system for the dune build system
Summary
Get and set dune policies to control changes in behavior of the dune build system. A policy
is by default set to OLD
if not set otherwise, except if the policy's activation version
is reached. Each policy can specify when it is set automatically to NEW
. The default behavior
can be influenced by the global cmake variable DUNE_POLICY_DEFAULT
.
Introducing a policy
In order to define/introduce a policy (a module property to identify whether an old or new build system behavior should be activated), one has to introduce an identifier in e.g. the Dune<Module>Macros.cmake
file, i.e., in a file that is exported to downstream modules so that they can set the policy value later:
dune_define_policy(<policy> <module> <version> "Documentation of the changed behavior")
- The first argument is an ID. It typically starts with "DP" for "Dune-Policy" and then comes a 4 digit number, e.g. "DP0042". This follows the pattern used in cmake. This identifier format is not checked, though. Thus a downstream module can introduce other names for their policies.
- The second argument is the dune module, e.g.,
DUNE_COMMON
, that the change in behavior is implemented in and also the version should be checked for. If the<version>
given in the third argument is reached in that dune module, the policy is set to "NEW" by default. - The last argument is a documentation string that is shown whenever the user is requested to set explicitly the policy value, e.g., if the module version is not reached.
Getting and setting a policy value
The policy's value change be changed. By default it is OLD
(except of the global variable DUNE_POLICY_DEFAULT
is set to something else). The value of a policy can be asked for by
dune_policy(GET <policy> <var>)
the result is stored in the variable <var>
.
If a module author want to change the default policy value, she can set the value by
dune_policy(SET <policy> <value>)
This change should be module-local (not in the Dune<Module>Macros.cmake
file) so that downstream modules can make their own change
Example
The motivation to introduce a policy system into dune came from a change in the dune_add_test
macro. We want to change the behavior that add_dune_all_flags
is called on all test targets by default. The new behavior would be not to do this. Thus, we introduce a first policy:
dune_define_policy(DP0001 DUNE_COMMON 2.11
"Do not call add_dune_all_flags for a target created with dune_add_test.")
And inside the dune_add_test
macro, we implement the change conditionally:
if(ADDTEST_SOURCES)
add_executable(${ADDTEST_NAME} ${ADDTEST_SOURCES})
# add all flags to the target!
dune_policy(GET DP0001 _add_all_flags)
if(_add_all_flags STREQUAL "OLD")
add_dune_all_flags(${ADDTEST_NAME})
endif()
endif()
Documentation
Whenever a new policy is introduced in the dune-common module, a corresponding entry should be added to doc/buildsystem/dune-common.rst
. A similar documentation is suggested for all modules that introduce their own policies.