summaryrefslogtreecommitdiff
path: root/debian/patches/ada-lib-info-source-date-epoch.diff
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/ada-lib-info-source-date-epoch.diff')
-rw-r--r--debian/patches/ada-lib-info-source-date-epoch.diff144
1 files changed, 144 insertions, 0 deletions
diff --git a/debian/patches/ada-lib-info-source-date-epoch.diff b/debian/patches/ada-lib-info-source-date-epoch.diff
new file mode 100644
index 0000000..794a2ba
--- /dev/null
+++ b/debian/patches/ada-lib-info-source-date-epoch.diff
@@ -0,0 +1,144 @@
+Description: set ALI timestamps from SOURCE_DATE_EPOCH if available.
+ When the SOURCE_DATE_EPOCH environment variable is set,
+ replace timestamps more recent than its value with its value
+ when writing Ada Library Information (ALI) files.
+ This allow reproducible builds from generated or patched Ada sources.
+ https://reproducible-builds.org/specs/source-date-epoch/
+Author: Nicolas Boulenguez <nicolas@debian.org>
+
+--- a/src/gcc/ada/ali-util.adb
++++ b/src/gcc/ada/ali-util.adb
+@@ -484,8 +484,10 @@ package body ALI.Util is
+ for D in ALIs.Table (A).First_Sdep .. ALIs.Table (A).Last_Sdep loop
+ Src := Source_Id (Get_Name_Table_Int (Sdep.Table (D).Sfile));
+
+- if Opt.Minimal_Recompilation
+- and then Sdep.Table (D).Stamp /= Source.Table (Src).Stamp
++ if (Opt.Minimal_Recompilation
++ and then Sdep.Table (D).Stamp /= Source.Table (Src).Stamp)
++ or else (Sdep.Table (D).Stamp = Source_Date_Epoch
++ and then Source_Date_Epoch < Source.Table (Src).Stamp)
+ then
+ -- If minimal recompilation is in action, replace the stamp
+ -- of the source file in the table if checksums match.
+--- a/src/gcc/ada/lib-writ.adb
++++ b/src/gcc/ada/lib-writ.adb
+@@ -1559,7 +1559,14 @@ package body Lib.Writ is
+
+ Write_Info_Name_May_Be_Quoted (Fname);
+ Write_Info_Tab (25);
+- Write_Info_Str (String (Time_Stamp (Sind)));
++ declare
++ T : Time_Stamp_Type := Time_Stamp (Sind);
++ begin
++ if Source_Date_Epoch < T then
++ T := Source_Date_Epoch;
++ end if;
++ Write_Info_Str (String (T));
++ end;
+ Write_Info_Char (' ');
+ Write_Info_Str (Get_Hex_String (Source_Checksum (Sind)));
+
+--- a/src/gcc/ada/osint.adb
++++ b/src/gcc/ada/osint.adb
+@@ -1686,6 +1686,20 @@ package body Osint is
+
+ Lib_Search_Directories.Set_Last (Primary_Directory);
+ Lib_Search_Directories.Table (Primary_Directory) := new String'("");
++
++ -- Look for Source_Date_Epoch in the environment.
++ declare
++ Env_Var : String_Access;
++ Get_OK : Boolean;
++ Epoch : OS_Time;
++ begin
++ Env_Var := Getenv ("SOURCE_DATE_EPOCH");
++ Get_OS_Time_From_String (Env_Var.all, Get_OK, Epoch);
++ Free (Env_Var);
++ if Get_OK then
++ Source_Date_Epoch := OS_Time_To_GNAT_Time (Epoch);
++ end if;
++ end;
+ end Initialize;
+
+ ------------------
+--- a/src/gcc/ada/osint.ads
++++ b/src/gcc/ada/osint.ads
+@@ -683,6 +683,17 @@ package Osint is
+ function Prep_Suffix return String;
+ -- The suffix used for preprocessed files
+
++ Source_Date_Epoch : Time_Stamp_Type := Time_Stamp_Type'("99991231235959");
++ -- * gnat1 truncates to this date time stamps written to ALI files, making
++ -- their contents deterministic even for patched or generated sources.
++ -- See https://reproducible-builds.org/specs/source-date-epoch.
++ -- * When gnatmake reads this date from an ALI file, and the source file is
++ -- more recent, it ignores the dates and only considers checksums as if
++ -- Minimal_Recompilation was selected. Else, the source would always
++ -- be detected as requiring a recompilation.
++ -- The default value has no effect, but Initialize will assign it if
++ -- SOURCE_DATE_EPOCH in the environment represents a valid epoch.
++
+ private
+
+ Current_Main : File_Name_Type := No_File;
+--- a/src/gcc/ada/libgnat/s-os_lib.adb
++++ b/src/gcc/ada/libgnat/s-os_lib.adb
+@@ -1146,6 +1146,41 @@ package body System.OS_Lib is
+ return Result;
+ end Get_Object_Suffix;
+
++ -----------------------------
++ -- Get_OS_Time_From_String --
++ -----------------------------
++
++ procedure Get_OS_Time_From_String (Arg : String;
++ Success : out Boolean;
++ Result : out OS_Time) is
++ -- Calling System.Val_LLI breaks the bootstrap sequence.
++ Digit : OS_Time;
++ begin
++ Result := 0;
++ if Arg'Length = 0 then
++ Success := False;
++ return;
++ end if;
++ for I in Arg'Range loop
++ if Arg (I) not in '0' .. '9' then
++ Success := False;
++ return;
++ end if;
++ Digit := OS_Time (Character'Pos (Arg (I)) - Character'Pos ('0'));
++ if OS_Time'Last / 10 < Result then
++ Success := False;
++ return;
++ end if;
++ Result := Result * 10;
++ if OS_Time'Last - Digit < Result then
++ Success := False;
++ return;
++ end if;
++ Result := Result + Digit;
++ end loop;
++ Success := True;
++ end Get_OS_Time_From_String;
++
+ ----------------------------------
+ -- Get_Target_Debuggable_Suffix --
+ ----------------------------------
+--- a/src/gcc/ada/libgnat/s-os_lib.ads
++++ b/src/gcc/ada/libgnat/s-os_lib.ads
+@@ -164,6 +164,13 @@ package System.OS_Lib is
+ -- component parts to be interpreted in the local time zone, and returns
+ -- an OS_Time. Returns Invalid_Time if the creation fails.
+
++ procedure Get_OS_Time_From_String (Arg : String;
++ Success : out Boolean;
++ Result : out OS_Time);
++ -- Success is set if Arg is not empty, only contains decimal
++ -- digits and represents an integer within OS_Time range. Result
++ -- is then affected with the represented value.
++
+ ----------------
+ -- File Stuff --
+ ----------------