Skip to content

fortran-lang/stdlib

Repository files navigation

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:

  • Utilities (containers, strings, files, OS/environment integration, unit testing & assertions, logging, ...)
  • Algorithms (searching and sorting, merging, ...)
  • Mathematics (linear algebra, sparse matrices, special functions, fast Fourier transform, random numbers, statistics, ordinary differential equations, numerical integration, optimization, ...)

Getting started

Get the code

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

Requirements

To build the Fortran standard library you need

  • a Fortran 2008 compliant compiler, or better, a Fortran 2018 compliant compiler (GCC Fortran and Intel Fortran compilers are known to work for stdlib)
  • CMake version 3.14 or newer (alternatively Make can be used)
  • a build backend for CMake, like Make or Ninja (the latter is recommended on Windows)
  • the fypp preprocessor (used as meta-programming tool)

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

  • -G Ninja to use the Ninja backend instead of the default Make backend. Other build backends are available with a similar syntax.
  • -DCMAKE_INSTALL_PREFIX is used to provide the install location for the library. If not provided the defaults will depend on your operating system, see here.
  • -DCMAKE_MAXIMUM_RANK the maximum array rank procedures should be generated for. The default value is chosen as 4. The maximum is 15 for Fortran 2003 compliant compilers, otherwise 7 for compilers not supporting Fortran 2003 completely yet. The minimum required rank to compile this project is 4. Compiling with maximum rank 15 can be resource intensive and requires at least 16 GB of memory to allow parallel compilation or 4 GB memory for sequential compilation.
  • -DBUILD_SHARED_LIBS set to on in case you want link your application dynamically against the standard library (default: off).
  • -DBUILD_TESTING set to off in case you want to disable the stdlib tests (default: on).
  • -DCMAKE_VERBOSE_MAKEFILE is by default set to Off, but if set to On will show commands used to compile the code.
  • -DCMAKE_BUILD_TYPE is by default set to RelWithDebInfo, which uses compiler flags suitable for code development (but with only -O2 optimization). Beware the compiler flags set this way will override any compiler flags specified via FFLAGS. To prevent this, use -DCMAKE_BUILD_TYPE=NoConfig in conjunction with FFLAGS.

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:

  • libstdlib.a into ~/.local/lib/ (Unix) or C:\Users\<username>\AppData\Roaming\local\lib\ (Windows)
  • all the .[s]mod files produced by the compiler into ~/.local/include/ (Unix) or C:\Users\<username>\AppData\Roaming\local\include\ (Windows)

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:

  • -L/my/custom/installation/path/lib
  • -I/my/custom/installation/path/include

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.

Contributing

Links