4 echo -n "checking for guile..."
5 GUILE=$(command -v ${GUILE-guile})
6 GUIX=$(command -v ${GUIX-guix})
8 if [ -x "$GUILE" ]; then
10 elif [ -x "$GUIX" ]; then
13 Missing dependencies, run
15 guix environment -l guix.scm
21 Missing dependencies, run
23 sudo apt-get install guile-2.2
27 exec ${GUILE-guile} -L . --no-auto-compile -e '(configure)' -s "$0" ${1+"$@"}
30 ;;; Mes --- Maxwell Equations of Software
31 ;;; Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
33 ;;; configure: This file is part of Mes.
35 ;;; Mes is free software; you can redistribute it and/or modify it
36 ;;; under the terms of the GNU General Public License as published by
37 ;;; the Free Software Foundation; either version 3 of the License, or (at
38 ;;; your option) any later version.
40 ;;; Mes is distributed in the hope that it will be useful, but
41 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
42 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 ;;; GNU General Public License for more details.
45 ;;; You should have received a copy of the GNU General Public License
46 ;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
48 (define-module (configure)
49 #:use-module (srfi srfi-26)
50 #:use-module (ice-9 and-let-star)
51 #:use-module (ice-9 curried-definitions)
52 #:use-module (ice-9 getopt-long)
53 #:use-module (ice-9 match)
54 #:use-module (ice-9 optargs)
55 #:use-module (ice-9 popen)
56 #:use-module (ice-9 rdelim)
60 (define PACKAGE "mes")
61 (define VERSION "0.16")
62 (define PREFIX "/usr/local")
63 (define GUILE_EFFECTIVE_VERSION (effective-version))
64 (define GUILE (or (getenv "guile") "guile"))
65 (define SYSCONFDIR "$(PREFIX)/etc")
68 (define (logf port string . rest)
69 (apply format (cons* port string rest))
73 (define (stderr string . rest)
74 (apply logf (cons* (current-error-port) string rest)))
76 (define (stdout string . rest)
77 (apply logf (cons* (current-output-port) string rest)))
79 (define *verbose?* #f)
81 (define (verbose string . rest)
82 (if *verbose?* (apply stderr (cons string rest))))
84 (define (gulp-pipe command)
85 (let* ((port (open-pipe* OPEN_READ *shell* "-c" command))
86 (output (read-string port))
87 (status (close-pipe port)))
88 (verbose "command[~a]: ~s => ~a\n" status command output)
89 (if (not (zero? status)) "" (string-trim-right output #\newline))))
91 (define* ((->string #:optional (infix "")) h . t)
92 (let ((o (if (pair? t) (cons h t) h)))
94 ((? char?) (make-string 1 o))
95 ((? number?) (number->string o))
97 ((? symbol?) (symbol->string o))
98 ((h ... t) (string-join (map (->string) o) ((->string) infix)))
103 ((and (null? a) (null? b)) #t)
104 ((null? a) (not (null? b)))
106 ((and (not (< (car a) (car b)))
107 (not (< (car b) (car a))))
108 (tuple< (cdr a) (cdr b)))
109 (else (< (car a) (car b)))))
111 (define (tuple<= a b)
112 (or (equal? a b) (tuple< a b)))
115 (define (version->string version)
116 ((->string '.) version))
118 (define (string->version string)
119 (and-let* ((version (string-tokenize string
120 (char-set-adjoin char-set:digit #\.)))
122 (version (sort version (lambda (a b) (> (string-length a) (string-length b)))))
123 (version (car version))
124 (version (string-tokenize version
125 (char-set-complement (char-set #\.)))))
126 (map string->number version)))
128 (define* (PATH-search-path name #:key (default name) warn?)
129 (or (search-path (string-split (getenv "PATH") #\:) name)
130 (and (and warn? (format (current-error-port) "warning: not found: ~a\n" name))
133 (define optional '())
134 (define required '())
135 (define* (check-version name expected
139 (version-option '--version)
142 (stderr "checking for ~a~a..." (basename name)
143 (if (null? expected) ""
144 (format #f " [~a]" (version->string expected))))
145 (let* ((output (gulp-pipe (format #f "~a ~a 2>&1" command version-option)))
146 (actual (string->version output))
147 (pass? (and actual (compare expected actual)))
148 ;(pass? (PATH-search-path command))
150 (stderr "~a ~a\n" (if pass? (if (pair? actual) "" " yes")
151 (if actual " no, found" "")) (version->string actual))
153 (if (not (pair? name)) (begin (if optional? (set! optional (cons (or deb name) optional))
154 (set! required (cons (or deb name) required)))
156 (check-version (cdr name) expected deb version-option compare)))))
158 (define* (check-pkg-config package expected #:optional (deb #f))
159 (check-version (format #f "pkg-config --modversion ~a" package) expected deb))
161 (define (check-compile-header-c header)
162 (and (= 0 (system (format #f "echo '#include ~s' | gcc -E - > /dev/null 2>&1" header)))
165 (define (check-compile-header-c++ header)
166 (and (= 0 (system (format #f "echo '#include ~s' | gcc --language=c++ --std=c++11 -E - > /dev/null 2>&1" header)))
169 (define* (check-header-c header deb #:optional (check check-compile-header-c))
170 (stderr "checking for ~a..." header)
171 (let ((result (check header)))
172 (stderr " ~a\n" (if result result "no"))
174 (set! required (cons deb required)))))
176 (define* (check-header-c++ header deb #:optional (check check-compile-header-c++))
177 (check-header-c header deb check))
180 (and (zero? (system "guix --version 1>/dev/null 2>/dev/null")) 1))
183 (define (parse-opts args)
187 (help (single-char #\h))
189 (sysconfdir (value #t))
190 (verbose (single-char #\v))
193 (enable-fast-install))))
194 (getopt-long args option-spec)))
196 (define* (print-help #:optional (port (current-output-port)))
198 `configure' configures ~a ~a to adapt to many kinds of systems.
200 Usage: ./configure [OPTION]... [VAR=VALUE]
202 To assign environment variables (e.g., CC, CFLAGS...), specify them as
203 VAR=VALUE. See below for descriptions of some of the useful variables.
205 Defaults for the options are specified in brackets.
208 -h, --help display this help
209 --build=BUILD configure for building on BUILD [guessed]
210 --host=HOST cross-compile to build programs to run on HOST [BUILD]
211 -v, --verbose be verbose
212 --with-courage assert being courageous to configure for unsupported platform
214 Installation directories:
215 --prefix=DIR install in PREFIX [~a]
216 --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
218 Some influential environment variables:
219 CC C compiler command
220 CFLAGS C compiler flags
221 CC32 x86 C compiler command
222 C32FLAGS x86 C compiler flags
224 GUILE_TOOLS guile-tools command
225 MES_SEED location of mes-seed
226 MESCC_TOOLS_SEED location of mescc-tools-seed
227 TCC tcc C compiler command
228 TINYCC_SEED location of tinycc-seed
229 " PACKAGE VERSION (getenv "PREFIX")))
232 (let* ((CC (or (getenv "CC") "gcc"))
233 (BUILD_TRIPLET %host-type)
234 (ARCH (car (string-split BUILD_TRIPLET #\-)))
235 (options (parse-opts args))
236 (build-triplet (option-ref options 'build BUILD_TRIPLET))
237 (host-triplet (option-ref options 'host BUILD_TRIPLET))
238 (prefix (option-ref options 'prefix PREFIX))
239 (sysconfdir (option-ref options 'sysconfdir SYSCONFDIR))
240 (verbose? (option-ref options 'verbose #f))
241 (with-courage? (option-ref options 'with-courage #f))
243 (vars (filter (cut string-index <> #\=) (option-ref options '() '())))
244 (help? (option-ref options 'help #f)))
245 (for-each (lambda (v) (apply setenv (string-split v #\=))) vars)
246 (let ((CC32 (or (getenv "CC32")
247 (if (member ARCH '("i686" "arm")) (string-append BUILD_TRIPLET "-" CC)
248 "i686-unknown-linux-gnu-gcc")))
249 (TCC (or (getenv "TCC") "tcc"))
250 (MAKEINFO (or (getenv "MAKEINFO") "makeinfo"))
251 (GUILE_TOOLS (or (getenv "GUILE_TOOLS") "guile-tools"))
252 (BLOOD_ELF (or (getenv "BLOOD_ELF") "blood-elf"))
253 (HEX2 (or (getenv "HEX2") "hex2"))
254 (M1 (or (getenv "M1") "M1"))
255 (CFLAGS (getenv "CFLAGS"))
256 (C32FLAGS (getenv "C32FLAGS"))
257 (HEX2FLAGS (getenv "HEX2FLAGS"))
258 (M1FLAGS (getenv "M1FLAGS"))
259 (MESCCFLAGS (getenv "MESCCFLAGS"))
260 (MES_SEED (or (getenv "MES_SEED") "../mes-seed"))
261 (MESCC_TOOLS_SEED (or (getenv "MESCC_TOOLS_SEED") "../mescc-tools-seed"))
262 (TINYCC_SEED (or (getenv "TINYCC_SEED") "../tinycc-seed")))
266 (set! *verbose?* verbose?)
267 (check-version "guile" '(2 0))
268 (check-version "guile-tools" '(2 0))
269 (check-version "mes-seed" '(0 16) #:optional? #t #:command (string-append MES_SEED "/refresh.sh"))
270 (check-version "tinycc-seed" '(0 16) #:optional? #t #:command (string-append TINYCC_SEED "/refresh.sh"))
271 (check-version BLOOD_ELF '(0 1))
272 (check-version HEX2 '(0 3))
273 (check-version M1 '(0 3))
274 (check-version "nyacc" '(0 80 41) #:command (string-append GUILE " -c '(use-modules (nyacc lalr)) (display *nyacc-version*)'"))
276 (check-version "bash" '(4 0))
277 (when (and (not (member ARCH '("i686" "x86_64"))) (not with-courage?))
278 (stderr "platform not supported: ~a, try --with-courage\n" ARCH)
280 (if (not (check-version CC '(4 8) #:optional? #t))
283 (check-header-c "stdio.h" "libc-dev")
284 (check-header-c "limits.h" "linux-headers"))
285 (if (not (check-version CC32 '(4 8) #:optional? #t))
287 (if (not (check-version TCC '(0 9 26) #:optional? #t #:version-option "-v"))
289 (set! make? (check-version "make" '(4 0) #:optional? #t))
290 (check-version "perl" '(5))
291 (if (not (check-version "makeinfo" '(6) #:optional? #t))
294 (when (pair? required)
295 (stderr "\nMissing dependencies [~a], run\n\n" ((->string ", ") required))
297 (stderr " guix environment -l guix.scm\n")
298 (stderr " sudo apt-get install ~a\n" ((->string " ") required)))
300 (with-output-to-file ".config.make"
302 (stdout "build:=~a\n" build-triplet)
303 (stdout "host:=~a\n" host-triplet)
304 (stdout "srcdir:=.\n")
305 (stdout "ARCH:=~a\n" ARCH)
306 (stdout "CC:=~a\n" (or CC ""))
307 (stdout "CC32:=~a\n" (or CC32 ""))
308 (stdout "TCC:=~a\n" (or TCC ""))
309 (stdout "BLOOD_ELF:=~a\n" (or BLOOD_ELF ""))
310 (stdout "MES_SEED:=~a\n" (or MES_SEED ""))
311 (stdout "MESCC_TOOLS_SEED:=~a\n" (or MESCC_TOOLS_SEED ""))
312 (stdout "TINYCC_SEED:=~a\n" (or TINYCC_SEED ""))
313 (stdout "HEX2:=~a\n" (or HEX2 ""))
314 (stdout "M1:=~a\n" (or M1 ""))
315 (stdout "GUILE:=~a\n" GUILE)
316 (stdout "GUILE_TOOLS:=~a\n" GUILE_TOOLS)
317 (stdout "GUILE_FOR_BUILD:=~a\n" GUILE)
318 (stdout "GUILE_EFFECTIVE_VERSION:=~a\n" GUILE_EFFECTIVE_VERSION)
319 (stdout "GUIX_P:=~a\n" (if guix? guix? ""))
320 (stdout "HEX2:=~a\n" (or HEX2 ""))
321 (stdout "PACKAGE:=~a\n" PACKAGE)
322 (stdout "VERSION:=~a\n" VERSION)
323 (stdout "PREFIX:=~a\n" (gulp-pipe (string-append "echo " prefix)))
324 (stdout "SYSCONFDIR:=~a\n" sysconfdir)
325 (when CFLAGS (stdout "CFLAGS:=~a\n" CFLAGS))
326 (when C32FLAGS (stdout "C32FLAGS:=~a\n" C32FLAGS))
327 (when HEX2FLAGS (stdout "HEX2FLAGS:=~a\n" HEX2FLAGS))
328 (when M1FLAGS (stdout "M1FLAGS:=~a\n" M1FLAGS))
329 (when MESCCFLAGS (stdout "MESCCFLAGS:=~a\n" MESCCFLAGS))))
330 (format (current-output-port)
333 ~a help for help on other targets\n"
334 (if make? "make" "./build.sh")
335 (if make? "make" "./build.sh")))))