Open certik opened 4 years ago
I would lean towards option 1 as being easier to implement in fpm. It just doesn't fetch and build optional dependencies unless specified, and only defines the environment variables for the ones specified.
With option 2, the build process has to be able to make decisions about which source file gets used to satisfy a given module. This requires us to modify/extend our current naming conventions with regards to source file name and module name.
I definitely see the need for such a feature, and I think we should definitely try and tackle this at some point.
See a recent discussion about this feature: https://fortran-lang.discourse.group/t/optional-dependencies-with-fpm/8538.
It is extremely common to have optional dependencies in Fortran projects (see the examples section at the end of this description).
The way Cargo handles it is described in here: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
it seems it is somehow tied to "features" that one can enable somehow, but I don't yet understand the full mechanism. Also there must be some way to propagate this "feature" on/off status inside the code using some macros or something.
In Fortran, I can see at least two ways to implemented it, are there more?
We can define some pre-processor definitions and use
#ifdef
to enable certain code if an optional dependency is used. We can support multiple pre-processors (cpp, fypp, ...).One can do it at the module level: I sometimes have two files, say, openmp.f90 and openmp.dum.f90 both of which implement the
openmp
module, so the rest of the Fortran code justuse openmp
no matter what, and only one of the two files is compiled and linked in the buildsystem:The advantage of 2. is that you do not have to use any pre-processor, which I try to avoid in my codes. The advantage of 1. is that it's simpler in some ways, you just put a few ifdefs in your code. I think
fpm
can support either one, or both.fpm
could for example create some module, sayoptional_dependencies
and export some variable or a function such asopenmp_enabled
for the "openmp" feature, that you can call in your code and make some decisions.Either way, we should figure out how to make
fpm
support optional dependencies and features that the user can configure.Examples
Example 1
A typical example is a large electronic structure code, that provides its own default exchange correlation functional, but optionally allows to link against the libxc library, in which case one must enable and link against it and some code paths are different (typically some Fortran modules are enabled / disabled) and it allows the code to use functionals from the libxc library.
Example 2
There are many linear and eigensolver libraries, and there is typically some default, but if the user installs a particular 3rd party solver, it can optionally enable it in the Fortran program to use it instead.