mes/configure
Jan Nieuwenhuizen 38d30a3e42 build: Refactor.
* GNUmakefile (OUT,QUIET,SUBDIRS): New variables.
  include make/common.make
* .gitignore: Remove toplevel targets.
* build-aux/compile-all.scm: Import from GNU Guix.
* configure (gulp-pipe): Check exit status.  Actually test for CC,
  CC32.
* make/bin.make: New file.
* make/check.make: New file.
* make/clean.make: New file.
* make/common.make: New file.
* make/compile.make: New file.
* make/guile.make: New file.
* make/mescc-guile.make: New file.
* make/mescc-mes.make: New file.
* make/reset.make: New file.
* lib/mlibc.c: Rename from top.
* lib/start.c: Rename from top.
* module/module.make: New file.
* scaffold/scaffold.make: New file.
* scripts/scripts.make: New file.
* src/mes.c: Rename from top.
* src/src.make: New file.
* src/mes.c: Rename from top.
* src/gc..c: Rename from top.
* src/lib.c: Rename from top.
* src/posix.c: Rename from top.
* src/reader.c: Rename from top.
* src/vector.c: Rename from top.
* tests/tests.make: New file.
2017-04-12 21:27:59 +02:00

233 lines
8.2 KiB
Scheme
Executable file

#! /bin/sh
# -*- scheme -*-
unset LANG LC_ALL
echo -n "checking for guile..."
GUILE=$(type -p ${GUILE-guile} 2>/dev/null|tail -n 1|sed 's,^.* ,,')
export GUILE
if [ -x "$GUILE" ]; then
echo " $GUILE"
else
pm=$({ guix --help || dpkg --help; }|head -n 1|sed 's,.*Usage: \([^ ]*\).*,\1,g')
#-paredit:'})(
case "$pm" in dpkg) message="sudo apt-get install guile-2.0";; *) message="guix package -i guile";; esac
cat <<EOF
Missing dependencies, run
$pm
EOF
exit 1
fi
unset GUILE_AUTO_COMPILE GUILE_LOAD_COMPILED_PATH
exec ${GUILE} --no-auto-compile -L $(pwd) -e '(@@ (configure) main)' -s "$0" ${1+"$@"}
!#
;;; Mes --- Maxwell Equations of Software
;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
;;;
;;; configure: This file is part of Mes.
;;;
;;; Mes 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.
;;;
;;; Mes 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 Mes. If not, see <http://www.gnu.org/licenses/>.
(define-module (configure)
#:use-module (ice-9 and-let-star)
#:use-module (ice-9 curried-definitions)
#:use-module (ice-9 getopt-long)
#:use-module (ice-9 match)
#:use-module (ice-9 optargs)
#:use-module (ice-9 popen)
#:use-module (ice-9 rdelim))
(define *shell* "sh")
(define PACKAGE "mes")
(define VERSION "0.4")
(define PREFIX "/usr/local")
(define GUILE_EFFECTIVE_VERSION (effective-version))
(define GUILE (or (getenv "guile") "guile"))
(define SYSCONFDIR "$(PREFIX)/etc")
;;; Utility
(define (logf port string . rest)
(apply format (cons* port string rest))
(force-output port)
#t)
(define (stderr string . rest)
(apply logf (cons* (current-error-port) string rest)))
(define (stdout string . rest)
(apply logf (cons* (current-output-port) string rest)))
(define *verbose?* #f)
(define (verbose string . rest)
(if *verbose?* (apply stderr (cons string rest))))
(define (gulp-pipe command)
(let* ((port (open-pipe* OPEN_READ *shell* "-c" command))
(output (read-string port))
(status (close-pipe port)))
(verbose "command[~a]: ~s => ~a\n" status command output)
(if (not (zero? status)) "" (string-trim-right output #\newline))))
(define* ((->string #:optional (infix "")) h . t)
(let ((o (if (pair? t) (cons h t) h)))
(match o
((? char?) (make-string 1 o))
((? number?) (number->string o))
((? string?) o)
((? symbol?) (symbol->string o))
((h ... t) (string-join (map (->string) o) ((->string) infix)))
(_ ""))))
(define (tuple< a b)
(cond
((and (null? a) (null? b)) #t)
((null? a) (not (null? b)))
((null? b) #f)
((and (not (< (car a) (car b)))
(not (< (car b) (car a))))
(tuple< (cdr a) (cdr b)))
(else (< (car a) (car b)))))
(define (tuple<= a b)
(or (equal? a b) (tuple< a b)))
;;; Configure
(define (version->string version)
((->string '.) version))
(define (string->version string)
(and-let* ((version (string-tokenize string
(char-set-adjoin char-set:digit #\.)))
((pair? version))
(version (sort version (lambda (a b) (> (string-length a) (string-length b)))))
(version (car version))
(version (string-tokenize version
(char-set-complement (char-set #\.)))))
(map string->number version)))
(define required '())
(define* (check-version command expected
#:optional
(deb #f)
(version-option '--version)
(compare tuple<=))
(stderr "checking for ~a~a..." command
(if (null? expected) ""
(format #f " [~a]" (version->string expected))))
(let* ((output (gulp-pipe (format #f "~a ~a 2>&1" command version-option)))
(actual (string->version output))
(pass? (and actual (compare expected actual))))
(stderr "~a ~a\n" (if pass? (if (pair? actual) "" " yes")
(if actual " no, found" "")) (version->string actual))
(or pass?
(if (not (pair? command)) (begin (set! required (cons (or deb command) required)) pass?)
(check-version (cdr command) expected deb version-option compare)))))
(define* (check-pkg-config package expected #:optional (deb #f))
(check-version (format #f "pkg-config --modversion ~a" package) expected deb))
(define (check-compile-header-c++ header)
(and (= 0 (system (format #f "echo '#include \"~a\"' | gcc --language=c++ --std=c++11 -E - > /dev/null 2>&1" header)))
'yes))
(define* (check-header-c++ header deb #:optional (check check-compile-header-c++))
(stderr "checking for ~a..." header)
(let ((result (check header)))
(stderr " ~a\n" (if result result "no"))
(if (not result)
(set! required (cons deb required)))))
(define guix?
(and (zero? (system "guix --version &>/dev/null")) 1))
;;;
(define CC (or (getenv "CC") "gcc"))
(define BUILD_TRIPLET (gulp-pipe (string-append CC " -dumpmachine 2>/dev/null")))
(define ARCH (car (string-split BUILD_TRIPLET #\-)))
(define CC32 (or (getenv "CC32")
(if (equal? ARCH "i686") CC
"i686-unknown-linux-gnu-gcc")))
(define (parse-opts args)
(let* ((option-spec
'((build (value #t))
(host (value #t))
(help (single-char #\h))
(prefix (value #t))
(sysconfdir (value #t))
(verbose (single-char #\v))
;;ignore
(enable-fast-install)))
(options (getopt-long args option-spec))
(help? (option-ref options 'help #f))
(files (option-ref options '() '()))
(prefix (option-ref options '() PREFIX))
(usage? (and (not help?) #f)))
(if (pair? files)
(stderr "ignoring files: ~a\n" files))
(or (and (or help? usage?)
((or (and usage? stderr) stdout) "\
Usage: ./configure [OPTION]...
-h, --help display this help
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
--prefix=DIR install in PREFIX [~a]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
-v, --verbose be verbose
" PREFIX)
(exit (or (and usage? 2) 0)))
options)))
(define (main args)
(let* ((options (parse-opts args))
(build-triplet (option-ref options 'build BUILD_TRIPLET))
(host-triplet (option-ref options 'host BUILD_TRIPLET))
(prefix (option-ref options 'prefix PREFIX))
(sysconfdir (option-ref options 'sysconfdir SYSCONFDIR))
(verbose? (option-ref options 'verbose #f)))
(set! *verbose?* verbose?)
(check-version 'bash '(4 0))
(check-version CC '(4 8))
(check-version CC32 '(4 8))
(check-version 'guile '(2 0))
(check-version 'make '(4 0))
(check-version 'perl '(5))
(when (pair? required)
(stderr "\nMissing dependencies [~a], run\n\n" ((->string ", ") required))
(if guix?
(stderr " guix environment -l guix.scm\n")
(stderr " sudo apt-get install ~a\n" ((->string " ") required)))
(exit 1))
(with-output-to-file ".config.make"
(lambda ()
(stdout "build:=~a\n" build-triplet)
(stdout "host:=~a\n" host-triplet)
(stdout "srcdir:=.\n")
(stdout "ARCH:=~a\n" ARCH)
(stdout "CC:=~a\n" CC)
(stdout "CC32:=~a\n" CC32)
(stdout "GUILE:=~a\n" GUILE)
(stdout "GUILE_EFFECTIVE_VERSION:=~a\n" GUILE_EFFECTIVE_VERSION)
(stdout "GUIX_P:=~a\n" (if guix? guix? ""))
(stdout "PACKAGE:=~a\n" PACKAGE)
(stdout "VERSION:=~a\n" VERSION)
(stdout "PREFIX:=~a\n" (gulp-pipe (string-append "echo " prefix)))
(stdout "SYSCONFDIR:=~a\n" sysconfdir)))
(stdout "\nRun:
make to build mes
make help for help on other targets\n")))