Build System
FOL uses a Zig-style build model. The build specification is a normal FOL
program called build.fol. It goes through the full compiler pipeline and
is executed against a build graph IR instead of emitting backend code.
The build system lives in lang/execution/fol-build. It handles:
- graph IR construction for artifacts, steps, options, modules, and generated files
- full control flow in build programs (when, loop, helper routines)
-DCLI option passing into the build program- named step selection at the command line
Entry Point
Every buildable package must have a build.fol at its root with exactly one
canonical entry:
pro[] build(): non = {
var build = .build();
build.meta({ name = "app", version = "0.1.0" });
var graph = build.graph();
...
}
The active build context is accessed explicitly through the build-only ambient accessor:
.build()
There is no injected graph parameter anymore. .build() returns an opaque
build-only handle. Users do not name its type explicitly. Package metadata and
direct dependencies are configured through that handle, and graph work is
reached through build.graph().
Minimal Example
pro[] build(): non = {
var build = .build();
build.meta({ name = "app", version = "0.1.0" });
var graph = build.graph();
var app = graph.add_exe({ name = "app", root = "src/main.fol" });
graph.install(app);
graph.add_run(app);
}
This registers package metadata, adds an executable, marks it for installation, and binds a default run step.
What fol-build Owns
graph.rs— build graph IR (steps, artifacts, modules, options, generated files)api.rs— Rust-level graph mutation interfacesemantic.rs— method signatures and type info for the resolver and typecheckerstdlib.rs—BuildStdlibScope: the ambient scope injected intobuild.folexecutor.rs— executes the lowered FOL IR against the build grapheval.rs— evaluate abuild.folfrom source; entry point forfol-packageoption.rs— build option kinds, target triples, optimize modesruntime.rs— runtime representation of artifacts, generated files, step bindingsstep.rs— step planning, ordering, cache keys, execution reportscodegen.rs— system tool and codegen request typesartifact.rs— artifact pipeline definitions and output typesdependency.rs— inter-package dependency surfaces
Use this section for:
- understanding the shape of
build.fol - the full graph API reference
- control flow available inside
build.fol - build options and
-Dflags - artifact types, modules, and generated files
- dependency handles and unified output handles
Near-Term Architecture
The next build round is about extending the existing explicit surface, not replacing it.
The intended layering is:
build.add_dep({...})declares a direct dependency and returns a dependency handlebuild.export_*({...})declares the build-facing surface a package chooses to exposegraph.file_from_root(...)andgraph.dir_from_root(...)remain the typed source-path producers- broader path-oriented exports and dependency path queries sit on top of those producers instead of collapsing back into raw string paths
- dependency modes, install reporting, and system integration should become more
concrete without changing the top-level
.build()structure
This means the near-term additions should look like richer values and richer
queries on top of the current build graph, not a new manifest format and not a
public Graph or Build type.
Standalone Examples
These checked-in example packages exercise the current public build surface:
examples/build_dep_exportsexamples/build_source_pathsexamples/build_dep_modesexamples/build_described_stepsexamples/build_generated_dirsexamples/build_dep_handlesexamples/build_output_handlesexamples/build_install_prefixexamples/build_system_libexamples/build_system_tool
Runtime-model reminder:
- examples that rely on hosted behavior such as
.echo(...)or routed execution should spellfol_model = "memo" coreandmemoexamples in the build book should stay free of hosted assumptions
Bundled std reminder:
stdships with FOL underlang/library/std- hosted packages add bundled std explicitly through:
.build().add_dep({ alias = "std", source = "internal", target = "standard" }) - normal hosted packages should rely on the bundled shipped
std, not an external replacement package