Skip to content

Introduce a cmake policy system for the dune build system

Simon Praetorius requested to merge feature/dune-cmake-policies into master

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.

Edited by Simon Praetorius

Merge request reports