1
0
Files
gcc-14/debian/patches/ada-lib-info-source-date-epoch.diff
Konstantin Demin c2c1923c7b initial import from Debian
version: 14.3.0-5
commit: bee30ab0fff2fd6af94c62376c8aa4221bb831e0
2025-08-11 15:00:09 +03:00

122 lines
4.8 KiB
Diff

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/
.
Also see debian/ada/test_ada_source_date_epoch.sh.
Author: Nicolas Boulenguez <nicolas@debian.org>
--- a/src/gcc/ada/osint.adb
+++ b/src/gcc/ada/osint.adb
@@ -64,6 +64,10 @@ package body Osint is
-- Used in Locate_File as a fake directory when Name is already an
-- absolute path.
+ Source_Date_Epoch : OS_Time := Invalid_Time;
+ -- Set at startup by the Initialize procedure.
+ -- See the specification of the File_Time_Stamp functions.
+
-------------------------------------
-- Use of Name_Find and Name_Enter --
-------------------------------------
@@ -1126,8 +1130,14 @@ package body Osint is
is
function Internal (N : C_File_Name; A : System.Address) return OS_Time;
pragma Import (C, Internal, "__gnat_file_time_name_attr");
+ T : OS_Time := Internal (Name, Attr.all'Address);
begin
- return Internal (Name, Attr.all'Address);
+ if Source_Date_Epoch /= Invalid_Time and then T /= Invalid_Time
+ and then Source_Date_Epoch < T
+ then
+ T := Source_Date_Epoch;
+ end if;
+ return T;
end File_Time_Stamp;
function File_Time_Stamp
@@ -1150,6 +1160,7 @@ package body Osint is
----------------
function File_Stamp (Name : File_Name_Type) return Time_Stamp_Type is
+ T : OS_Time;
begin
if Name = No_File then
return Empty_Time_Stamp;
@@ -1161,9 +1172,13 @@ package body Osint is
-- not exist, and OS_Time_To_GNAT_Time will convert this value to
-- Empty_Time_Stamp. Therefore we do not need to first test whether
-- the file actually exists, which saves a system call.
-
- return OS_Time_To_GNAT_Time
- (File_Time_Stamp (Name_Buffer (1 .. Name_Len)));
+ T := File_Time_Stamp (Name_Buffer (1 .. Name_Len));
+ if Source_Date_Epoch /= Invalid_Time and then T /= Invalid_Time
+ and then Source_Date_Epoch < T
+ then
+ T := Source_Date_Epoch;
+ end if;
+ return OS_Time_To_GNAT_Time (T);
end File_Stamp;
function File_Stamp (Name : Path_Name_Type) return Time_Stamp_Type is
@@ -3261,4 +3276,34 @@ begin
Osint.Initialize;
end Initialization;
+ -- When the SOURCE_DATE_EPOCH the environment variable is not empty,
+ -- only contains decimal digits and represents a value lower than 2**63,
+ -- set Source_Date_Epoch to this value.
+ Set_Source_Date_Epoch : declare
+ Env_Var : String_Access := Getenv ("SOURCE_DATE_EPOCH");
+ Epoch : Long_Long_Integer range 0 .. Long_Long_Integer'Last := 0;
+ Index : Integer range Env_Var.all'First .. Env_Var.all'Last + 1
+ := Env_Var.all'First;
+ Digit : Long_Long_Integer;
+ begin
+ if Index <= Env_Var.all'Last then
+ -- Calling System.Val_LLI breaks the bootstrap sequence.
+ loop
+ Digit := Character'Pos (Env_Var.all (Index)) - Character'Pos ('0');
+ exit when Digit not in 0 .. 9;
+ exit when Long_Long_Integer'Last - Digit < Epoch;
+ Epoch := Epoch + Digit;
+ if Index = Env_Var.all'Last then
+ Source_Date_Epoch := To_Ada (Epoch);
+ exit;
+ end if;
+ Index := Index + 1;
+ -- The division is computed once at build time.
+ exit when Long_Long_Integer'Last / 10 < Epoch;
+ Epoch := Epoch * 10;
+ end loop;
+ end if;
+ Free (Env_Var);
+ end Set_Source_Date_Epoch;
+
end Osint;
--- a/src/gcc/ada/osint.ads
+++ b/src/gcc/ada/osint.ads
@@ -196,6 +196,7 @@ package Osint is
-- information in order to locate it. If the source file cannot be opened,
-- or Name = No_File, and all blank time stamp is returned (this is not an
-- error situation).
+ -- Handles SOURCE_DATE_EPOCH like File_Time_Stamp functions below.
function File_Stamp (Name : Path_Name_Type) return Time_Stamp_Type;
-- Same as above for a path name
@@ -303,6 +304,11 @@ package Osint is
(Name : Path_Name_Type;
Attr : access File_Attributes) return Time_Stamp_Type;
-- Return the time stamp of the file
+ -- If the SOURCE_DATE_EPOCH environment variable exists and represents
+ -- an OS_Type value, any more recent file time stamp is truncated.
+ -- This ensures that gnat1 writes deterministic .ali files even in
+ -- the presence of patched or generated sources. See
+ -- https://reproducible-builds.org/specs/source-date-epoch.
function Is_Readable_File
(Name : C_File_Name;