fobos — the FoBiS makefile
A fobos file is FoBiS.py's project configuration file. It replaces makefiles entirely, using a simple INI-like syntax.
Overview
When FoBiS.py runs, it automatically looks for a file named fobos in the current working directory. Options in the fobos file override the CLI defaults, and for cflags, lflags, and preproc they are combined with any additional values passed on the command line.
Design principle
Brevity is a design parameter. The fobos file uses the same option names as the CLI switches — there is nothing new to learn.
Basic structure
A minimal single-mode fobos file:
[default]
compiler = gnu
cflags = -c -O2
src = ./src/
build_dir = ./build/
obj_dir = ./obj/
mod_dir = ./mod/
target = src/main.f90
output = myappA multi-mode fobos file:
[modes]
modes = debug release
[debug]
compiler = gnu
cflags = -c -O0 -g -Wall
build_dir = ./build/debug/
[release]
compiler = gnu
cflags = -c -O3
build_dir = ./build/release/Loading a fobos file
| Scenario | Command |
|---|---|
| Default name and location | Loaded automatically |
| Custom name or path | fobis build -f /path/to/my_fobos |
| Select a specific mode | fobis build -mode release |
| List available modes | fobis build -lmodes |
Case sensitivity
By default fobos option names are case-sensitive. To make them case-insensitive:
fobis build -fciOr in the fobos file itself, this is implicit for the option names (values remain as written).
Available options
All CLI options accepted by build and clean are available in a fobos mode section with identical names (using the long form without the leading --). A representative set:
| Option | Description |
|---|---|
compiler | Compiler identifier (gnu, intel, …) |
fc | Compiler executable (for custom compiler) |
cflags | Compilation flags |
lflags | Linking flags |
preproc | Preprocessor macro flags |
src | Root source directory (space-separated list) |
build_dir | Build output directory |
obj_dir | Compiled objects directory |
mod_dir | Module interface files directory |
lib_dir | External library search directories |
include | Include files search directories |
target | Build target file |
output | Output executable name |
exclude | Files to exclude from the build |
libs | External libraries (full paths) |
vlibs | Volatile external libraries (full paths) |
ext_libs | External libraries (by name, in linker path) |
ext_vlibs | Volatile external libraries (by name) |
dependon | Interdependent external fobos files |
mklib | Build a library: static or shared |
ar | Archiver executable for static libraries (default: ar) |
arflags | Archiver flags (default: -rcs) |
ranlib | Ranlib executable; set to empty string to skip (default: ranlib) |
mpi | Enable MPI compiler variant |
openmp | Enable OpenMP |
coarray | Enable coarrays |
coverage | Enable coverage instrumentation |
jobs | Number of parallel compile jobs |
colors | Coloured terminal output |
quiet | Suppress verbose output |
log | Write build log file |
cflags_heritage | Track flag changes and force rebuild on change |
build_profile | Named compiler flag preset: debug, release, asan, coverage |
cache_dir | Build cache directory (default: .fobis_cache) |
no_cache | Disable build cache (true/false) |
no_auto_discover | Disable convention-based source discovery (true/false) |
pre_build | Shell command to run before the build |
post_build | Shell command to run after a successful build |
features | Space-separated feature names to activate for this mode (see Feature Flags) |
varset | Space-separated varset names to apply for this mode (see Varsets) |
intrinsic_modules | Space-separated module names to treat as intrinsic — silently skipped from the dependency graph (see below) |
Special sections
Beyond the mode sections, a fobos file can contain several top-level sections with fixed names:
| Section | Purpose | Documentation |
|---|---|---|
[modes] | Lists the available named mode sections | Many-mode fobos |
[project] | Project metadata: name, version, authors, … | Project metadata |
[features] | Named compile-time option sets, activated with --features | Feature Flags |
[feature:NAME] | Per-feature metadata: flags, requires, conflicts | Feature Flags |
[feature-group:NAME] | Mutually-exclusive feature group with optional default | Feature Flags |
[varsets] | Varset metadata: default = NAMES (fobos-declared fallback) | Varsets |
[varset:NAME] | Named bundle of $variable bindings, applied via --varset | Varsets |
[include] | Pull in sibling fobos files; ? prefix for optional | Includes |
[dependencies] | GitHub-hosted build dependencies | Fetch Dependencies |
[test] | Test runner defaults: suite, timeout, jobs | Test Runner |
[coverage] | Coverage report settings: output dir, fail threshold, excludes | Coverage |
[externals] | External library flags via pkg-config and MPI auto-detection | External Libraries |
[pkgconfig] | Generate a .pc file for your own project | External Libraries |
[target.NAME] | Named build target with per-target flag overrides | build reference |
[example.NAME] | Named example target (same syntax as target.NAME) | build reference |
[rule-NAME] | Custom shell-command rules | Rules |
[features] section
Defines named compile-time option sets that map to flags:
[features]
default = release mpi ; active when none are explicitly requested
release = -O3 -DNDEBUG
debug = -g -O0 -fcheck=all
mpi = -DUSE_MPI
hdf5 = -DUSE_HDF5 -I/opt/hdf5/include
omp_defs = -DUSE_OMP ; define only — pair with --features openmp
# Composite features: prefix a name with @ to reference another feature.
# Activating `prod` pulls in `release`, `mpi`, and `hdf5`.
prod = @release @mpi @hdf5
dev = @debug @mpiFlags are routed to cflags or lflags automatically by pattern. Composite expansion is recursive and cycle-safe.
Activation sources (merged in order, last wins on negation):
[features] default = ...— project-wide baseline[mode-X] features = a b c— per-mode preset--features a,bon the CLI — user override;-namedeactivates
fobis build # default features only
fobis build --features prod # composite expansion
fobis build --features prod,-coverage # drop coverage from the active set
fobis build --no-default-features # ignore [features] default =Well-known compiler capabilities (openmp/omp, mpi, coarray, coverage, profile) are implicit features — they work without a [features] section and resolve to the correct compiler-specific flag automatically.
[feature:NAME] and [feature-group:NAME] sections
For features that need constraints or grouping, declare them in dedicated sibling sections:
[feature:hdf5]
requires = mpi ; auto-pulls mpi when hdf5 is active
[feature:static]
conflicts = shared ; hard error if both active
[feature-group:precision]
members = single double quad ; at most one active at a time
default = double ; auto-activated when group is emptyrequires cascades transitively (cycle-safe). conflicts and group violations abort the build with a verbose error tracing each side back to its originator. See Feature Flags for the full reference.
[varsets] and [varset:NAME] sections
Varsets are named bundles of $variable bindings selected at invocation time. They eliminate per-cluster / per-target mode duplication when the only difference between modes is a handful of paths or numeric parameters:
[varsets]
default = local ; applied when --varset is omitted
[varset:local]
$HDF5_PREFIX = lib/hdf5/develop/nvf/26.1
[varset:leonardo]
$HDF5_PREFIX = /leonardo/prod/spack/.../hdf5-1.14.3
$ARCH = cc80
[mode-prism]
template = template-nvf-oac
target = adam_prism_fnl.F90
libs = $HDF5_PREFIX/lib/libhdf5_fortran.a $HDF5_PREFIX/lib/libhdf5.a
lib_dir = $HDF5_PREFIX/lib
include = $HDF5_PREFIX/include
cflags = -c -gpu=$ARCHfobis build --mode mode-prism # uses [varsets] default = local
fobis build --mode mode-prism --varset leonardo # leonardo paths + cc80
fobis build --mode mode-prism --varset leonardo,cc89 # combined; last write winsVariables defined inside [varset:NAME] sections do not leak into the implicit global pool — they apply only when the varset is selected. See Varsets for the full reference.
[include] section
Pulls in the contents of one or more sibling fobos files before any other processing. Useful for splitting a large fobos by concern, sharing configuration across sibling repos, or layering machine-local overrides on top of committed defaults:
[include]
paths = templates.fobos
rules.fobos
?fobos.local ; '?' prefix → optional, silent if missingPaths resolve relative to the including file's directory (after ${ENV} and ~ expansion). On conflict, the parent file wins; among siblings, later includes override earlier ones. Cycles abort with exit 1. By convention, included fragments use the .fobos extension (the resolver itself accepts any path). See Includes for the full reference.
[dependencies] section
Declares GitHub-hosted dependencies. Each entry maps a short name to a repository spec:
[dependencies]
deps_dir = .fobis_deps # optional: where to clone deps (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=gnuThe use= field selects the integration mode:
sources(default) — dependency sources are compiled inline with your projectfobos— dependency is built as a separate library and linked
See Fetch Dependencies and Lock File & Semver for the full syntax and workflow.
[test] section
Sets defaults for fobis test:
[test]
suite = unit ; only run tests tagged with this suite
timeout = 120 ; seconds per test
jobs = 4 ; parallel compile jobs[coverage] section
Sets defaults for fobis coverage:
[coverage]
output_dir = coverage/
source_dir = src/
fail_under = 75
exclude = test/*
examples/*[target.NAME] and [example.NAME] sections
Named targets allow per-target flag overrides without separate fobos modes:
[target.solver]
target = src/solver.F90
output = solver
cflags = -c -O3 -DSOLVER
[example.demo]
target = examples/demo.F90
output = demofobis build --target-filter solver
fobis build --examplesintrinsic_modules mode key
When the dependency scanner sees a use NAME line that doesn't resolve to any source file or compiled .mod, it warns "the file 'X' depends on 'NAME' that is unreachable". FoBiS already filters out the standard Fortran intrinsics (iso_fortran_env, iso_c_binding, ieee_*, openacc, omp_lib, mpi) and the modules supplied by the active compiler (cudafor etc. under nvfortran; ifport etc. under intel).
For modules that come from external libraries — hdf5, mpi_f08, vendor HPC libraries, or any project-specific helper that lives outside the source tree — declare them per-mode so the warning goes away:
[release]
compiler = nvfortran
cflags = -cpp -c -O3
target = src/main.F90
intrinsic_modules = hdf5 hdf5_hl mpi_f08The names are case-insensitive (Fortran rules) and apply only to the mode they are declared in. They compose with the universal and compiler-specific sets — together they form the union the dependency scanner skips. See Compilers for the list of compiler-supplied modules and Architecture for the three-tier filter.
Comments
Lines beginning with # are ignored:
[default]
# This is a comment
compiler = gnu # inline comments are also supported
cflags = -c -O2Further reading
- Complete example — annotated fobos with every section and option
- Single-mode fobos — the simplest configuration
- Many-mode fobos — multiple build configurations in one file
- Templates — share common settings across modes
- Variables — define reusable
$variablevalues - Rules — custom task automation (documentation, archives, …)
- Intrinsic rules — built-in automation rules
- Project metadata —
[project]section: name, version, authors, and more - Feature Flags —
[features]section: named compile-time option sets - Varsets —
[varset:NAME]sections: bundle$variablebindings, swap at invocation time - Includes —
[include]section: pull in sibling fobos files (split, share, override) - Build Profiles —
build_profilekey: named compiler flag presets - Fetch Dependencies —
[dependencies]section: GitHub-hosted build dependencies - Lock File & Semver — reproducible builds and version constraints
- Test Runner —
[test]section: test discovery and execution - Coverage —
[coverage]section: HTML/XML coverage reports - External Libraries —
[externals]and[pkgconfig]sections