#! /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 < ;;; ;;; 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 . (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_EV (effective-version)) (define CC (or (getenv "CC") "gcc")) (define CC32 (or (getenv "CC32") "i686-unknown-linux-gnu-gcc")) (define GUILE (or (getenv "guile") "guile")) (define SYSCONFDIR "$(PREFIX)/etc") ;;; Utility (define (gulp-pipe command) (let* ((port (open-pipe* OPEN_READ *shell* "-c" command)) (output (read-string port))) (close-port port) (string-trim-right output #\newline))) (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* ((->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* ((actual (gulp-pipe (format #f "~a ~a 2>&1" command version-option))) (actual (string->version actual)) (pass? (and actual (compare expected actual)))) (stderr "~a ~a\n" (if pass? (if (pair? actual) "" " yes") (if actual " no, found" "")) (version->string actual)) (if (not pass?) (set! required (cons (or deb command) required))) pass?)) (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? (system "guix --version &>/dev/null")) ;;; (define (parse-opts args) (let* ((option-spec '((build (value #t)) (help (single-char #\h)) (prefix (value #t)) (sysconfdir (value #t)) ;;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 --prefix=DIR install in PREFIX [~a] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] " PREFIX) (exit (or (and usage? 2) 0))) options))) (define BUILD_TRIPLET (gulp-pipe "gcc -dumpmachine 2>/dev/null")) (define (main args) (let* ((options (parse-opts args)) (build-triplet (option-ref options 'build BUILD_TRIPLET)) (prefix (option-ref options 'prefix PREFIX)) (sysconfdir (option-ref options 'sysconfdir SYSCONFDIR))) (check-version 'bash '(4 0)) (check-version 'gcc '(4 8)) (check-version 'i686-unknown-linux-gnu-gcc '(4 8)) (check-version 'guile '(2 0)) (check-version 'make '(4 0)) (check-version 'perl '(5)) (when (pair? required) (stderr "\nMissing dependencies, run\n\n") (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 "CC:=~a\n" CC) (stdout "CC32:=~a\n" CC32) (stdout "GUILE:=~a\n" GUILE) (stdout "GUILE_EV:=~a\n" GUILE_EV) (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")))