Skip to content

3. A library ​

quad_rules is meant for other programs too. Two more modes build it as a library, static and shared:

ini
[modes]
modes = debug release static shared

[debug]
help      = Checks on, no optimisation
compiler  = gnu
cflags    = -c -O0 -g -fcheck=all -Wall
src       = ./src/
build_dir = ./build/debug/
target    = src/integrate.F90

[release]
help      = Optimised
compiler  = gnu
cflags    = -c -O2
src       = ./src/
build_dir = ./build/release/
target    = src/integrate.F90

[static]
help        = The library, static
compiler    = gnu
cflags      = -c -O2
src         = ./src/
build_dir   = ./build/static/
target      = src/quad_rules.F90
mklib       = static
output      = libquad.a
track_build = True

[shared]
help        = The library, shared
compiler    = gnu
cflags      = -c -O2 -fPIC
src         = ./src/
build_dir   = ./build/shared/
target      = src/quad_rules.F90
mklib       = shared
output      = libquad.so
track_build = True
  • target is the module's file, mklib the kind of library, output its name.
  • The shared library needs position-independent code: -fPIC.
  • track_build records what the build produced, for fobis install.
  • Each library has its own build_dir: two modes that build the same target into one directory would overwrite each other's record.
console
$ fobis build --mode static --quiet

Building src/quad_rules.F90
Compiling src/quad_rules.F90 serially
Linking build/static/libquad.a
Target src/quad_rules.F90 has been successfully built
Track building of src/quad_rules.F90
console
$ fobis build --mode shared --quiet

Building src/quad_rules.F90
Compiling src/quad_rules.F90 serially
Linking build/shared/libquad.so
Target src/quad_rules.F90 has been successfully built
Track building of src/quad_rules.F90
console
$ find build/static build/shared -type f | sort
build/shared/.quad_rules.F90.track_build
build/shared/libquad.so
build/shared/mod/quad_rules.mod
build/shared/obj/.fobis-compiler.json
build/shared/obj/quad_rules.o
build/static/.quad_rules.F90.track_build
build/static/libquad.a
build/static/mod/quad_rules.mod
build/static/obj/.fobis-compiler.json
build/static/obj/quad_rules.o

The module file quad_rules.mod is part of the library: a program using the library needs it to compile.

fobis build --mode static writes a static library

Recorded on a small demo project, not quad.

Installing ​

fobis install copies what a mode built into a prefix, executables to bin/, libraries to lib/, module files to include/:

console
$ fobis install --mode static --prefix ~/opt/quad && find ~/opt -type f | sort
Install "build/static/libquad.a" in "~/opt/quad/lib"
Install "build/static/mod/quad_rules.mod" in "~/opt/quad/include"
~/opt/quad/include/quad_rules.mod
~/opt/quad/lib/libquad.a

a tracked build installed to a prefix

Recorded on a small demo project, not quad.

Using the installed library ​

Another project, elsewhere, computes the area under a parabola with simpson. Its fobos points the compiler to the installed module file (include) and the linker to the library (lib_dir, ext_libs):

ini
[default]
compiler = gnu
cflags   = -c -O2
include  = ../opt/quad/include
lib_dir  = ../opt/quad/lib
ext_libs = quad
target   = src/area.F90
fortran
!< The area under x**2 on [0, 1], with the installed quad library.
program area
!< The area under x**2 on [0, 1], with the installed quad library.
use quad_rules, only : R8P, simpson
use curves,     only : parabola
implicit none

print '(A, F18.15)', 'area = ', simpson(parabola, 0._R8P, 1._R8P, 2)
endprogram area
fortran
!< The curves whose areas we want.
module curves
!< The curves whose areas we want.
use quad_rules, only : R8P
implicit none
private
public :: parabola

contains
   pure function parabola(x) result(y)
   !< x**2.
   real(R8P), intent(in) :: x !< Abscissa.
   real(R8P)             :: y !< x**2.

   y = x * x
   endfunction parabola
endmodule curves
console
$ cd ~/consumer && fobis build --quiet && ./area
[auto-discover] src not set; scanning: ./src

Building src/area.F90
Compiling src/curves.F90 serially
Compiling src/area.F90 serially
Linking ./area
Target src/area.F90 has been successfully built
area =  0.333333333333333

FoBiS does not find quad_rules among the project's sources, so it does not try to compile it: the module comes from the include path. Simpson's rule is exact on a parabola, even with two intervals.

What you learned

mklib = static | shared, track_build, fobis install --prefix, and a project linking an installed library with include, lib_dir, ext_libs. When the library is a FoBiS project you build yourself, the next chapters show better ways: fetching it as a dependency (chapter 5).

Next: 4. Tests.