Yocto Reproducible Timestamps: Identify Inputs That Still Bypass SOURCE_DATE_EPOCH

A custom Yocto package differs between two builds even though the source revision is fixed. The difference is a generated banner containing the build date. SOURCE_DATE_EPOCH was set, but the generator called the wall clock directly and never consumed it.

An environment variable supplies an input to cooperating tools. It does not automatically rewrite arbitrary strings already embedded in generated files. Start by locating the changing timestamp and the process that created it.

Distinguish the timestamp from its container

Compare the differing artifacts at the appropriate level. Is the date inside a generated header, in a document's metadata, in an archive member header, or only in a file's modification time? These locations can require different fixes.

For an illustrative build-info.json, changing the file's mtime after generation will not alter a date string stored inside its JSON. Conversely, two files with identical contents can still produce different archives if their recorded member timestamps differ.

Avoid normalizing everything before identifying the source of the difference. That can hide a volatile metadata field while leaving the generator's wall-clock dependency intact. Trace the command or library call that produced the field and identify which timestamp it was supposed to represent.

Inspect the value in the generating task

The Yocto 5.0.12 variable reference describes SOURCE_DATE_EPOCH as seconds since the Unix epoch and explains that Yocto computes a value from each recipe's sources. It is not necessarily one global timestamp shared by every package in an image.

The examined base class writes the source-date stamp after unpacking, while the reproducibility helper derives it from available source information or a fixed fallback.

Inspect the task environment at the phase where the generator runs and trace the value into any wrapper or subprocess. A value visible in an interactive shell is not proof that the actual generator received it. Likewise, a pre-unpack observation can miss the later source-derived stamp.

If the generator does receive the expected value but output still changes, inspect whether it ignores the variable, converts it through local time, or reads another file's mtime instead.

Diagram separating embedded timestamp bytes from file or archive metadata and showing a re-executed fixed-input comparison.
Original timestamp-producer diagnostic diagram. Supplying SOURCE_DATE_EPOCH only helps tools that consume it correctly.

Repair the producer's timestamp contract

The SOURCE_DATE_EPOCH specification defines an integer environment value that is deterministic from source inputs. Cooperating build processes use it in place of the current time for embedded build timestamps and preserve it for child processes. For build-specific timestamps that require an upper bound, the specification describes clamping.

For a custom generator, first ask whether the field is needed. A source revision may communicate software identity more accurately than a build date. If the timestamp remains necessary, parse the supplied value explicitly and format it with a stable timezone and representation. In a reproducibility-required workflow, silently falling back to the wall clock on malformed input defeats the purpose.

Use an existing tool interface when available. CMake 3.28's string TIMESTAMP documentation states that the environment value replaces the current time; its UTC option avoids local-time formatting. That behavior does not automatically extend to a separate Python generator launched by the project.

Rebuild the producer, then compare the relevant bytes

Test with fixed source inputs and the same epoch while varying build time and timezone. Ensure the affected generation step actually executes again; comparing an output with a cached copy of itself cannot reveal a wall-clock read.

The Yocto reproducibility guide describes a two-build selftest and optional detailed difference reports. Use a focused target selection when investigating one custom recipe, and inspect the saved differences rather than treating tool completion alone as proof.

Finally, keep runtime timestamps outside this build-time policy. Device event logs and acquisition times should describe real events under the product's clock model. The correction belongs in the build artifact's timestamp producer, not in a blanket replacement of every use of time.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *