Hello,

I’ve been looking, in the past few days, at how to make CHICKEN
produce C files deterministically.

My goal here is to make it easier for package managers like Guix to
ship CHICKEN, as well as help us see how compiler changes affect the
generated output. I’m also highly interested in getting the same
binaries each time I compile a CHICKEN project.

So, here is a patch that does just that. I tried to make it as little
as possible and may have missed a few things.

The main problem was that the symbol hash table used a random seed,
which made the symbol order in the C files random. That’s what the new
deterministic-build unit addresses.

The other main source of non-determinism was the mention of the build
host and date at the top of the generated C files. I removed that
entirely as it doesn’t seem really useful.

I have left two identifiers untouched yet, unique-id in c-backend.scm
and make-random-name in support.scm. Both use (current-seconds) which
I want to remove.

Though it seems unique-id isn’t used anywhere, can I remove it
entirely?

About make-random-name, would it be ok to just remove the
current-seconds call or replace it with something else?

I also changed the default `ar` invocation options to make it generate
the same .a file each time it’s called with the same files, but sadly
the deterministic option doesn’t exist on Apple computers.

I hope all of this isn’t too messy. Please tell me what you think
about this change, I don’t want to impose anything.

If the change is accepted, I’ll make a new version of the patch and
port everything to chicken-5 as soon as I know what to do with the
remaining two identifiers.

Thanks in advance!


>From 1e8f302e018f60dfc48d05bbff85526e1d3d82e0 Mon Sep 17 00:00:00 2001
From: Kooda <[email protected]>
Date: Sun, 5 Jun 2016 13:45:38 +0200
Subject: [PATCH] Make CHICKEN build process deterministic

---
 c-backend.scm           | 47 ++++++++++++++++++++---------------------------
 chicken.scm             |  2 +-
 defaults.make           |  2 +-
 deterministic-build.scm |  2 ++
 library.scm             |  5 +----
 rules.make              |  4 ++--
 6 files changed, 27 insertions(+), 35 deletions(-)
 create mode 100644 deterministic-build.scm

diff --git a/c-backend.scm b/c-backend.scm
index cbe5895..bfd44fa 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -505,34 +505,27 @@
        (if (< n 10)
            (string-append "0" (number->string n))
            n) )
-      (let* ((tm (##sys#decode-seconds (current-seconds) #f))
-            (min (vector-ref tm 1))
-            (hour (vector-ref tm 2))
-            (mday (vector-ref tm 3))
-            (mon (vector-ref tm 4))
-            (year (vector-ref tm 5)) )
-       (gen "/* Generated from " source-file " by the CHICKEN compiler" #t
-            "   http://www.call-cc.org"; #t
-            "   " (+ 1900 year) #\- (pad0 (add1 mon)) #\- (pad0 mday) #\space 
(pad0 hour) #\: (pad0 min) #t
-            (string-intersperse
-             (map (cut string-append "   " <> "\n") 
-                  (string-split (chicken-version #t) "\n") ) 
-             "")
-            "   command line: ")
-       (gen-list compiler-arguments)
+      (gen "/* Generated from " source-file " by the CHICKEN compiler" #t
+          "   http://www.call-cc.org"; #t
+          (string-intersperse
+           (map (cut string-append "   " <> "\n")
+                (string-split (chicken-version #t) "\n") )
+           "")
+          "   command line: ")
+      (gen-list compiler-arguments)
+      (gen #t)
+      (cond [unit-name (gen "   unit: " unit-name)]
+           [else
+            (gen "   used units: ")
+            (gen-list used-units) ] )
+      (gen #t "*/" #t #t "#include \"" target-include-file "\"")
+      (when external-protos-first
+       (generate-foreign-callback-stub-prototypes foreign-callback-stubs) )
+      (when (pair? foreign-declarations)
        (gen #t)
-       (cond [unit-name (gen "   unit: " unit-name)]
-             [else 
-              (gen "   used units: ")
-              (gen-list used-units) ] )
-       (gen #t "*/" #t #t "#include \"" target-include-file "\"")
-       (when external-protos-first
-         (generate-foreign-callback-stub-prototypes foreign-callback-stubs) )
-       (when (pair? foreign-declarations)
-         (gen #t)
-         (for-each (lambda (decl) (gen #t decl)) foreign-declarations) )
-       (unless external-protos-first
-         (generate-foreign-callback-stub-prototypes foreign-callback-stubs) ) 
) )
+       (for-each (lambda (decl) (gen #t decl)) foreign-declarations) )
+      (unless external-protos-first
+       (generate-foreign-callback-stub-prototypes foreign-callback-stubs) )  )
   
     (define (trailer)
       (gen #t #t "/*" #t 
diff --git a/chicken.scm b/chicken.scm
index c1e4a10..ebf9d03 100644
--- a/chicken.scm
+++ b/chicken.scm
@@ -26,7 +26,7 @@
 
 
 (declare
-  (uses chicken-syntax chicken-ffi-syntax 
+  (uses deterministic-build library eval chicken-syntax chicken-ffi-syntax
        srfi-1 srfi-4 utils files extras data-structures srfi-69
        lolevel ; unused, but loaded to make foldable bindings available
        support compiler optimizer lfa2 compiler-syntax scrutinizer
diff --git a/defaults.make b/defaults.make
index 1b11241..8071151 100644
--- a/defaults.make
+++ b/defaults.make
@@ -154,7 +154,7 @@ LINKER_LIBRARY_SUFFIX ?=
 endif
 LINKER_LINK_SHARED_LIBRARY_OPTIONS ?= -shared
 LINKER_LINK_SHARED_DLOADABLE_OPTIONS ?= -shared -L.
-LIBRARIAN_OPTIONS ?= cru
+LIBRARIAN_OPTIONS ?= crD
 LIBRARIAN_OUTPUT_OPTION ?=
 LIBRARIAN_OUTPUT ?= $(LIBRARIAN_OUTPUT_OPTION) $@
 LIBRARIES ?= -lm
diff --git a/deterministic-build.scm b/deterministic-build.scm
new file mode 100644
index 0000000..d0c6e46
--- /dev/null
+++ b/deterministic-build.scm
@@ -0,0 +1,2 @@
+(declare (unit deterministic-build))
+(##core#inline "C_randomize" 0)
diff --git a/library.scm b/library.scm
index a32ee8c..d22e17a 100644
--- a/library.scm
+++ b/library.scm
@@ -3719,12 +3719,9 @@ EOF
         (if ##sys#build-branch (string-append " (" ##sys#build-branch ")") "")
         (if ##sys#build-id (string-append " (rev " ##sys#build-id ")") "")
         "\n"
-        (get-config)
         (if (zero? (##sys#size spec))
             ""
-            (string-append " [" spec " ]") )
-        "\n"
-        (or (##sys#build-tag) "")))
+            (string-append "[" spec " ]") ) ) )
       ##sys#build-version) )
 
 
diff --git a/rules.make b/rules.make
index d61e5d4..af87e78 100644
--- a/rules.make
+++ b/rules.make
@@ -45,7 +45,7 @@ LIBCHICKEN_STATIC_OBJECTS = 
$(LIBCHICKEN_OBJECTS_1:=-static$(O))
 
 COMPILER_OBJECTS_1 = \
        chicken batch-driver compiler optimizer lfa2 compiler-syntax 
scrutinizer support \
-       c-platform c-backend
+       c-platform c-backend deterministic-build
 COMPILER_OBJECTS        = $(COMPILER_OBJECTS_1:=$(O))
 COMPILER_STATIC_OBJECTS = $(COMPILER_OBJECTS_1:=-static$(O))
 
@@ -573,7 +573,7 @@ $(foreach obj, $(IMPORT_LIBRARIES),\
 define declare-bootstrap-compiler-object
 $(1).c: $$(SRCDIR)$(1).scm $$(SRCDIR)compiler-namespace.scm \
          $$(SRCDIR)private-namespace.scm $$(SRCDIR)tweaks.scm
-       $$(CHICKEN) $$< $$(CHICKEN_COMPILER_OPTIONS) -output-file $$@ 
+       $$(CHICKEN) $$< $$(CHICKEN_COMPILER_OPTIONS) -explicit-use -output-file 
$$@
 endef
 
 $(foreach obj, $(COMPILER_OBJECTS_1),\
-- 
2.1.4

_______________________________________________
Chicken-hackers mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/chicken-hackers

Reply via email to