Skip to content

5. Dependencies ​

quad's program wants to print its best estimate with all the digits that matter, no more: PENF's str does that. PENF is a FoBiS project on GitHub; the fobos declares it:

ini
[dependencies]
penf = https://github.com/szaghi/PENF :: tag=v2.0.1

and names the project, which fobis tree and the ecosystem tools use:

ini
[project]
name    = quad
version = 0.1.0
authors = Ada Fortran

The program now uses PENF:

fortran
!< Integrate sin(x) over [0, pi], whose exact value is 2, with more and more intervals.
program integrate
!< Integrate sin(x) over [0, pi], whose exact value is 2, with more and more intervals.
use quad_rules, only : R8P, trapezoid, simpson
use integrands, only : sine
use penf,       only : str
implicit none
real(R8P), parameter :: pi = acos(-1._R8P) !< Pi.
integer              :: n                  !< Number of intervals.

print '(A6, 2A18)', 'n', 'trapezoid error', 'simpson error'
n = 4
do while (n <= 64)
   print '(I6, 2ES18.4)', n, abs(trapezoid(sine, 0._R8P, pi, n) - 2._R8P), abs(simpson(sine, 0._R8P, pi, n) - 2._R8P)
   n = 2 * n
enddo
print '(A)', 'Simpson, 64 intervals: '//trim(str(simpson(sine, 0._R8P, pi, 64), no_sign=.true., compact=.true.))
endprogram integrate

Fetching ​

console
$ fobis fetch
Cloning penf from https://github.com/szaghi/PENF
Checking out v2.0.1 for penf
Saved deps config to .fobis_deps/.deps_config.ini
Saved lock file to .fobis_deps/fobos.lock

fobis fetch cloned PENF into .fobis_deps/ at the tag and recorded two files there:

console
$ ls .fobis_deps && cat .fobis_deps/.deps_config.ini
fobos.lock
penf
[deps]
src = .fobis_deps/penf

.deps_config.ini tells fobis build where the fetched sources are: they are compiled with the project's, with the project's flags (use=sources, the default). A dependency declared with use=fobos is instead built as a library by its own fobos, and linked.

console
$ fobis build --mode release --quiet && ./build/release/integrate

Building src/integrate.F90
Compiling .fobis_deps/penf/src/lib/penf_global_parameters_variables.F90 serially
Compiling .fobis_deps/penf/src/lib/penf_b_size.F90 serially
Compiling .fobis_deps/penf/src/lib/penf_stringify.F90 serially
Compiling src/quad_rules.F90 .fobis_deps/penf/src/lib/penf_allocatable_memory.F90 serially
Compiling src/integrands.F90 .fobis_deps/penf/src/lib/penf.F90 serially
Compiling src/integrate.F90 serially
Linking build/release/integrate
Target src/integrate.F90 has been successfully built
     n   trapezoid error     simpson error
     4        1.0388E-01        4.5598E-03
     8        2.5768E-02        2.6917E-04
    16        6.4297E-03        1.6591E-05
    32        1.6066E-03        1.0334E-06
    64        4.0161E-04        6.4530E-08
Simpson, 64 intervals: 2.0000000645300013

FoBiS compiled the five PENF modules the program needs before the program, and quad_rules, changed by the doctests of chapter 4, with integrands, which uses it. Files on the same line belong to the same level of the dependency tree.

console
$ fobis tree
quad v0.1.0
└── penf v2.0.1 (https://github.com/szaghi/PENF :: tag=v2.0.1)

fobis fetch clones the dependencies, fobis build compiles them

Recorded on a small demo project, not quad.

The lock file ​

console
$ cat .fobis_deps/fobos.lock
# fobos.lock — auto-generated by FoBiS.py fetch — do not edit by hand

[penf]
url = https://github.com/szaghi/PENF
commit = 4cb9d326c08f109ed5126d83c27e8e70c98b7eaa
sha256 = 2a46c1a89c4e1e9de7a410cdf0efe4ec1cbef53526998b8552ad98c97260bd66
tag = v2.0.1

The lock lives with the dependencies, in .fobis_deps/, and like them it is not committed: it is this machine's record of the commit each dependency resolved to, and a checksum of its files. What makes another checkout fetch the same code is the specification in the fobos (tag=, rev=). fobis fetch --frozen refuses to run without the lock and checks every dependency against it:

console
$ fobis fetch --frozen
Dependency penf already fetched (use --update to refresh)
Saved deps config to .fobis_deps/.deps_config.ini

fobis fetch --update moves each dependency to the newest commit its specification allows and rewrites the lock.

Specifications ​

SpecificationResolves to
URLthe default branch
URL :: branch=developthe branch's head
URL :: tag=v2.0.1the tag
URL :: rev=4cb9d32the commit
URL :: semver=^2.0the newest tag that satisfies the constraint
user/repohttps://github.com/user/repo

:: mode=NAME picks the dependency's fobos mode, :: use=fobos builds it as a library, and :: dev makes it test-only: fobis test uses it, the builds of the program and of the library do not (test-only dependencies).

What you learned

[dependencies], fobis fetch, .fobis_deps/, the lock and --frozen, fobis tree. Reference: fetch, tree.

This is the end of the first track: quad builds in two modes, as a library, with tests, doctests, coverage and a dependency. Growing a project takes it further.