Package: valac
Version: 0.30.0-2
Severity: wishlist
Tags: patch
User: reproducible-bui...@lists.alioth.debian.org
Usertags: toolchain randomness
X-Debbugs-Cc: reproducible-bui...@lists.alioth.debian.org

While working on the "reproducible builds" effort [1], we have noticed
that the gnome-clocks package doesn't build reproducibly because the
C files generated by valac vary between builds. A sample diff is

  --- a/src/timer.c
  +++ b/src/timer.c
  @@ -1277,8 +1277,8 @@ static void 
clocks_timer_face_clocks_clock_interface_init (ClocksClockIface * if
   static void clocks_timer_face_instance_init (ClocksTimerFace * self) {
          self->priv = CLOCKS_TIMER_FACE_GET_PRIVATE (self);
          self->priv->_state = CLOCKS_TIMER_FACE_STATE_STOPPED;
  -       g_type_ensure (CLOCKS_TYPE_ANALOG_FRAME);
          g_type_ensure (CLOCKS_TIMER_TYPE_COUNTDOWN_FRAME);
  +       g_type_ensure (CLOCKS_TYPE_ANALOG_FRAME);
          gtk_widget_init_template (GTK_WIDGET (self));
   }

The order of the two g_type_ensure() calls varies more or less randomly.
 
I've tracked this down to a HashSet data structure in Vala.GtkModule
that holds these classes in the C code generation phase. Changing that
to an ordered List type instead fixes the issue. Please consider the
attached patch.

While gnome-clocks seems to be the only affected package, I'm also seeing
this with gnome-contacts when I force regeneration of the C files there.
They are currently not rebuilt from their vala sources during the package
build (#802520).

I'm also attaching a minified test case for your convenience. The generated
t.c varies for me between the compilations with the current valac in sid
but not with a patched one.

[1] https://wiki.debian.org/ReproducibleBuilds
-- 
Niko Tyni   nt...@debian.org
>From 901ec8b07fefb81938f54414e57974ffd095eed3 Mon Sep 17 00:00:00 2001
From: Niko Tyni <nt...@debian.org>
Date: Mon, 19 Oct 2015 23:56:36 +0300
Subject: [PATCH] Preserve order of current_required_app_classes for
 reproducibility

The elements of current_required_app_classes end up in the generated
code in g_type_ensure() statements. The order of these can vary
between builds when using a HashSet, breaking reproducibilty.

See https://wiki.debian.org/ReproducibleBuilds
---
 codegen/valagtkmodule.vala | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/codegen/valagtkmodule.vala b/codegen/valagtkmodule.vala
index ecc709f..c0f439a 100644
--- a/codegen/valagtkmodule.vala
+++ b/codegen/valagtkmodule.vala
@@ -32,7 +32,7 @@ public class Vala.GtkModule : GSignalModule {
 	/* GtkBuilder xml child to Vala class mapping */
 	private HashMap<string, Class> current_child_to_class_map = new HashMap<string, Class>(str_hash, str_equal);
 	/* Required custom application-specific gtype classes to be ref'd before initializing the template */
-	private HashSet<Class> current_required_app_classes = new HashSet<Class>();
+	private List<Class> current_required_app_classes = new ArrayList<Class>();
 
 	private void ensure_cclass_to_vala_map () {
 		// map C name of gtypeinstance classes to Vala classes
-- 
2.5.1

Attachment: valac-reproducibility.tar.gz
Description: application/gzip

Reply via email to