1
Fork 0
mirror of https://https.git.savannah.gnu.org/git/guix.git/ synced 2025-07-14 19:10:49 +02:00
guix/gnu/packages/patches/mono-1.9.1-reproducibility.patch
Danny Milosavljevic fd256bb786
gnu: mono@2.4.2.3: Make it reproducible.
* gnu/packages/patches/mono-2.4.2.3-fix-parallel-builds.patch: New file.
* gnu/packages/patches/mono-2.4.2.3-reproducibility.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add references to those patches.
* gnu/packages/dotnet.scm (mono-2.4.2.3)[source]: Use those patches.
[arguments]<#:phases>[disable-mono-mini-timestamps]: New phase.

Change-Id: Ib0a57d2e93b8b72c10fa9854a77eadeee578266c
Reviewed-by: Ludovic Courtès <ludo@gnu.org>
Signed-off-by: Sharlatan Hellseher <sharlatanus@gmail.com>
2025-06-23 23:05:44 +01:00

216 lines
8.1 KiB
Diff

Author: Danny Milosavljevic <dannym@friendly-machines.com>
Date: 10 Jun 2025
Subject: Fix sources of non-reproducibility.
diff -ru orig/mono-1.9.1-checkout/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs mono-1.9.1-checkout/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
--- orig/mono-1.9.1-checkout/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs 2025-06-09 11:58:58.679365113 +0200
+++ mono-1.9.1-checkout/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs 2025-06-09 19:10:46.839764717 +0200
@@ -80,7 +80,7 @@
this.assembly = this.assemblyb = assb;
this.transient = transient;
// to keep mcs fast we do not want CryptoConfig wo be involved to create the RNG
- guid = Guid.FastNewGuidArray ();
+ guid = new byte[16]; // = Guid.Empty.ToByteArray();
// guid = Guid.NewGuid().ToByteArray ();
table_idx = get_next_table_index (this, 0x00, true);
name_cache = new Hashtable ();
diff -ru orig/mono-1.9.1-checkout/mcs/class/Mono.Cecil/Mono.Cecil.Binary/ImageInitializer.cs mono-1.9.1-checkout/mcs/class/Mono.Cecil/Mono.Cecil.Binary/ImageInitializer.cs
--- orig/mono-1.9.1-checkout/mcs/class/Mono.Cecil/Mono.Cecil.Binary/ImageInitializer.cs 2025-06-09 11:58:58.233978153 +0200
+++ mono-1.9.1-checkout/mcs/class/Mono.Cecil/Mono.Cecil.Binary/ImageInitializer.cs 2025-06-09 16:46:46.086454131 +0200
@@ -132,6 +132,15 @@
public static uint TimeDateStampFromEpoch ()
{
+ string sourceDateEpoch = Environment.GetEnvironmentVariable("SOURCE_DATE_EPOCH");
+ if (sourceDateEpoch != null && sourceDateEpoch != "") {
+ try {
+ return uint.Parse(sourceDateEpoch);
+ } catch {
+ // fallthrough
+ }
+ }
+
return (uint) DateTime.UtcNow.Subtract (
new DateTime (1970, 1, 1)).TotalSeconds;
}
diff -ru orig/mono-1.9.1-checkout/mcs/mcs/anonymous.cs mono-1.9.1-checkout/mcs/mcs/anonymous.cs
--- orig/mono-1.9.1-checkout/mcs/mcs/anonymous.cs 2025-06-09 11:58:58.814338639 +0200
+++ mono-1.9.1-checkout/mcs/mcs/anonymous.cs 2025-06-09 22:27:26.049258977 +0200
@@ -21,6 +21,7 @@
namespace Mono.CSharp {
+
public abstract class CompilerGeneratedClass : Class
{
GenericMethod generic_method;
@@ -174,6 +175,61 @@
throw new InternalErrorException ("Helper class already defined!");
}
+//
+// A comparer for all types that inherit from the abstract class 'Variable'.
+// Uses only C# 2.0 compatible syntax.
+//
+//
+public class VariableComparer : System.Collections.IComparer
+{
+ // Helper method to safely get a comparable name from any Variable type.
+ private string GetVariableName(object obj)
+ {
+ // Case 1: The object is a 'CapturedVariable' or any of its children.
+ if (obj is ScopeInfo.CapturedVariable)
+ {
+
+ ScopeInfo.CapturedVariable cv = (ScopeInfo.CapturedVariable)obj;
+ return cv.Name;
+ }
+
+ // Case 2: The object is a 'LocalVariable'
+ if (obj is LocalInfo.LocalVariable)
+ {
+ // Explicit cast required for C# 2.0
+ LocalInfo.LocalVariable lv = (LocalInfo.LocalVariable)obj;
+ return lv.LocalInfo.Name;
+ }
+
+ //
+ // Fallback for any other unknown 'Variable' subtype.
+ //
+ return obj.GetType().FullName;
+ }
+
+ // The single method required by the IComparer interface.
+ public int Compare(object x, object y)
+ {
+ // Handle nulls gracefully.
+ if (x == null && y == null) return 0;
+ if (x == null) return -1;
+ if (y == null) return 1;
+
+ string name_x = GetVariableName(x);
+ string name_y = GetVariableName(y);
+
+ // Primary Sort Key: The extracted variable name.
+ int name_compare = string.CompareOrdinal(name_x, name_y);
+ if (name_compare != 0)
+ {
+ return name_compare;
+ }
+
+ // Secondary Sort Key (Tie-breaker): The full type name.
+ return string.CompareOrdinal(x.GetType().FullName, y.GetType().FullName);
+ }
+}
+
protected class CapturedVariableField : Field
{
public CapturedVariableField (CompilerGeneratedClass helper, string name,
@@ -264,9 +320,11 @@
protected CapturedScope[] CapturedScopes {
get {
- CapturedScope[] list = new CapturedScope [captured_scopes.Count];
- captured_scopes.Values.CopyTo (list, 0);
- return list;
+ ArrayList list = new ArrayList(captured_scopes.Values);
+ list.Sort(new VariableComparer());
+ CapturedScope[] result = new CapturedScope[list.Count];
+ list.CopyTo(result, 0);
+ return result;
}
}
@@ -420,7 +478,7 @@
return new ScopeInitializer (this);
}
- protected abstract class CapturedVariable : Variable
+ public abstract class CapturedVariable : Variable
{
public readonly ScopeInfo Scope;
public readonly string Name;
@@ -493,7 +551,7 @@
}
}
- protected class CapturedParameter : CapturedVariable {
+ public class CapturedParameter : CapturedVariable {
public readonly Parameter Parameter;
public readonly int Idx;
@@ -511,7 +569,7 @@
}
}
- protected class CapturedLocal : CapturedVariable {
+ public class CapturedLocal : CapturedVariable {
public readonly LocalInfo Local;
public CapturedLocal (ScopeInfo scope, LocalInfo local)
@@ -527,7 +585,7 @@
}
}
- protected class CapturedThis : CapturedVariable {
+ public class CapturedThis : CapturedVariable {
public CapturedThis (RootScopeInfo host)
: base (host, "<>THIS", host.ParentType)
{ }
@@ -646,7 +704,9 @@
} else
scope_instance = ec.ig.DeclareLocal (type);
- foreach (CapturedLocal local in Scope.locals.Values) {
+ ArrayList sorted_locals = new ArrayList(Scope.locals.Values);
+ sorted_locals.Sort(new VariableComparer());
+ foreach (CapturedLocal local in sorted_locals) {
FieldExpr fe = (FieldExpr) Expression.MemberLookup (
ec.ContainerType, type, local.Field.Name, loc);
Report.Debug (64, "RESOLVE SCOPE INITIALIZER #2", this, Scope,
@@ -660,7 +720,9 @@
}
if (Scope.HostsParameters) {
- foreach (CapturedParameter cp in Scope.captured_params.Values) {
+ ArrayList sorted_params = new ArrayList(Scope.captured_params.Values);
+ sorted_params.Sort(new VariableComparer());
+ foreach (CapturedParameter cp in sorted_params) {
FieldExpr fe = (FieldExpr) Expression.MemberLookup (
ec.ContainerType, type, cp.Field.Name, loc);
if (fe == null)
@@ -775,7 +837,9 @@
captured_scope.EmitAssign (ec);
if (Scope.HostsParameters) {
- foreach (CapturedParameter cp in Scope.captured_params.Values) {
+ ArrayList sorted_params = new ArrayList(Scope.captured_params.Values);
+ sorted_params.Sort(new VariableComparer());
+ foreach (CapturedParameter cp in sorted_params) {
Report.Debug (128, "EMIT SCOPE INIT #6", this,
ec, ec.IsStatic, Scope, cp, cp.Field.Name);
DoEmitInstance (ec);
diff -ru orig/mono-1.9.1-checkout/mcs/mcs/statement.cs mono-1.9.1-checkout/mcs/mcs/statement.cs
--- orig/mono-1.9.1-checkout/mcs/mcs/statement.cs 2025-06-09 11:58:58.816851529 +0200
+++ mono-1.9.1-checkout/mcs/mcs/statement.cs 2025-06-09 22:07:10.441563853 +0200
@@ -1392,7 +1392,7 @@
get { return Location; }
}
- protected class LocalVariable : Variable
+ public class LocalVariable : Variable
{
public readonly LocalInfo LocalInfo;
LocalBuilder builder;
diff -ru orig/mono-1.9.1-checkout/mono/metadata/reflection.c mono-1.9.1-checkout/mono/metadata/reflection.c
--- orig/mono-1.9.1-checkout/mono/metadata/reflection.c 2025-06-09 11:58:58.903462701 +0200
+++ mono-1.9.1-checkout/mono/metadata/reflection.c 2025-06-09 18:44:58.063693593 +0200
@@ -4851,7 +4851,7 @@
header->coff.coff_machine = GUINT16_FROM_LE (assemblyb->machine);
header->coff.coff_sections = GUINT16_FROM_LE (nsections);
- header->coff.coff_time = GUINT32_FROM_LE (time (NULL));
+ header->coff.coff_time = GUINT32_FROM_LE (getenv("SOURCE_DATE_EPOCH") ? atoi(getenv("SOURCE_DATE_EPOCH")) : time (NULL));
header->coff.coff_opt_header_size = GUINT16_FROM_LE (sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4);
if (assemblyb->pekind == 1) {
/* it's a dll */