Complete fobos example
A single annotated file showing every recognised section and option. Copy it as a starting point and delete what you do not need.
ini
# ─────────────────────────────────────────────────────────────────────────────
# [modes] — list every named mode section defined below.
# Run: fobis build --mode <name>
# List: fobis build --lmodes
# ─────────────────────────────────────────────────────────────────────────────
[modes]
modes = debug release
# ─────────────────────────────────────────────────────────────────────────────
# [project] — optional metadata; consumed by `fobis introspect --projectinfo`
# and used to generate pkg-config files.
# `version` may be a literal string or a path to a file that
# contains the version string (relative to the git repo root).
# ─────────────────────────────────────────────────────────────────────────────
[project]
name = myproject ; short machine-readable name
version = 1.2.0 ; or: src/version.inc
summary = A modern Fortran solver library ; one-line description
authors = Alice Smith
Bob Jones ; one author per line
repository = https://github.com/example/myproject
website = https://example.github.io/myproject
email = alice@example.com
year = 2026
# ─────────────────────────────────────────────────────────────────────────────
# [features] — named compile-time option sets.
# default = features active when none are explicitly requested
# All other keys: name = flags (routed to cflags/lflags automatically)
# Well-known implicit names (openmp/omp, mpi, coarray, coverage, profile,
# openmp_offload/omp_offload) do NOT need an entry here — they resolve
# through the compiler table automatically.
# ─────────────────────────────────────────────────────────────────────────────
[features]
default = mpi ; active by default
mpi = -DUSE_MPI ; -D → cflags
hdf5 = -DUSE_HDF5 -I/opt/hdf5/include ; -I → cflags
netcdf = -DUSE_NETCDF -I/opt/netcdf/include
omp_defs = -DUSE_OMP ; define only; use --features openmp for the compiler flag
# ─────────────────────────────────────────────────────────────────────────────
# [dependencies] — GitHub-hosted build dependencies fetched by `fobis fetch`.
# deps_dir = local directory for cloned repositories (default: .fobis_deps)
# Each entry: name = URL [:: branch=X | tag=X | rev=X | semver=X]
# [:: mode=X] [:: use=sources|fobos]
# ─────────────────────────────────────────────────────────────────────────────
[dependencies]
deps_dir = .fobis_deps ; where to clone (same as --deps-dir)
penf = https://github.com/szaghi/PENF :: tag=v1.5.0
stdlib = https://github.com/fortran-lang/stdlib :: semver=>=0.5,<1.0 :: use=fobos :: mode=gnu
jsonfort = https://github.com/jacobwilliams/json-fortran :: branch=main :: use=fobos
utils = szaghi/fortran-utils :: rev=a1b2c3d ; user/repo shorthand resolves to GitHub
# ─────────────────────────────────────────────────────────────────────────────
# [externals] — system library resolution via pkg-config or MPI auto-detect.
# pkg-config = space-separated list of pkg-config package names
# mpi-auto = true → probe mpifort/mpif90 wrappers for compile+link flags
# ─────────────────────────────────────────────────────────────────────────────
[externals]
pkg-config = hdf5 netcdf ; runs `pkg-config --cflags --libs`
mpi-auto = false ; set true to probe MPI wrappers
# ─────────────────────────────────────────────────────────────────────────────
# [test] — defaults for `fobis test`.
# ─────────────────────────────────────────────────────────────────────────────
[test]
test_dir = tests ; directory scanned for test programs
suite = unit ; only run tests tagged ! fobis: suite=unit
timeout = 120 ; seconds before a test is killed
compiler = gnu ; override compiler for test builds
cflags = -c -O0 -g ; extra cflags for test compilation
# ─────────────────────────────────────────────────────────────────────────────
# [coverage] — defaults for `fobis coverage`.
# ─────────────────────────────────────────────────────────────────────────────
[coverage]
output_dir = coverage/ ; where HTML/XML report is written
source_dir = src/ ; filter coverage to this directory
fail_under = 75 ; exit 1 if line coverage < N %
exclude = tests/* ; glob patterns to exclude (one per line)
examples/*
# ─────────────────────────────────────────────────────────────────────────────
# Build mode sections — one section per named mode.
# All option names mirror the CLI long flags (without --).
# ─────────────────────────────────────────────────────────────────────────────
# ── shared template (inherited by debug and release via template = base) ──────
[base]
compiler = gnu ; gnu intel intel_nextgen nvfortran nag ibm amd pgi g95 custom
fc = gfortran ; compiler executable (required for custom)
modsw = -J ; module directory switch (required for custom)
src = ./src/ ; source root (space-separated list)
build_dir = ./build/ ; where executables are placed
obj_dir = ./obj/ ; compiled object files
mod_dir = ./mod/ ; Fortran .mod interface files
lib_dir = /usr/local/lib ; external library search paths (space-sep)
include = /usr/local/include ; include file search paths (space-sep)
exclude_dirs = ./vendor/ ; directories excluded from source scan
disable_recursive_search = false ; do not recurse into subdirectories
target = src/main.F90 ; specific source file to build
output = myapp ; output executable name
exclude = src/scratch.F90 ; source files to skip (space-separated)
libs = /opt/mylib/libfoo.a ; external libraries (full paths)
vlibs = /opt/mylib/libvolatile.a ; volatile libs — rebuild when changed
ext_libs = lapack blas ; library names (passed as -l to linker)
ext_vlibs = myvolatile ; volatile library names
dependon = ../otherlib/fobos:release ; interdependent fobos files (path:mode)
inc = .inc .INC .h .H ; include file extensions (space-sep)
extensions = .F90 .f90 .F .f ; Fortran source extensions to scan
build_all = false ; compile all parsed sources, not just programs
mklib = static ; build a library: static or shared
ar = ar ; archiver executable
arflags = -rcs ; archiver flags
ranlib = ranlib ; ranlib executable; set to empty to skip
mpi = false ; use MPI compiler wrapper
openmp = false ; enable OpenMP
openmp_offload = false ; enable OpenMP offload
coarray = false ; enable coarrays
coverage = false ; coverage instrumentation (--coverage)
profile = false ; profiling instrumentation (-pg)
cflags_heritage = false ; force full rebuild when cflags change
track_build = false ; save build info for `fobis install`
preprocessor = PreForM.py ; source preprocessor executable
preproc = -DSOME_MACRO ; preprocessor macro flags
preprocessor_args = --output-dir .preproc ; extra flags passed to the preprocessor
preprocessor_no_o = false ; omit -o from the preprocessor command
preprocessor_dir = .preproc ; keep preprocessed sources in this dir
preprocessor_ext = .pf .PF ; file extensions to preprocess
build_profile = debug ; named flag preset: debug release asan coverage
features = ; comma-separated features to activate
no_auto_discover = false ; disable src/source/app/ auto-detection
no_cache = false ; disable the build artifact cache
cache_dir = .fobis_cache ; override default cache directory
pre_build = gen_version ; rule(s) to run before compilation
post_build = run_tests ; rule(s) to run after successful link
externals = hdf5 netcdf ; entries from [externals] to apply
pkgconfig = false ; generate a .pc file on build
pkgconfig_name = myproject ; package name in the .pc file
pkgconfig_desc = My Fortran library ; description in the .pc file
pkgconfig_url = https://github.com/example/myproject
pkgconfig_req = hdf5 ; Requires: line in the .pc file
pkgconfig_req_priv = zlib ; Requires.private: line in the .pc file
colors = false ; coloured terminal output
log = false ; write a build log file
graph = false ; write a graphviz dependency graph
quiet = false ; suppress informational output
verbose = false ; maximum diagnostic verbosity
jobs = 4 ; parallel compile jobs
# ── local variables — reused via $name substitution ──────────────────────────
$opt_flags = -O2 -march=native ; define once, reference as $opt_flags
# ── debug mode ───────────────────────────────────────────────────────────────
[debug]
template = base ; inherit all options from [base]
cflags = -c -O0 -g -Wall -Wextra
lflags = ; no extra link flags
build_profile = debug ; prepends: -fcheck=all -fbacktrace -ffpe-trap=...
build_dir = ./build/debug/
# ── release mode ─────────────────────────────────────────────────────────────
[release]
template = base
cflags = -c $opt_flags ; $opt_flags substituted from variable above
lflags =
build_profile = release ; prepends: -O3 -funroll-loops
build_dir = ./build/release/
# ─────────────────────────────────────────────────────────────────────────────
# [target.NAME] — per-target overrides; built with --target-filter NAME.
# source = source file for this target (required)
# output = output binary name (required)
# Any build option can be added to override the base mode.
# ─────────────────────────────────────────────────────────────────────────────
[target.solver]
source = src/solver.F90
output = solver
cflags = -c -O3 -DSOLVER_STANDALONE
# ─────────────────────────────────────────────────────────────────────────────
# [example.NAME] — same syntax as target.*; built with --examples.
# ─────────────────────────────────────────────────────────────────────────────
[example.demo]
source = examples/demo.F90
output = demo
build_dir = ./build/examples/
# ─────────────────────────────────────────────────────────────────────────────
# [rule-NAME] — custom shell commands; run with `fobis rule --execute NAME`
# or referenced by pre_build / post_build.
# help = one-line description shown by `fobis rule --list`
# quiet = suppress command echo
# log = write errors to rules_errors.log
# rule1 … ruleN = shell commands (executed in alphabetical key order)
# ─────────────────────────────────────────────────────────────────────────────
[rule-gen_version]
help = Generate src/version.inc from git tag
rule1 = git describe --tags --abbrev=0 > src/version.inc
[rule-run_tests]
help = Run the test suite after a successful build
rule1 = ./build/release/test_suite --verbose
quiet = false
log = true
[rule-docs]
help = Build the VitePress documentation site
rule1 = npm run docs:build