A software build is reproducible if using the same source code and by following the same build instructions in a specific build environment, bit-by-bit identical copies of expected output can be obtained by anyone.
Although reproducible builds are desirable for a number of reasons, the ability to verify that the build output corresponds exactly to the source code is a major benefit.
jp2a is a JPEG to ASCII conversion library written in C. I’ve used it in an Image Processing project, and for some other fun stuff. Its source code can be found here. It is listed as a reproducible package by Reproducible Builds here.
But how do we determine that ourselves? The solution is to build the software in a deterministic build environment, and verify that the binary it produces has the same cryptographic checksum when built at different times, on different machines by different people.
It is important to create a build environment for the process, that can be set-up again with ease, and does not introduce any sources of indeterminism. Containers are an excellent choice for this purpose. Here, I set up a Docker container to build jp2a from source. The
Dockerfile to create the image is
It starts from a base image (Debian Stretch), installs required dependencies, specifies a fixed build path, gets the source code via
git clone, and then follows the instructions required to compile from source. The image created by this
Dockerfile contains the binary (named jp2a) inside
We wish to verify the integrity of this binary primarily, because the
.deb archive of the library is just this binary packaged in a format specified by Debian.
Make sure Docker is installed.
Dockerfile, preferably in a new directory, using the contents mentioned in the previous section.
docker build -t jp2a-test .
After the image is built, create an instance of this image (a container) by running
docker run --name jp2a -t jp2a-test
docker cpto extract the binary and save it as
docker cp jp2a:/build/jp2a/src/jp2a jp2a
Check the SHA-256 hash with
Make sure to stop the container with
docker stop jp2a.
The SHA-256 hash, obtained after each of the several different test runs is -
This process can be followed on your own machine, and the obtained hash should match this value. It will further confirm that this binary is indeed reproducible.
If the build path is changed, the two separate binaries will not give identical hash values, and thus output will not remain reproducible. Setting different flags during compilation can also lead to the same situation. Such differences can be identified with the tool
diffoscope, and wherever possible, be worked upon.
As of now, jp2a can be built reproducibly in a deterministic build environment.