fortran-lang / fpm

Fortran Package Manager (fpm)
https://fpm.fortran-lang.org
MIT License
869 stars 97 forks source link

Metapackages #853

Closed perazz closed 1 year ago

perazz commented 1 year ago

Motivation

I'm opening a specification proposal for metapackages for fpm. This arises on the attempt of addressing #161.

Many fortran programs use "packages" that offer several implementations but a common API, e.g., OpenMP/acceleration, CoArrays, MPI, netCDF, stdlib, etc. Some of them are libraries that need to be pre-built and linked, some are available based on the current platform, some can be turned on with appropriate compiler flags, etc.

The fpm user should see none of that, and as suggested in #161, they should be able to enable these "features" with the most syntactically simple flags in fpm.toml.

The way I suggest fpm could handle those is via metapackages, i.e., configuration wrappers that 1) check whether they're available on the system and current compiler; 2) where possible, they add them as dependencies to download/build them; 3) ensure the package is built with all proper inputs and flags.

As each compiler/system could require different commands, I think we should start from the base platforms and gradually make more and more options available.

So I'm opening this as an issue here. Please, let's improve over this idea and see if it fits our needs as users!

Specification

I would start simple with a specification that enables whether the metapackage is requested or not. It seems reasonable that it is a feature of the whole package (at least in its first implementation), so it could be added to the build section, like it's done for the external modules already:

[build]
openmp=true
coarray=true

later, version specifications could be added to the same flag:

[build]
mpi="^3.0"

Internally, I see a metapackage_t that, when queried, assembles the necessary build commands and adds dependencies to the manifest:

type :: metapackage_t

    logical :: has_library
    logical :: has_compiler_flags

    type(string_t), allocatable :: fflags(:)
    type(string_t), allocatable :: link_flags(:)
    type(string_t), allocatable :: link_dirs(:)

    ! [etc.] 

    contains
    procedure :: is_available
    procedure :: add_deps1
    procedure :: add_linker_commands
    ! [etc.]
end type

Each instance is constructed on fpm bootstrap, and we will need to have one well-framed constructor subroutine for each metapackage, as part of the local fpm config:

type(metapackage_t) :: openmp
type(metapackage_t) :: coarrays
type(metapackage_t) :: mpi

Maybe down the road we could enable .toml files to be built to/from these configs, to allow the users to manually edit them, but as a first shot, I'd just provide one working version that's available on the system and make it work first.

Prior Art

No response

Additional Information

perazz commented 1 year ago

Closing for now, as the first implementation has been merged.