Skip to content

Add brief explanation on how to include stdlib in a Makefile #781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 63 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,30 @@ 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

```cmake
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:
```toml
[dependencies]
Expand All @@ -215,25 +239,51 @@ stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm" }
>
> [see also](https://fpm.fortran-lang.org/spec/metapackages.html)

## Using stdlib in your project
### Using stdlib with a regular Makefile

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.
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](https://www.freedesktop.org/wiki/Software/pkg-config/) tool, for which an example is shown below.
```make
# 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)

For CMake builds of stdlib you can find a local installation with
STDLIB_CFLAGS := `pkg-config --cflags fortran_stdlib`
STDLIB_LIBS := `pkg-config --libs fortran_stdlib`

```cmake
find_package(fortran_stdlib REQUIRED)
# Example definition of Fortran compiler and flags
FC := gfortran
FFLAGS := -O2 -Wall -g

# Definition of targets etc.
...
target_link_libraries(
${PROJECT_NAME}
PRIVATE
fortran_stdlib::fortran_stdlib
)

# 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)

```

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``.
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
```make
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
```make
build_dir := path/to/build_dir
libdir := $(build_dir)/src
moduledir := $(build_dir)/src/mod_files
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it would be good to see an example of how libdir and moduledir would be used inside the makefile to affect the compiler flags.


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a something like below, to cover the case of compiling in a shell script or naively from the command line? I don't have much expertise on build systems, and often write small scripts to build programs.

Using stdlib when compiling within a script, or on the command line

This example uses pkg-config to manage the compiler flags.

export PKG_CONFIG_PATH=${install_dir}/lib/pkgconfig:$PKG_CONFIG_PATH
export STDLIB_CFLAGS=$(pkg-config --cflags fortran_stdlib)
export STDLIB_LIBS=$(pkg-config --libs fortran_stdlib)

export FC=gfortran
export FFLAGS="-O3 -flto"

# Compile
$FC $FFLAGS -c $STDLIB_CFLAGS my_program.f90
# Link
$FC $FFLAGS -o my_program my_program.o $STDLIB_LIBS 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the information on pkg-config would certainly be nice to include as well, I can do that. I am a little hesitant to include actual compile rules, since these will depend on the particular compiler used and perhaps also on other things. To explain this clearly to people who are not familiar with Makefiles and compilation rules could take too much space. Instead, it could be nice to include a few worked-out usage examples with Makefiles in a separate location.

## Documentation

Expand Down