60 lines
1.9 KiB
Diff
60 lines
1.9 KiB
Diff
Based on https://gcc.gnu.org/ml/gcc-patches/2015-06/txtLtaPOCTgpq.txt
|
|
|
|
Support for deterministic builds with externally defined
|
|
values for the macros __DATE__, __TIME__ and __DATETIME__.
|
|
|
|
If the environment variable SOURCE_DATE_EPOCH is defined,
|
|
use its value instead of the time(2) return value as
|
|
seconds since the Epoch.
|
|
|
|
Use strtoll() to convert SOURCE_DATE_EPOCH just in case
|
|
time_t is some day promoted to a 64 bit value.
|
|
|
|
--- libcpp/macro.c
|
|
+++ libcpp/macro.c
|
|
@@ -356,14 +356,38 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
|
|
slow on some systems. */
|
|
time_t tt;
|
|
struct tm *tb = NULL;
|
|
+ char *source_date_epoch;
|
|
|
|
- /* (time_t) -1 is a legitimate value for "number of seconds
|
|
- since the Epoch", so we have to do a little dance to
|
|
- distinguish that from a genuine error. */
|
|
- errno = 0;
|
|
- tt = time(NULL);
|
|
- if (tt != (time_t)-1 || errno == 0)
|
|
- tb = localtime (&tt);
|
|
+ /* Allow the date and time to be set externally by an exported
|
|
+ environment variable to enable reproducible builds. */
|
|
+ source_date_epoch = getenv ("SOURCE_DATE_EPOCH");
|
|
+ if (source_date_epoch)
|
|
+ {
|
|
+ errno = 0;
|
|
+ tt = (time_t) strtoll (source_date_epoch, NULL, 10);
|
|
+ if (errno == 0)
|
|
+ {
|
|
+ tb = gmtime (&tt);
|
|
+ if (tb == NULL)
|
|
+ cpp_error (pfile, CPP_DL_ERROR,
|
|
+ "SOURCE_DATE_EPOCH=\"%s\" is not a valid date",
|
|
+ source_date_epoch);
|
|
+ }
|
|
+ else
|
|
+ cpp_error (pfile, CPP_DL_ERROR,
|
|
+ "SOURCE_DATE_EPOCH=\"%s\" is not a valid number",
|
|
+ source_date_epoch);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* (time_t) -1 is a legitimate value for "number of seconds
|
|
+ since the Epoch", so we have to do a little dance to
|
|
+ distinguish that from a genuine error. */
|
|
+ errno = 0;
|
|
+ tt = time(NULL);
|
|
+ if (tt != (time_t)-1 || errno == 0)
|
|
+ tb = localtime (&tt);
|
|
+ }
|
|
|
|
if (tb)
|
|
{
|