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:
[dependencies]
penf = https://github.com/szaghi/PENF :: tag=v2.0.1and names the project, which fobis tree and the ecosystem tools use:
[project]
name = quad
version = 0.1.0
authors = Ada FortranThe program now uses PENF:
!< 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 integrateFetching
$ 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.lockfobis fetch cloned PENF into .fobis_deps/ at the tag and recorded two files there:
$ 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.
$ 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.0000000645300013FoBiS 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.
$ fobis tree
quad v0.1.0
└── penf v2.0.1 (https://github.com/szaghi/PENF :: tag=v2.0.1)
Recorded on a small demo project, not quad.
The lock file
$ 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.1The 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:
$ fobis fetch --frozen
Dependency penf already fetched (use --update to refresh)
Saved deps config to .fobis_deps/.deps_config.inifobis fetch --update moves each dependency to the newest commit its specification allows and rewrites the lock.
Specifications
| Specification | Resolves to |
|---|---|
URL | the default branch |
URL :: branch=develop | the branch's head |
URL :: tag=v2.0.1 | the tag |
URL :: rev=4cb9d32 | the commit |
URL :: semver=^2.0 | the newest tag that satisfies the constraint |
user/repo | https://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.