stdlib

Fortran Standard Library

Actions Status Actions Status

Goals and Motivation

The Fortran Standard, as published by the ISO (https://wg5-fortran.org/), does not have a Standard Library. The goal of this project is to provide a community driven and agreed upon de facto “standard” library for Fortran, called a Fortran Standard Library (stdlib). We have a rigorous process how stdlib is developed as documented in our Workflow. stdlib is both a specification and a reference implementation. We are cooperating with the Fortran Standards Committee (e.g., the effort started at the J3 committee repository) and the plan is to continue working with the Committee in the future (such as in the step 5. in the Workflow document), so that if the Committee wants to standardize some feature already available in stdlib, it would base it on stdlib’s implementation.

Scope

The goal of the Fortran Standard Library is to achieve the following general scope:

Getting started

Get the code

git clone https://github.com/fortran-lang/stdlib
cd stdlib

Requirements

To build the Fortran standard library you need

If your system package manager does not provide the required build tools, all build dependencies can be installed with the Python command line installer pip:

pip install --user fypp cmake ninja

Alternatively, you can install the build tools from the conda-forge channel with the conda package manager:

conda config --add channels conda-forge
conda create -n stdlib-tools fypp cmake ninja
conda activate stdlib-tools

You can install conda using the miniforge installer. Also, you can install a Fortran compiler from conda-forge by installing the fortran-compiler package, which installs GFortran.

Supported Compilers

The following combinations are tested on the default branch of stdlib:

Name Version Platform Architecture
GCC Fortran 10, 11, 12, 13 Ubuntu 22.04.2 LTS x86_64
GCC Fortran 10, 11, 12, 13 macOS 12.6.3 (21G419) x86_64
GCC Fortran (MSYS) 13 Windows Server 2022 (10.0.20348 Build 1547) x86_64
GCC Fortran (MinGW) 13 Windows Server 2022 (10.0.20348 Build 1547) x86_64, i686
Intel oneAPI LLVM 2024.0 Ubuntu 22.04.2 LTS x86_64
Intel oneAPI classic 2023.1 macOS 12.6.3 (21G419) x86_64

The following combinations are known to work, but they are not tested in the CI:

Name Version Platform Architecture
GCC Fortran (MinGW) 9.3.0, 10.2.0, 11.2.0 Windows 10 x86_64, i686

We try to test as many available compilers and platforms as possible. A list of tested compilers which are currently not working and the respective issue are listed below.

Name Version Platform Architecture Status
GCC Fortran <9 any any #296, #430
NVIDIA HPC SDK 20.7, 20.9, 20.11 Manjaro Linux 20 x86_64 #107
NAG 7.0 RHEL x86_64 #108
Intel Parallel Studio XE 16, 17, 18 OpenSUSE x86_64 failed to compile

Please share your experience with successful and failing builds for compiler/platform/architecture combinations not covered above.

Build with CMake

Configure the build with

cmake -B build

You can pass additional options to CMake to customize the build. Important options are

For example, to configure a build using the Ninja backend while specifying compiler optimization via FFLAGS, generating procedures up to rank 7, installing to your home directory, using the NoConfig compiler flags, and printing the compiler commands, use

export FFLAGS="-O3"
cmake -B build -G Ninja -DCMAKE_MAXIMUM_RANK:String=7 -DCMAKE_INSTALL_PREFIX=$HOME/.local -DCMAKE_VERBOSE_MAKEFILE=On -DCMAKE_BUILD_TYPE=NoConfig

To build the standard library run

cmake --build build

To test your build, run the test suite and all example programs after the build has finished with

cmake --build build --target test

To test only the test suite, run

ctest --test-dir build/test

Please report failing tests on our issue tracker including details of the compiler used, the operating system and platform architecture.

To install the project to the declared prefix run

cmake --install build

Now you have a working version of stdlib you can use for your project.

If at some point you wish to recompile stdlib with different options, you might want to delete the build folder. This will ensure that cached variables from earlier builds do not affect the new build.

Build with fortran-lang/fpm

Fortran Package Manager (fpm) is a package manager and build system for Fortran.
You can build stdlib using provided fpm.toml:

Option 1: From root folder

As fpm does not currently support fypp natively, stdlib now proposes a python script to preprocess and build it. This script enables modification of the different fypp macros available in stdlib. The preprocessed files will be dumped at <current_folder>/temp/*.f90 or *.F90.

Make sure to install the dependencies from the requirement.txt

pip install --upgrade -r config/requirements.txt

To build, you can use the following command line:

python config/fypp_deployment.py
fpm build --profile release

or the short-cut

python config/fypp_deployment.py --build

To modify the maxrank macro for instance:

python config/fypp_deployment.py --maxrank 7 --build

To see all the options:

python config/fypp_deployment.py --help

Note: If you use a compiler different than GNU compilers, the script will try to catch it from the environment variables FPM_FC, FPM_CC, FPM_CXX.

Option 2: From the stdlib-fpm branch which has already been preprocessed with default macros:

git checkout stdlib-fpm
fpm build --profile release

Installing with fpm

Either option you chose for building the stdlib, you can install it with:

fpm install --profile release

The command above will install the following files:

You can change the installation path by setting the prefix option to fpm:

fpm install --profile release --prefix /my/custom/installation/path/

You can use the stdlib by adding the -lstdlib flag to your compiler. If your prefix is a non standard path, add also:

Running the examples

You can run the examples with fpm as:

fpm run --example prog

with prog being the name of the example program (e.g., example_sort).

Using stdlib in your project

Using stdlib with CMake

The stdlib project exports CMake package files and pkg-config files to make stdlib usable for other projects. The package files are located in the library directory in the installation prefix.

For CMake builds of stdlib you can find a local installation with

find_package(fortran_stdlib REQUIRED)
...
target_link_libraries(
  ${PROJECT_NAME}
  PRIVATE
  fortran_stdlib::fortran_stdlib
)

To make the installed stdlib project discoverable add the stdlib directory to the CMAKE_PREFIX_PATH. The usual install location of the package files is $PREFIX/lib/cmake/fortran_stdlib.

Using stdlib with fpm

To use stdlib within your fpm project, add the following lines to your fpm.toml file:

[dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm" }

Warning

Fpm 0.9.0 and later implements stdlib as a metapackage. To include the standard library metapackage, change the dependency to: stdlib = "*".

see also

Using stdlib with a regular Makefile

After the library has been built, it can be included in a regular Makefile. The recommended way to do this is using the pkg-config tool, for which an example is shown below.

# Necessary if the installation directory is not in PKG_CONFIG_PATH
install_dir := path/to/install_dir
export PKG_CONFIG_PATH := $(install_dir)/lib/pkgconfig:$(PKG_CONFIG_PATH)

STDLIB_CFLAGS := `pkg-config --cflags fortran_stdlib`
STDLIB_LIBS := `pkg-config --libs fortran_stdlib`

# Example definition of Fortran compiler and flags
FC := gfortran
FFLAGS := -O2 -Wall -g

# Definition of targets etc.
...

# Example rule to compile object files from .f90 files
%.o: %.f90
    $(FC) -c -o $@ $< $(FFLAGS) $(STDLIB_CFLAGS)

# Example rule to link an executable from object files
%: %.o
    $(FC) -o $@ $^ $(FFLAGS) $(STDLIB_LIBS)

The same can also be achieved without pkg-config. If the library has been installed in a directory inside the compiler’s search path, only a flag -lfortran_stdlib is required. If the installation directory is not in the compiler’s search path, one can add for example

install_dir := path/to/install_dir
libdir := $(install_dir)/lib
moduledir := $(install_dir)/include/fortran_stdlib/<compiler name and version>

The linker should then look for libraries in libdir (using e.g.-L$(libdir)) and the compiler should look for module files in moduledir (using e.g. -I$(moduledir)). Alternatively, the library can also be included from a build directory without installation with

build_dir := path/to/build_dir
libdir := $(build_dir)/src
moduledir := $(build_dir)/src/mod_files

Documentation

Documentation is a work in progress (see issue #4) but already available at stdlib.fortran-lang.org. This includes API documentation automatically generated from static analysis and markup comments in the source files using the FORD tool, as well as a specification document or “spec” for each proposed feature.

Some discussions and prototypes of proposed APIs along with a list of popular open source Fortran projects are available on the wiki.

BLAS and LAPACK

stdlib ships full versions of BLAS and LAPACK, for all real and complex kinds, through generalized interface modules stdlib_linalg_blas and stdlib_linalg_lapack. The 32- and 64-bit implementations may be replaced by external optimized libraries if available, which may allow for faster code. When linking against external BLAS/LAPACK libraries, the user should define macros STDLIB_EXTERNAL_BLAS and STDLIB_EXTERNAL_LAPACK, to ensure that the external library version is used instead of the internal implementation.

Support for 64-bit integer size interfaces of all BLAS and LAPACK procedures may also be enabled by setting the CMake flag -DWITH_ILP64=True. The 64-bit integer version is always built in addition to the 32-bit integer version, that is always available. Additional macros STDLIB_EXTERNAL_BLAS_I64 and STDLIB_EXTERNAL_LAPACK_I64
may be defined to link against an external 64-bit integer library, such as Intel MKL.

Contributing