Reproducible Builds
In this tutorial we will compile a small C program twice — each time against a pinned Debian toolchain installed into its own rootfs — and confirm the resulting binaries are byte-for-byte identical. By the end you will have performed a reproducible build: the same source, compiled against the same toolchain, produced the same bytes on disk.
Before we start
Work in a fresh directory. If you don't have flatroot yet, follow Get FlatRoot.
Build the first toolchain
Install a pinned Debian toolchain — gcc and the C runtime headers — into a fresh rootfs:
The @2024-06-15 suffix tells flatroot to use Debian's snapshot mirror for that exact date. flatroot fetches the package index as it was on that day, resolves dependencies, and extracts the resulting closure into ./build-a.
Build the second toolchain
Run the same command into a different directory:
This run is quicker — flatroot reuses the packages it already downloaded.
Write the program
A trivial C program is enough to see the effect:
Compile it in the first environment
Copy the source into the first rootfs and compile it there:
sudo chroot runs gcc with ./build-a as the root of the filesystem. The output binary lands at ./build-a/hello.
Compile it in the second environment
Do the same thing in the second rootfs:
Compare the two binaries
Compute a SHA-256 for each compiled program:
You will see two lines with identical hashes. The two hello binaries — each compiled independently, in its own rootfs, by its own instance of gcc — are byte-for-byte the same.
This is reproducibility at the level of a build, not just provisioning. Pinning the Debian source to @2024-06-15 gave us the exact same gcc, the exact same C runtime headers, and the exact same linker in both environments. Running that toolchain against the same source produced the same bytes. Anyone — you, a colleague, a build farm six months from now — running this sequence against the same pin will get the same binary.
Clean up
Remove the two rootfs, the source, and the binary:
What we did
- Built two identical toolchains by installing a pinned Debian source into two rootfs.
- Compiled the same C program against each toolchain, using
sudo chrootto rungccinside each rootfs. - Verified the two resulting binaries were byte-identical via SHA-256.
- Observed how pinning enables reproducible builds: a deterministic toolchain is the missing ingredient that makes "same source → same binary" hold across time and machines.
flatroot's role here is narrow and important — it delivers a deterministic build environment on demand, from an upstream distribution's own archives, without a running package manager. The reproducibility of hello itself is a property of the toolchain; flatroot just makes sure you get the same toolchain every time.
Related pages
- How-To Guides / Pin a build to a snapshot date — This guide shows how to pin a FlatRoot install to a specific point in time, so repeated runs produce the same rootfs regardless of when or where the command is executed....
pinning reproducibility install how-to - Appendix / Versioning / Snapshot Pinning — Snapshot pinning freezes the package index to a specific date, producing identical output regardless of when or where the command runs. Append @YYYY-MM-DD to the remote string:
pinning reproducibility appendix - Tutorials / Build your first rootfs — In this tutorial we will build a small Alpine Linux rootfs and confirm it works by entering it with chroot. By the end you will have a directory containing a miniature Linux...
tutorial install rootfs chroot