diff options
author | pukkamustard <pukkamustard@posteo.net> | 2021-01-05 19:03:18 +0100 |
---|---|---|
committer | pukkamustard <pukkamustard@posteo.net> | 2021-01-05 19:03:18 +0100 |
commit | bb70868957e0600ed5c6c393076338371637885b (patch) | |
tree | 4f6fa95f1ca187ba4c82917ca40a9937211fce63 | |
parent | 09f2aa343d87494be90357ae2267bd349f70a633 (diff) |
Add GNU build system
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | AUTHORS | 3 | ||||
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | Makefile.am | 77 | ||||
-rw-r--r-- | NEWS | 14 | ||||
-rw-r--r-- | build-aux/test-driver.scm | 180 | ||||
-rw-r--r-- | configure.ac | 39 | ||||
-rw-r--r-- | hall.scm | 3 | ||||
-rw-r--r-- | lmdb.scm | 51 | ||||
-rw-r--r-- | lmdb/internal.scm.in | 60 | ||||
-rw-r--r-- | pre-inst-env.in | 14 |
11 files changed, 398 insertions, 45 deletions
@@ -63,3 +63,4 @@ stamp-h[0-9] tmp /.version /doc/stamp-[0-9] +/lmdb/internal.scm @@ -0,0 +1,3 @@ +Contributers to guile-lmdb 0.1.0: + + pukkamustard <pukkamustard@posteo.net> diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..58e92c6 --- /dev/null +++ b/ChangeLog @@ -0,0 +1 @@ +For a complete log, please see the Git commit log at <https://inqlab.net/git/guile-lmdb.git/PATH/TO/LOG>. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..93515f1 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,77 @@ + + +bin_SCRIPTS = + +# Handle substitution of fully-expanded Autoconf variables. +do_subst = $(SED) \ + -e 's,[@]GUILE[@],$(GUILE),g' \ + -e 's,[@]guilemoduledir[@],$(guilemoduledir),g' \ + -e 's,[@]guileobjectdir[@],$(guileobjectdir),g' \ + -e 's,[@]localedir[@],$(localedir),g' + +nodist_noinst_SCRIPTS = pre-inst-env + +GOBJECTS = $(SOURCES:%.scm=%.go) + +moddir=$(prefix)/share/guile/site/$(GUILE_EFFECTIVE_VERSION) +godir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache +ccachedir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache + +nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES) +nobase_go_DATA = $(GOBJECTS) + +# Make sure source files are installed first, so that the mtime of +# installed compiled files is greater than that of installed source +# files. See +# <http://lists.gnu.org/archive/html/guile-devel/2010-07/msg00125.html> +# for details. +guile_install_go_files = install-nobase_goDATA +$(guile_install_go_files): install-nobase_modDATA + +EXTRA_DIST = $(SOURCES) $(NOCOMP_SOURCES) +GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat +SUFFIXES = .scm .go +.scm.go: + $(AM_V_GEN)$(top_builddir)/pre-inst-env $(GUILE_TOOLS) compile $(GUILE_WARNINGS) -o "$@" "$<" + +SOURCES = lmdb.scm \ + lmdb/internal.scm + +TESTS = + +TEST_EXTENSIONS = .scm +SCM_LOG_DRIVER = \ + $(top_builddir)/pre-inst-env \ + $(GUILE) --no-auto-compile -e main \ + $(top_srcdir)/build-aux/test-driver.scm + +# Tell 'build-aux/test-driver.scm' to display only source file names, +# not indivdual test names. +AM_SCM_LOG_DRIVER_FLAGS = --brief=yes + +AM_SCM_LOG_FLAGS = --no-auto-compile -L "$(top_srcdir)" + +AM_TESTS_ENVIRONMENT = abs_top_srcdir="$(abs_top_srcdir)" + +info_TEXINFOS = doc/lmdb.texi +dvi: # Don't build dvi docs + +EXTRA_DIST += README.org \ + README \ + HACKING \ + COPYING \ + guix.scm \ + .gitignore \ + hall.scm \ + build-aux/test-driver.scm \ + $(TESTS) + +ACLOCAL_AMFLAGS = -I m4 + +clean-go: + -$(RM) $(GOBJECTS) +.PHONY: clean-go + +CLEANFILES = \ + $(GOBJECTS) \ + $(TESTS:tests/%.scm=%.log) @@ -0,0 +1,14 @@ +-*- mode: org; coding: utf-8; -*- + +#+TITLE: guile-lmdb NEWS – history of user-visible changes +#+STARTUP: content hidestars + +Copyright © (2021) pukkamustard <pukkamustard@posteo.net> + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +Please send guile-lmdb bug reports to pukkamustard@posteo.net. + +* Publication at 0.1.0 diff --git a/build-aux/test-driver.scm b/build-aux/test-driver.scm new file mode 100644 index 0000000..a818968 --- /dev/null +++ b/build-aux/test-driver.scm @@ -0,0 +1,180 @@ + +;;;; test-driver.scm - Guile test driver for Automake testsuite harness + +(define script-version "2019-01-15.13") ;UTC + +;;; Copyright © 2015, 2016 Mathieu Lirzin <mthl@gnu.org> +;;; Copyright © 2019 Alex Sassmannshausen <alex@pompo.co> +;;; +;;; This program is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;;; Commentary: +;;; +;;; This script provides a Guile test driver using the SRFI-64 Scheme API for +;;; test suites. SRFI-64 is distributed with Guile since version 2.0.9. +;;; +;;; This script is a lightly modified version of the orignal written by +;;; Matthieu Lirzin. The changes make it suitable for use as part of the +;;; guile-hall infrastructure. +;;; +;;;; Code: + +(use-modules (ice-9 getopt-long) + (ice-9 pretty-print) + (srfi srfi-26) + (srfi srfi-64)) + +(define (show-help) + (display "Usage: + test-driver --test-name=NAME --log-file=PATH --trs-file=PATH + [--expect-failure={yes|no}] [--color-tests={yes|no}] + [--enable-hard-errors={yes|no}] [--brief={yes|no}}] [--] + TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] +The '--test-name', '--log-file' and '--trs-file' options are mandatory. +")) + +(define %options + '((test-name (value #t)) + (log-file (value #t)) + (trs-file (value #t)) + (color-tests (value #t)) + (expect-failure (value #t)) ;XXX: not implemented yet + (enable-hard-errors (value #t)) ;not implemented in SRFI-64 + (brief (value #t)) + (help (single-char #\h) (value #f)) + (version (single-char #\V) (value #f)))) + +(define (option->boolean options key) + "Return #t if the value associated with KEY in OPTIONS is 'yes'." + (and=> (option-ref options key #f) (cut string=? <> "yes"))) + +(define* (test-display field value #:optional (port (current-output-port)) + #:key pretty?) + "Display 'FIELD: VALUE\n' on PORT." + (if pretty? + (begin + (format port "~A:~%" field) + (pretty-print value port #:per-line-prefix "+ ")) + (format port "~A: ~S~%" field value))) + +(define* (result->string symbol #:key colorize?) + "Return SYMBOL as an upper case string. Use colors when COLORIZE is #t." + (let ((result (string-upcase (symbol->string symbol)))) + (if colorize? + (string-append (case symbol + ((pass) "[0;32m") ;green + ((xfail) "[1;32m") ;light green + ((skip) "[1;34m") ;blue + ((fail xpass) "[0;31m") ;red + ((error) "[0;35m")) ;magenta + result + "[m") ;no color + result))) + +(define* (test-runner-gnu test-name #:key color? brief? out-port trs-port) + "Return an custom SRFI-64 test runner. TEST-NAME is a string specifying the +file name of the current the test. COLOR? specifies whether to use colors, +and BRIEF?, well, you know. OUT-PORT and TRS-PORT must be output ports. The +current output port is supposed to be redirected to a '.log' file." + + (define (test-on-test-begin-gnu runner) + ;; Procedure called at the start of an individual test case, before the + ;; test expression (and expected value) are evaluated. + (let ((result (cute assq-ref (test-result-alist runner) <>))) + (format #t "test-name: ~A~%" (result 'test-name)) + (format #t "location: ~A~%" + (string-append (result 'source-file) ":" + (number->string (result 'source-line)))) + (test-display "source" (result 'source-form) #:pretty? #t))) + + (define (test-on-test-end-gnu runner) + ;; Procedure called at the end of an individual test case, when the result + ;; of the test is available. + (let* ((results (test-result-alist runner)) + (result? (cut assq <> results)) + (result (cut assq-ref results <>))) + (unless brief? + ;; Display the result of each test case on the console. + (format out-port "~A: ~A - ~A~%" + (result->string (test-result-kind runner) #:colorize? color?) + test-name (test-runner-test-name runner))) + (when (result? 'expected-value) + (test-display "expected-value" (result 'expected-value))) + (when (result? 'expected-error) + (test-display "expected-error" (result 'expected-error) #:pretty? #t)) + (when (result? 'actual-value) + (test-display "actual-value" (result 'actual-value))) + (when (result? 'actual-error) + (test-display "actual-error" (result 'actual-error) #:pretty? #t)) + (format #t "result: ~a~%" (result->string (result 'result-kind))) + (newline) + (format trs-port ":test-result: ~A ~A~%" + (result->string (test-result-kind runner)) + (test-runner-test-name runner)))) + + (define (test-on-group-end-gnu runner) + ;; Procedure called by a 'test-end', including at the end of a test-group. + (let ((fail (or (positive? (test-runner-fail-count runner)) + (positive? (test-runner-xpass-count runner)))) + (skip (or (positive? (test-runner-skip-count runner)) + (positive? (test-runner-xfail-count runner))))) + ;; XXX: The global results need some refinements for XPASS. + (format trs-port ":global-test-result: ~A~%" + (if fail "FAIL" (if skip "SKIP" "PASS"))) + (format trs-port ":recheck: ~A~%" + (if fail "yes" "no")) + (format trs-port ":copy-in-global-log: ~A~%" + (if (or fail skip) "yes" "no")) + (when brief? + ;; Display the global test group result on the console. + (format out-port "~A: ~A~%" + (result->string (if fail 'fail (if skip 'skip 'pass)) + #:colorize? color?) + test-name)) + #f)) + + (let ((runner (test-runner-null))) + (test-runner-on-test-begin! runner test-on-test-begin-gnu) + (test-runner-on-test-end! runner test-on-test-end-gnu) + (test-runner-on-group-end! runner test-on-group-end-gnu) + (test-runner-on-bad-end-name! runner test-on-bad-end-name-simple) + runner)) + +;;; +;;; Entry point. +;;; + +(define (main . args) + (let* ((opts (getopt-long (command-line) %options)) + (option (cut option-ref opts <> <>))) + (cond + ((option 'help #f) (show-help)) + ((option 'version #f) (format #t "test-driver.scm ~A" script-version)) + (else + (let ((log (open-file (option 'log-file "") "w0")) + (trs (open-file (option 'trs-file "") "wl")) + (out (duplicate-port (current-output-port) "wl"))) + (redirect-port log (current-output-port)) + (redirect-port log (current-warning-port)) + (redirect-port log (current-error-port)) + (test-with-runner + (test-runner-gnu (option 'test-name #f) + #:color? (option->boolean opts 'color-tests) + #:brief? (option->boolean opts 'brief) + #:out-port out #:trs-port trs) + (load-from-path (option 'test-name #f))) + (close-port log) + (close-port trs) + (close-port out)))) + (exit 0))) diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..75509f8 --- /dev/null +++ b/configure.ac @@ -0,0 +1,39 @@ + +dnl -*- Autoconf -*- + +AC_INIT(guile-lmdb, 0.1.0) +AC_SUBST(HVERSION, "\"0.1.0\"") +AC_SUBST(AUTHOR, "\"pukkamustard\"") +AC_SUBST(COPYRIGHT, "'(2021)") +AC_SUBST(LICENSE, gpl3+) +AC_CONFIG_SRCDIR(lmdb.scm) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE([1.12 gnu silent-rules subdir-objects color-tests parallel-tests -Woverride -Wno-portability]) +AM_SILENT_RULES([yes]) + +PKG_CHECK_MODULES([LIBLMDB], [liblmdb]) +PKG_CHECK_VAR([LIBLMDB_LIBDIR], [liblmdb], [libdir]) +AC_SUBST([LIBLMDB_LIBDIR]) + +AC_CONFIG_FILES([Makefile lmdb/internal.scm]) +AC_CONFIG_FILES([pre-inst-env], [chmod +x pre-inst-env]) + +dnl Search for 'guile' and 'guild'. This macro defines +dnl 'GUILE_EFFECTIVE_VERSION'. +GUILE_PKG([3.0 2.2 2.0]) +GUILE_PROGS +GUILE_SITE_DIR +if test "x$GUILD" = "x"; then + AC_MSG_ERROR(['guild' binary not found; please check your guile-2.x installation.]) +fi + +dnl Hall auto-generated guile-module dependencies + + +dnl Installation directories for .scm and .go files. +guilemoduledir="${datarootdir}/guile/site/$GUILE_EFFECTIVE_VERSION" +guileobjectdir="${libdir}/guile/$GUILE_EFFECTIVE_VERSION/site-ccache" +AC_SUBST([guilemoduledir]) +AC_SUBST([guileobjectdir]) + +AC_OUTPUT @@ -10,7 +10,8 @@ (license gpl3+) (dependencies `()) (files (libraries - ((scheme-file "lmdb") (directory "lmdb" ()))) + ((scheme-file "lmdb") + (directory "lmdb" ((scheme-file "internal"))))) (tests ((directory "tests" ()))) (programs ((directory "scripts" ()))) (documentation @@ -1,3 +1,7 @@ +; SPDX-FileCopyrightText: 2021 pukkamustard <pukkamustard@posteo.net> +; +; SPDX-License-Identifier: GPL-3.0-or-later + (define-module (lmdb) #:use-module (system foreign) @@ -6,50 +10,9 @@ #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) - #:use-module (rnrs bytevectors)) - -;; dynamic binding to liblmdb - -(define liblmdb (dynamic-link - "/gnu/store/4xi21x5i0vch4wmylg2vbzjl7rqija5f-lmdb-0.9.27/lib/liblmdb")) - - -;; error handling - -(define-condition-type &lmdb-error - &error - lmdb-error? - (function-name lmdb-error-function-name) - (code lmdb-error-code) - (description lmdb-error-description)) - -(define (mdb-strerror err) - "Return a string describing a given error code." - (let ((proc (pointer->procedure '* - (dynamic-func "mdb_strerror" liblmdb) - (list int)))) - (pointer->string (proc err)))) - -;; helper for calling lmdb functions that checks return value - -(define (liblmdb-func name arg-types) - (let ((proc (pointer->procedure int - (dynamic-func name liblmdb) - arg-types))) - (lambda* (#:rest args) - (let ((return-value (apply proc args))) - (unless (= 0 return-value) - (raise - (condition (&lmdb-error - (function-name name) - (code return-value) - (description (mdb-strerror return-value)))))) - return-value)))) - -(define (liblmdb-void-func name arg-types) - (pointer->procedure void - (dynamic-func name liblmdb) - arg-types)) + #:use-module (rnrs bytevectors) + + #:use-module (lmdb internal)) ;; MDB_env diff --git a/lmdb/internal.scm.in b/lmdb/internal.scm.in new file mode 100644 index 0000000..eb04656 --- /dev/null +++ b/lmdb/internal.scm.in @@ -0,0 +1,60 @@ +; SPDX-FileCopyrightText: 2021 pukkamustard <pukkamustard@posteo.net> +; +; SPDX-License-Identifier: GPL-3.0-or-later + +(define-module (lmdb internal) + #:use-module (system foreign) + + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) + + #:export (liblmdb + + lmdb-error? + lmdb-error-function-name + lmdb-error-code + lmdb-error-description + + liblmdb-func + liblmdb-void-func)) + +;; Internal helpers + +(define liblmdb (dynamic-link "@LIBLMDB_LIBDIR@/liblmdb")) + +;; Error handling + +(define-condition-type &lmdb-error + &error + lmdb-error? + (function-name lmdb-error-function-name) + (code lmdb-error-code) + (description lmdb-error-description)) + +(define (mdb-strerror err) + "Return a string describing a given error code." + (let ((proc (pointer->procedure '* + (dynamic-func "mdb_strerror" liblmdb) + (list int)))) + (pointer->string (proc err)))) + +;; Helper for calling lmdb functions + +(define (liblmdb-func name arg-types) + (let ((proc (pointer->procedure int + (dynamic-func name liblmdb) + arg-types))) + (lambda* (#:rest args) + (let ((return-value (apply proc args))) + (unless (= 0 return-value) + (raise + (condition (&lmdb-error + (function-name name) + (code return-value) + (description (mdb-strerror return-value)))))) + return-value)))) + +(define (liblmdb-void-func name arg-types) + (pointer->procedure void + (dynamic-func name liblmdb) + arg-types)) diff --git a/pre-inst-env.in b/pre-inst-env.in new file mode 100644 index 0000000..1556fcd --- /dev/null +++ b/pre-inst-env.in @@ -0,0 +1,14 @@ + +#!/bin/sh + +abs_top_srcdir="`cd "@abs_top_srcdir@" > /dev/null; pwd`" +abs_top_builddir="`cd "@abs_top_builddir@" > /dev/null; pwd`" + +GUILE_LOAD_COMPILED_PATH="$abs_top_builddir${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH" +GUILE_LOAD_PATH="$abs_top_builddir:$abs_top_srcdir${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH" +export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH + +PATH="$abs_top_builddir/scripts:$PATH" +export PATH + +exec "$@" |