4 echo -n "checking for guile..."
5 GUILE=$(type -p ${GUILE-guile} 2>/dev/null|tail -n 1|sed 's,^.* ,,')
7 if [ -x "$GUILE" ]; then
10 pm=$({ guix --help || dpkg --help; }|head -n 1|sed 's,.*Usage: \([^ ]*\).*,\1,g')
12 case "$pm" in dpkg) message="sudo apt-get install guile-2.0";; *) message="guix environment guix.scm";; esac
14 Missing dependencies, run
20 exec ${GUILE} --no-auto-compile -L $(pwd) -C $(pwd) -e 'main' -s "$0" ${1+"$@"}
23 ;;; Mes --- Maxwell Equations of Software
24 ;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
26 ;;; configure: This file is part of Mes.
28 ;;; Mes is free software; you can redistribute it and/or modify it
29 ;;; under the terms of the GNU General Public License as published by
30 ;;; the Free Software Foundation; either version 3 of the License, or (at
31 ;;; your option) any later version.
33 ;;; Mes is distributed in the hope that it will be useful, but
34 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
35 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 ;;; GNU General Public License for more details.
38 ;;; You should have received a copy of the GNU General Public License
39 ;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
42 ((@@ (configure) main) args))
44 (define-module (configure)
45 #:use-module (ice-9 and-let-star)
46 #:use-module (ice-9 curried-definitions)
47 #:use-module (ice-9 getopt-long)
48 #:use-module (ice-9 match)
49 #:use-module (ice-9 optargs)
50 #:use-module (ice-9 popen)
51 #:use-module (ice-9 rdelim))
54 (define PACKAGE "mes")
55 (define VERSION "0.11")
56 (define PREFIX "/usr/local")
57 (define GUILE_EFFECTIVE_VERSION (effective-version))
58 (define GUILE (or (getenv "guile") "guile"))
59 (define SYSCONFDIR "$(PREFIX)/etc")
62 (define (logf port string . rest)
63 (apply format (cons* port string rest))
67 (define (stderr string . rest)
68 (apply logf (cons* (current-error-port) string rest)))
70 (define (stdout string . rest)
71 (apply logf (cons* (current-output-port) string rest)))
73 (define *verbose?* #f)
75 (define (verbose string . rest)
76 (if *verbose?* (apply stderr (cons string rest))))
78 (define (gulp-pipe command)
79 (let* ((port (open-pipe* OPEN_READ *shell* "-c" command))
80 (output (read-string port))
81 (status (close-pipe port)))
82 (verbose "command[~a]: ~s => ~a\n" status command output)
83 (if (not (zero? status)) "" (string-trim-right output #\newline))))
85 (define* ((->string #:optional (infix "")) h . t)
86 (let ((o (if (pair? t) (cons h t) h)))
88 ((? char?) (make-string 1 o))
89 ((? number?) (number->string o))
91 ((? symbol?) (symbol->string o))
92 ((h ... t) (string-join (map (->string) o) ((->string) infix)))
97 ((and (null? a) (null? b)) #t)
98 ((null? a) (not (null? b)))
100 ((and (not (< (car a) (car b)))
101 (not (< (car b) (car a))))
102 (tuple< (cdr a) (cdr b)))
103 (else (< (car a) (car b)))))
105 (define (tuple<= a b)
106 (or (equal? a b) (tuple< a b)))
109 (define (version->string version)
110 ((->string '.) version))
112 (define (string->version string)
113 (and-let* ((version (string-tokenize string
114 (char-set-adjoin char-set:digit #\.)))
116 (version (sort version (lambda (a b) (> (string-length a) (string-length b)))))
117 (version (car version))
118 (version (string-tokenize version
119 (char-set-complement (char-set #\.)))))
120 (map string->number version)))
122 (define optional '())
123 (define required '())
124 (define* (check-version name expected
128 (version-option '--version)
131 (stderr "checking for ~a~a..." name
132 (if (null? expected) ""
133 (format #f " [~a]" (version->string expected))))
134 (let* ((output (gulp-pipe (format #f "~a ~a 2>&1" command version-option)))
135 (actual (string->version output))
136 (pass? (and actual (compare expected actual))))
137 (stderr "~a ~a\n" (if pass? (if (pair? actual) "" " yes")
138 (if actual " no, found" "")) (version->string actual))
140 (if (not (pair? name)) (begin (if optional? (set! optional (cons (or deb name) optional))
141 (set! required (cons (or deb name) required)))
143 (check-version (cdr name) expected deb version-option compare)))))
145 (define* (check-pkg-config package expected #:optional (deb #f))
146 (check-version (format #f "pkg-config --modversion ~a" package) expected deb))
148 (define (check-compile-header-c header)
149 (and (= 0 (system (format #f "echo '#include ~s' | gcc -E - > /dev/null 2>&1" header)))
152 (define (check-compile-header-c++ header)
153 (and (= 0 (system (format #f "echo '#include ~s' | gcc --language=c++ --std=c++11 -E - > /dev/null 2>&1" header)))
156 (define* (check-header-c header deb #:optional (check check-compile-header-c))
157 (stderr "checking for ~a..." header)
158 (let ((result (check header)))
159 (stderr " ~a\n" (if result result "no"))
161 (set! required (cons deb required)))))
163 (define* (check-header-c++ header deb #:optional (check check-compile-header-c++))
164 (check-header-c header deb check))
167 (and (zero? (system "guix --version 1>/dev/null 2>/dev/null")) 1))
170 (define CC (or (getenv "CC") "gcc"))
171 (define BUILD_TRIPLET %host-type)
172 (define ARCH (car (string-split BUILD_TRIPLET #\-)))
173 (define CC32 (or (getenv "CC32")
174 (if (member ARCH '("i686" "arm")) (string-append BUILD_TRIPLET "-" CC)
175 "i686-unknown-linux-gnu-gcc")))
176 (define HEX2 (or (getenv "HEX2") "hex2"))
177 (define M1 (or (getenv "M1") "M1"))
179 (define (parse-opts args)
183 (help (single-char #\h))
185 (sysconfdir (value #t))
186 (verbose (single-char #\v))
189 (enable-fast-install)))
190 (options (getopt-long args option-spec))
191 (help? (option-ref options 'help #f))
192 (files (option-ref options '() '()))
193 (prefix (option-ref options '() PREFIX))
194 (usage? (and (not help?) #f)))
196 (stderr "ignoring files: ~a\n" files))
197 (or (and (or help? usage?)
198 ((or (and usage? stderr) stdout) "\
199 Usage: ./configure [OPTION]...
200 -h, --help display this help
201 --build=BUILD configure for building on BUILD [guessed]
202 --host=HOST cross-compile to build programs to run on HOST [BUILD]
203 --prefix=DIR install in PREFIX [~a]
204 --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
205 -v, --verbose be verbose
206 --with-courage assert being courageous to configure for unsupported platform
208 (exit (or (and usage? 2) 0)))
212 (let* ((options (parse-opts args))
213 (build-triplet (option-ref options 'build BUILD_TRIPLET))
214 (host-triplet (option-ref options 'host BUILD_TRIPLET))
215 (prefix (option-ref options 'prefix PREFIX))
216 (sysconfdir (option-ref options 'sysconfdir SYSCONFDIR))
217 (verbose? (option-ref options 'verbose #f))
218 (with-courage? (option-ref options 'with-courage #f))
220 (set! *verbose?* verbose?)
221 (check-version 'guile '(2 0))
222 (check-version HEX2 '(0 1))
223 (check-version M1 '(0 2))
224 (check-version 'nyacc '(0 80 3) #:command (string-append GUILE " -c '(use-modules (nyacc lalr)) (display *nyacc-version*)'"))
226 (check-version 'bash '(4 0))
227 (when (and (not (member ARCH '("i686" "x86_64"))) (not with-courage?))
228 (stderr "platform not supported: ~a, try --with-courage\n" ARCH)
230 (if (not (check-version CC '(4 8) #:optional? #t))
233 (check-header-c "stdio.h" "libc-dev")
234 (check-header-c "limits.h" "linux-headers"))
235 (if (not (check-version CC32 '(4 8) #:optional? #t))
237 (set! make? (check-version 'make '(4 0) #:optional? #t))
238 (check-version 'perl '(5))
240 (when (pair? required)
241 (stderr "\nMissing dependencies [~a], run\n\n" ((->string ", ") required))
243 (stderr " guix environment -l guix.scm\n")
244 (stderr " sudo apt-get install ~a\n" ((->string " ") required)))
246 (with-output-to-file ".config.make"
248 (stdout "build:=~a\n" build-triplet)
249 (stdout "host:=~a\n" host-triplet)
250 (stdout "srcdir:=.\n")
251 (stdout "ARCH:=~a\n" ARCH)
252 (stdout "CC:=~a\n" (or CC ""))
253 (stdout "CC32:=~a\n" (or CC32 ""))
254 (stdout "HEX2:=~a\n" (or HEX2 ""))
255 (stdout "M1:=~a\n" (or M1 ""))
256 (stdout "GUILE:=~a\n" GUILE)
257 (stdout "GUILE_FOR_BUILD:=~a\n" GUILE)
258 (stdout "GUILE_EFFECTIVE_VERSION:=~a\n" GUILE_EFFECTIVE_VERSION)
259 (stdout "GUIX_P:=~a\n" (if guix? guix? ""))
260 (stdout "HEX2:=~a\n" (or HEX2 ""))
261 (stdout "PACKAGE:=~a\n" PACKAGE)
262 (stdout "VERSION:=~a\n" VERSION)
263 (stdout "PREFIX:=~a\n" (gulp-pipe (string-append "echo " prefix)))
264 (stdout "SYSCONFDIR:=~a\n" sysconfdir)))
265 (format (current-output-port)
268 ~a help for help on other targets\n"
269 (if make? "make" "./make.scm")
270 (if make? "make" "./make.scm"))))