Skip to content

Commit

Permalink
Support clamping the file mtime to the build time
Browse files Browse the repository at this point in the history
This makes the file mtime more reproducible and consistent. The
package build time is set before the build is started, so every
new file will get the same time.
  • Loading branch information
mlschroe committed Mar 27, 2024
1 parent 2880adc commit c9579db
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 21 deletions.
52 changes: 35 additions & 17 deletions build/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ static int seenHardLink(FileRecords files, FileListRec flp, rpm_ino_t *fileid)
* @param pkg (sub) package
* @param isSrc pass 1 for source packages 0 otherwise
*/
static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
static void genCpioListAndHeader(FileList fl, rpmSpec spec, Package pkg, int isSrc)
{
FileListRec flp;
char buf[BUFSIZ];
Expand All @@ -1033,23 +1033,41 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
rpm_loff_t totalFileSize = 0;
Header h = pkg->header; /* just a shortcut */
int override_date = 0;
time_t source_date_epoch = 0;
time_t mtime_clamp = 0;
char *srcdate = getenv("SOURCE_DATE_EPOCH");
char *mtime_policy_str = rpmExpand("%{?build_mtime_policy}", NULL);

/* Limit the maximum date to SOURCE_DATE_EPOCH if defined
* similar to the tar --clamp-mtime option
* https://reproducible-builds.org/specs/source-date-epoch/
*/
if (srcdate && rpmExpandNumeric("%{?clamp_mtime_to_source_date_epoch}")) {
char *endptr;
errno = 0;
source_date_epoch = strtol(srcdate, &endptr, 10);
if (srcdate == endptr || *endptr || errno != 0) {
rpmlog(RPMLOG_ERR, _("unable to parse %s=%s\n"), "SOURCE_DATE_EPOCH", srcdate);
fl->processingFailed = 1;
/* backward compatibility */
if (!*mtime_policy_str) {
if (srcdate && rpmExpandNumeric("%{?clamp_mtime_to_source_date_epoch}")) {
free(mtime_policy_str);
mtime_policy_str = xstrdup("clamp_to_source_date_epoch");
}
}

if (!strcmp(mtime_policy_str, "clamp_to_buildtime")) {
mtime_clamp = spec->buildTime;
override_date = 1;
} else if (!strcmp(mtime_policy_str, "clamp_to_source_date_epoch")) {
/* Limit the maximum date to SOURCE_DATE_EPOCH if defined
* similar to the tar --clamp-mtime option
* https://reproducible-builds.org/specs/source-date-epoch/
*/
if (srcdate) {
char *endptr;
errno = 0;
mtime_clamp = strtol(srcdate, &endptr, 10);
if (srcdate == endptr || *endptr || errno != 0) {
rpmlog(RPMLOG_ERR, _("unable to parse %s=%s\n"), "SOURCE_DATE_EPOCH", srcdate);
fl->processingFailed = 1;
}
override_date = 1;
}
} else if (*mtime_policy_str) {
rpmlog(RPMLOG_WARNING,
_("Unknown mtime policy '%s'\n"), mtime_policy_str);
}
free(mtime_policy_str);

/*
* See if non-md5 file digest algorithm is requested. If not
Expand Down Expand Up @@ -1192,8 +1210,8 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
}
}

if (override_date && flp->fl_mtime > source_date_epoch) {
flp->fl_mtime = source_date_epoch;
if (override_date && flp->fl_mtime > mtime_clamp) {
flp->fl_mtime = mtime_clamp;
}
/*
* For items whose size varies between systems, always explicitly
Expand Down Expand Up @@ -2652,7 +2670,7 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
if (checkHardLinks(&fl.files))
(void) rpmlibNeedsFeature(pkg, "PartialHardlinkSets", "4.0.4-1");

genCpioListAndHeader(&fl, pkg, 0);
genCpioListAndHeader(&fl, spec, pkg, 0);

exit:
FileListFree(&fl);
Expand Down Expand Up @@ -2782,7 +2800,7 @@ rpmRC processSourceFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags)

if (! fl.processingFailed) {
if (sourcePkg->header != NULL) {
genCpioListAndHeader(&fl, sourcePkg, 1);
genCpioListAndHeader(&fl, spec, sourcePkg, 1);
}
}

Expand Down
10 changes: 6 additions & 4 deletions macros.in
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,12 @@ Supplements: (%{name} = %{version}-%{release} and langpacks-%{1})\
# Is ignored when SOURCE_DATE_EPOCH is not set.
%use_source_date_epoch_as_buildtime 0

# If true, make sure that timestamps in built rpms
# are not later than the value of SOURCE_DATE_EPOCH.
# Is ignored when SOURCE_DATE_EPOCH is not set.
%clamp_mtime_to_source_date_epoch 0
# Defines file timestamp handling in built rpms. Possible values
# are "clamp_to_buildtime" and "clamp_to_source_date_epoch",
# which makes sure the the file timestamps are not later than
# the build time of the package or the value of
# SOURCE_DATE_EPOCH, respectively.
#%build_mtime_policy

# If enabled, dilute user() and group() requires into recommends
#%_use_weak_usergroup_deps 1
Expand Down

0 comments on commit c9579db

Please sign in to comment.