handling of `config.h` (proposal for dev-meeting 22.1.2021)
As discussed on the last dev-meeting, there are some issues with how we currently work with config.h DUNE. Our usage pattern requires all dependent applications to use the DUNE buildsystem, which is not nice.
The aim is now to clean up this part of the buildsystem.
Long term perspective to remove config.h
The config.h is an artifact from autotools time. As part of the autotools workflow it was automatically generated in each module or project building on top of DUNE.
In our effort to support simpler work flows for derived projects (see #199 (closed) and #188) we now face the problem, that such projects will not be able to generate the required config.h. Thus we need an alterantive way to "remember" which features are enabled and which not.
The first indea to install the config.h is not practical, as
- there is not the one and only
config.h, but they are a collection of defines from different modules and their dependencies - our
config.hmight interfere with aconfig.hgenerated in the user project
The goal of this proposal is to eventually remove config.h completely.
Discussion
The current config.h serves a mixture of different purposes:
- it collects a set of
HAVE_FOOdefines, which correspond to detected features - some
HAVE_FOOflags map toENABLE_FOOto allow enabling/disabling features for individual targets inside a project - preprocessor macros, which change their behaviour, depending on the results of configure checks (e.g.
LAPACK_MANGLE)
This is kind of orthogonal to the handling of dependencies, where we define target (either real cmake targets or pkg-config files) for each module.
Many of the detected features are not used at all in DUNE, so we don't need to include these.
Possible solutions
HAVE_FOO defines
Those defines that are necessary, i.e. they change the behaviour or DUNE headers, should be passed as command line arguments.
Optional: rename HAVE_FOO
The current preprocessor defines HAVE_FOO are very generic and as such the chances of collisions exist.
Thus the more far-reaching proposal is that we replace the defines with DUNE specific one, e.g. DUNE_WITH_FOO or DUNE_ENABLE_FOO.
As, in the first transition period the config.h is present anyway, we can use it to
- warn about the deprecation of
config.h - warn about the deprecation of
HAVE_FOO - and provide a fallback definition
#if DUNE_WITH_FOO
#define HAVE_FOO`
#endif
ENABLE_FOO magic
The ENABLE_FOO magic had the goal to have something like target dependent defines.
For example, consider the case that some targets should link against suitesparse and some not. The dune-istl headers will change their behaviour, depending on the presence of suitesparse.
As we now have cmake targets we can introduce an auxiliary target dune-istl-suitesparse. This target should then define the ENABLE_SUITESPARSE or directly HAVE_SUITESPARSE (or DUNE_WITH_SUITESPARSE) and have suitesparse as a dependency itself. The idea behind the naming is that this does not only mean that we use suitesparse, but we use the dune interface to suitesparse. An application would then add dune-suitesparse as a dependency.
We can follow the same approach for pkg-config and introduce explicitly these targets as pc files. By this it is possible for an application outside the DUNE buildsystem specify dependencies and get the necessary flags with a call like
pkg-config --clags dune-istl dune-istl-suitesparse
Note: The above example should not imply that we necessarily plan to have suitesparse as a separate target.
additional macros
We should move these macros into separate headers, which are then included where ever needed.
For LAPACK_MANGLE the snippet
#ifdef LAPACK_NEEDS_UNDERLINE
#define LAPACK_MANGLE(name,NAME) name##_
#else
#define LAPACK_MANGLE(name,NAME) name
#endif
Could simply be moved to a header in dune-common.
For other cases the code is generated. The example we are currently aware are the macros needed for the DUNE_GRID_GRIDTYPE_SELECTOR. Here we can't add this code to a static header, as the code depends on the dune modules found. We argue that this header therefore does not belong into any of the DUNE modules, but it belongs into the leaf module, where the user wants to make use of this features.
We suggest to add a cmake macro that can be called to generate a gridselector.hh in the BUILD_DIR of a project.
Note: This does imply that this magic can't be used without the DUNE buildsystem, but that is also the case now.
Final proposal
Summarizing the above discussion, we suggest the following solution
- every DUNE module provides its own target (both
cmakeandpkg-config... this is planned anyway) - any
HAVE_FOOflags are added to theCFLAGSof the corresponding target - the
HAVE_FOOflags get renamed to something DUNE specific -
config.hwill be deprecated and only contains some code to ensure backwards compatibility - any
ENABLE_FOOshould become a corresponding target or be enabled by default. The correspondingCFLAGSwill then be added to the module target or to the sub-target - any macros in
config.hwill be either moved to separate headers or we introducecmakemacros to generate the required header in theBUILD_DIRor the application module.