Bagel is a lightweight, parallelizable build system written in Rust and C++ that:
- Builds a dependency DAG and schedules commands to run in topological order
- Allows incremental builds by skipping up-to-date targets with hashing
- Supports parallel execution of independent build steps
- Is inspired by Bazel (Google's build system). This is a fun project, and by no means a production-ready system :)
With respect to the design of build systems, Bagel narrows down 3 dimensions of optimization:
-
Minimality - processing each target only once
-
Parallelism - executing independent build steps in parallel to reduce overall build times
-
Incrementality - tracking file changes and dependecy relationships to avoid unnecessary rebuilds on unchanged components
Hermeticity is also an important dimension, but we backlog this in favor for key functionality concerning the other three dimensions. Ideally, we would like to have a container image per language toolchain.
A more detailed discussion can be found in docs/design.md.
The project is a single Rust package (bagel) organized into modules:
core- build spec parsing, dependency graph management, and topological sortexec- serial and parallel (rayon-backed) executors that actually run commandsutils- hashing/caching for incremental builds, and shared helpers
# Build the project
cargo build
# Run the CLI without installing anything
cargo run -- build
# Run tests
cargo testIf you're going to run bagel more than once or twice, you may want to install it onto your PATH:
cargo install --path .
bagel buildNote: The instructions in this README assumes bagel is installed. If you'd rather not install it, swap bagel for cargo run --release -- in any command below.
Builds your project off Bagel.toml.
-f,--force— force rebuild of all targets (no-cache).-j,--parallel— run independent targets concurrently. Bagel defaults to sequential execution.-v,--verbose— prints metadata (incl. shell command) for each target ran.--json <path>— alongside the normal terminal output, write a full build report to<path>as JSON. Provides the build progress, start time relative to the build, duration, and declared dependencies of each target.
Parses and prints the contents of a Bagel.toml.
Prints the dependency graph as Graphviz DOT to stdout, pass --out <path> to write to a file.
bagel graph --out graph.dot
dot -Tpng graph.dot -o graph.pngThe examples directory contains several demo projects that can be built with Bagel. Here is an example workflow to compare the serial and parallel execution of examples/demo:
cd examples/demo
bagel build --json serial.json
bagel build -j --json parallel.json
cat parallel.jsonA lot of the design decisions made in this project are based on the following work: