Commit f3f431a712729a1af94d01bd1bfde17a252ff02c

Authored by Paul Kocialkowski
Committed by Tom Rini
1 parent 9c57487752

Reproducible U-Boot build support, using SOURCE_DATE_EPOCH

In order to achieve reproducible builds in U-Boot, timestamps that are defined
at build-time have to be somewhat eliminated. The SOURCE_DATE_EPOCH environment
variable allows setting a fixed value for those timestamps.

Simply by setting SOURCE_DATE_EPOCH to a fixed value, a number of targets can be
built reproducibly. This is the case for e.g. sunxi devices.

However, some other devices might need some more tweaks, especially regarding
the image generation tools.

Signed-off-by: Paul Kocialkowski <contact@paulk.fr>

Showing 3 changed files with 36 additions and 4 deletions Side-by-side Diff

... ... @@ -1230,9 +1230,10 @@
1230 1230 endef
1231 1231  
1232 1232 define filechk_timestamp.h
1233   - (LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \
1234   - LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \
1235   - LC_ALL=C date +'#define U_BOOT_TZ "%z"')
  1233 + (SOURCE_DATE="$${SOURCE_DATE_EPOCH:+@$$SOURCE_DATE_EPOCH}"; \
  1234 + LC_ALL=C date -u -d "$${SOURCE_DATE:-now}" +'#define U_BOOT_DATE "%b %d %C%y"'; \
  1235 + LC_ALL=C date -u -d "$${SOURCE_DATE:-now}" +'#define U_BOOT_TIME "%T"'; \
  1236 + LC_ALL=C date -u -d "$${SOURCE_DATE:-now}" +'#define U_BOOT_TZ "%z"' )
1236 1237 endef
1237 1238  
1238 1239 $(version_h): include/config/uboot.release FORCE
... ... @@ -5081,6 +5081,18 @@
5081 5081 - CONFIG_SYS_MEM_TOP_HIDE_MIN
5082 5082 Define minimum DDR size to be hided from top of the DDR memory
5083 5083  
  5084 +Reproducible builds
  5085 +-------------------
  5086 +
  5087 +In order to achieve reproducible builds, timestamps used in the U-Boot build
  5088 +process have to be set to a fixed value.
  5089 +
  5090 +This is done using the SOURCE_DATE_EPOCH environment variable.
  5091 +SOURCE_DATE_EPOCH is to be set on the build host's shell, not as a configuration
  5092 +option for U-Boot or an environment variable in U-Boot.
  5093 +
  5094 +SOURCE_DATE_EPOCH should be set to a number of seconds since the epoch, in UTC.
  5095 +
5084 5096 Building the Software:
5085 5097 ======================
5086 5098  
tools/default_image.c
... ... @@ -88,6 +88,9 @@
88 88 struct image_tool_params *params)
89 89 {
90 90 uint32_t checksum;
  91 + char *source_date_epoch;
  92 + struct tm *time_universal;
  93 + time_t time;
91 94  
92 95 image_header_t * hdr = (image_header_t *)ptr;
93 96  
94 97  
... ... @@ -96,9 +99,25 @@
96 99 sizeof(image_header_t)),
97 100 sbuf->st_size - sizeof(image_header_t));
98 101  
  102 + source_date_epoch = getenv("SOURCE_DATE_EPOCH");
  103 + if (source_date_epoch != NULL) {
  104 + time = (time_t) strtol(source_date_epoch, NULL, 10);
  105 +
  106 + time_universal = gmtime(&time);
  107 + if (time_universal == NULL) {
  108 + fprintf(stderr, "%s: SOURCE_DATE_EPOCH is not valid\n",
  109 + __func__);
  110 + time = 0;
  111 + } else {
  112 + time = mktime(time_universal);
  113 + }
  114 + } else {
  115 + time = sbuf->st_mtime;
  116 + }
  117 +
99 118 /* Build new header */
100 119 image_set_magic(hdr, IH_MAGIC);
101   - image_set_time(hdr, sbuf->st_mtime);
  120 + image_set_time(hdr, time);
102 121 image_set_size(hdr, sbuf->st_size - sizeof(image_header_t));
103 122 image_set_load(hdr, params->addr);
104 123 image_set_ep(hdr, params->ep);