Skip to content

Latest commit

 

History

History

guix

Gerbil and Guix : More Scheme!

guix package -f guix/gerbil.scm

Building from “git” without .git.

I like to use guix. It builds a replicatable package and confirms it is as expected from source through binary. Which is great, but it means a consistent source tree.

That means no .git. But for both conveniences and the fact that the Gerbil developers are not package managers (or, at least, the gerbil source tree is not meant to be a package … or some such), Gerbil and Gambit in general rely on a git tree to tell them certain things.

There is Fare’s nix package which helped.

https://github.com/muknio/nixpkgs/tree/devel/pkgs/development/compilers/gerbil

Gambit: versions and dates.

Gambit has 3 things that are set from git and/or defaulted to something that we need to change

STAMP_VERSION
git describe --tag --always
STAMP_YMD
(TZ=UTC git show --quiet --date='format-local:%Y%m%d' --format=%cd)
STAMP_HMS
(TZ=UTC git show --quiet --date='format-local:%H%M%S' --format=%cd)
set -eu
cd $(dirname "$0") # Change to this directory
GS_FILE="$(pwd)/gambit-stamp.scm"

cd ../src/gambit

STAMP_VERSION=$(git describe --tag --always)
STAMP_YMD=$(TZ=UTC git show --quiet --date='format-local:%Y%m%d' --format=%cd)
STAMP_HMS=$(TZ=UTC git show --quiet --date='format-local:%H%M%S' --format=%cd)

echo "(define gambit-stamp-version \"$STAMP_VERSION\")" | tee "$GS_FILE"
echo "(define gambit-stamp-ymd \"$STAMP_YMD\")" | tee -a "$GS_FILE"
echo "(define gambit-stamp-hms \"$STAMP_HMS\")" | tee -a "$GS_FILE"

Then we just need to update certain things in gambit.

(include "gambit-stamp.scm")

(define gambit-sub-config
  `(substitute* "src/gambit/configure"
	      (("^PACKAGE_VERSION=.*")
	       ,(string-append "PACKAGE_VERSION='"gambit-stamp-version"'\n"))
	      (("^PACKAGE_STRING=.*")
	       ,(string-append "PACKAGE_STRING='Gambit "gambit-stamp-version"'\n"))))


(define gambit-stamp.h
  `(begin (with-output-to-file "src/gambit/include/stamp.h.new"
	    (lambda () (display (string-append "
/* Automatically generated */

#ifndef ___STAMP_VERSION
#define ___STAMP_VERSION \"",gambit-stamp-version"\"
#endif

#ifndef ___STAMP_YMD
#define ___STAMP_YMD ",gambit-stamp-ymd"
#endif

#ifndef ___STAMP_HMS
#define ___STAMP_HMS ",gambit-stamp-hms"
#endif\n"))))
	  (substitute* "src/gambit/include/makefile.in"
		       (("^(.*)echo > stamp.h;" _ ws)
			(string-append ws "cp -v stamp.h.new stamp.h;")))))
			    
	     

Gerbil versions

At build time gerbil defines the version by looking at git. We don’t have git.

I think the only place is src/gerbil/runtime/version.ss.

That gets built by src/build/build-version.scm so let us replace that.

set -eu
cd $(dirname "$0") # Change to this directory
GS_FILE="$(pwd)/gerbil-stamp.scm"

STAMP_VERSION=$(git describe --tag --always)

echo "(define gerbil-stamp-version \"$STAMP_VERSION\")" | tee "$GS_FILE"
(include "gerbil-stamp.scm")

(define gerbil-build-version
  `(with-output-to-file "src/build/build-version.scm"
     (lambda ()
       (write
	'(let* ((gerbil-version-path
		 (path-expand "gerbil/runtime/version.ss" (getenv "GERBIL_SOURCE")))
		(gerbil-version-text
		 (string-append "(def (gerbil-version-string) \"" ,gerbil-stamp-version "\")\n")))
	   (display "... write ") (display gerbil-version-path) (newline)
	   (call-with-output-file `(path: ,gerbil-version-path create: maybe append: #f truncate: #t)
	     (lambda (port) (display gerbil-version-text port))))))))

And Gerbil’s ./configure calls git a bunch. As luck would have it this only time it uses the value AND is not already done by guix’s git-fetch is to see the version.

(define gerbil-conf-sub-git
 `(substitute* "configure"
   (("set -e") (string-append "set -e ; git () { echo \"",gerbil-stamp-version"\" ;}\n"))))

The --install-from-file file

(define-module (gerbil packages)
  #:use-module (gnu packages commencement)
  #:use-module (gnu packages linux)
  #:use-module (guix packages)
  #:use-module (guix build-system gnu)
  #:use-module ((guix licenses) #:prefix l:)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages)
  #:use-module (gnu packages version-control)
  #:use-module (gnu packages base)
  #:use-module (guix git-download)
  #:use-module (guix derivations)
  #:use-module (gnu packages tls)
  #:use-module (gnu packages web)
  #:use-module (gnu packages serialization)
  #:use-module (gnu packages sqlite)
  #:use-module (gnu packages xml)
  #:use-module (gnu packages databases)
  #:use-module (guix store))

(include "gambit-build-utils.scm")
(include "gerbil-build-utils.scm")

(include "gerbil-package.scm")

The package form

(package
 (name "gerbil")
 (version "0.18.1")
 (source
  (origin
   (method git-fetch)
   (uri (git-reference
	 (recursive? #t)
         (url "https://github.com/mighty-gerbils/gerbil.git")
         (commit "0917172a519d28c7833886b445938fd250717b2a")))
   (file-name (git-file-name name version))
   (sha256
    (base32 "0cxpsf7n9nbk39i2n11kpvgm81qkzkskymq32d40cqajfixd5k9x"))))
 (arguments
  `(#:phases
    (modify-phases
     %standard-phases
     (delete 'bootstrap)
     (add-after
      'unpack 'create-versions
      (lambda* (#:key source #:allow-other-keys)
	       ,gambit-sub-config
	       ,gambit-stamp.h
	       ,gerbil-build-version
	       ,gerbil-conf-sub-git))
     (add-before 'build 'add-tmp-home
       (lambda _ (setenv "HOME" "/tmp/gerbil-build")))
     (delete 'check))
    #:make-flags '("CC=gcc")))
 (native-inputs
  `(("coreutils" ,coreutils)
    ("util-linux" ,util-linux)))
 (propagated-inputs
  `(("zlib" ,zlib)
    ("openssl" ,openssl)
    ("sqlite" ,sqlite)))
 (build-system gnu-build-system)
 (synopsis "Meta-dialect of Scheme with post-modern features")
 (description "Gerbil is an opinionated dialect of Scheme designed for Systems
Programming, with a state of the art macro and module system on top of the Gambit
runtime.  The macro system is based on quote-syntax, and provides the full meta-syntactic
tower with a native implementation of syntax-case.  It also provides a full-blown module
system, similar to PLT Scheme's (sorry, Racket) modules.  The main difference from Racket
is that Gerbil modules are single instantiation, supporting high performance ahead of
time compilation and compiled macros.")
 (home-page "https://cons.io")
 (license `(,l:lgpl2.1 ,l:asl2.0)))