mescc: Run without shell.
[mes.git] / configure
1 #! /bin/sh
2 # -*-scheme-*-
3 MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)' -s "$0" ${1+"$@"}
4 !#
5
6 ;;; GNU Mes --- Maxwell Equations of Software
7 ;;; Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
8 ;;;
9 ;;; configure: This file is part of GNU Mes.
10 ;;;
11 ;;; GNU Mes is free software; you can redistribute it and/or modify it
12 ;;; under the terms of the GNU General Public License as published by
13 ;;; the Free Software Foundation; either version 3 of the License, or (at
14 ;;; your option) any later version.
15 ;;;
16 ;;; GNU Mes is distributed in the hope that it will be useful, but
17 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;;; GNU General Public License for more details.
20 ;;;
21 ;;; You should have received a copy of the GNU General Public License
22 ;;; along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
23
24 (define-module (configure)
25   #:use-module (srfi srfi-1)
26   #:use-module (srfi srfi-9)
27   #:use-module (srfi srfi-9 gnu)
28   #:use-module (srfi srfi-26)
29   #:use-module (ice-9 getopt-long)
30   #:use-module (ice-9 optargs)
31   #:use-module (ice-9 popen)
32   #:use-module (ice-9 rdelim)
33   #:export (main))
34
35 (cond-expand
36  (guile)
37  (mes (mes-use-module (srfi srfi-1))
38       (mes-use-module (srfi srfi-9))
39       (mes-use-module (srfi srfi-9 gnu))
40       (mes-use-module (srfi srfi-26))
41       (mes-use-module (mes getopt-long))
42       (mes-use-module (mes guile))
43       (mes-use-module (mes misc))
44       (mes-use-module (mes optargs))
45       (define %host-type "x86_64-unknown-linux-gnu")
46       (define OPEN_READ "r")
47       (define (canonicalize-path o)
48         (if (string-prefix? "/" o) o
49             (string-append (getcwd) "/" o)))
50       (define (sort lst less)
51         lst)
52       (define (close-pipe o) 0)
53       (define (open-pipe* OPEN_READ . commands)
54         (let ((fake-pipe ".pipe"))
55           (with-output-to-file fake-pipe
56             (lambda _
57               (let ((status (apply system* (append commands))))
58                 (set! close-pipe (lambda _ status)))))
59           (open-input-file fake-pipe)))))
60
61 (define* (PATH-search-path name #:key (default name) warn?)
62   (or (search-path (string-split (getenv "PATH") #\:) name)
63       (and (and warn? (format (current-error-port) "warning: not found: ~a\n" name))
64            default)))
65
66 (define *shell* "sh")
67 (define PACKAGE "mes")
68 (define VERSION "0.18")
69
70 ;;; Utility
71 (define (logf port string . rest)
72   (apply format (cons* port string rest))
73   (force-output port)
74   #t)
75
76 (define (stderr string . rest)
77   (apply logf (cons* (current-error-port) string rest)))
78
79 (define (stdout string . rest)
80   (apply logf (cons* (current-output-port) string rest)))
81
82 (define %verbose? #f)
83
84 (define (verbose string . rest)
85   (if %verbose? (apply stderr (cons string rest))))
86
87 (define (gulp-pipe* . command)
88   (let* ((err (current-error-port))
89          (foo (set-current-error-port (open-output-file ".error")))
90          (port (apply open-pipe* OPEN_READ command))
91          (output (read-string port))
92          (status (close-pipe port))
93          (error (with-input-from-file ".error" read-string)))
94     (set-current-error-port err)
95     (verbose "command[~a]: ~s => ~a [~a]\n" status command output error)
96     (if (not (zero? status)) ""
97         (string-trim-right (string-append output error)))))
98
99 (define (tuple< a b)
100   (cond
101    ((and (null? a) (null? b)) #t)
102    ((null? a) (not (null? b)))
103    ((null? b) #f)
104    ((and (not (< (car a) (car b)))
105          (not (< (car b) (car a))))
106     (tuple< (cdr a) (cdr b)))
107    (else (< (car a) (car b)))))
108
109 (define (tuple<= a b)
110   (or (equal? a b) (tuple< a b)))
111
112 (define (conjoin . predicates)
113   (lambda (. arguments)
114     (every (cut apply <> arguments) predicates)))
115
116 (define (char->char from to char)
117   (if (eq? char from) to char))
118
119 (define (string-replace-char string from to)
120   (string-map (cut char->char from to <>) string))
121
122 (define (string-replace-string string from to)
123   (cond ((string-contains string from)
124          => (lambda (i) (string-replace string to i (+ i (string-length from)))))
125         (else string)))
126
127 (define (string-replace-string/all string from to)
128   (or (and=> (string-contains string from)
129              (lambda (i)
130                (string-append
131                 (substring string 0 i)
132                 to
133                 (string-replace-string/all
134                  (substring string (+ i (string-length from))) from to))))
135       string))
136
137 ;;; Configure
138
139 (define-immutable-record-type <dependency>
140   (make-dependency name version-expected optional? version-option commands file-name data version-found)
141   dependency?
142   (name dependency-name)
143   (version-expected dependency-version-expected)
144   (optional? dependency-optional?)
145   (version-option dependency-version-option)
146   (commands dependency-commands)
147   (file-name dependency-file-name)
148   (data dependency-data)
149   (version-found dependency-version-found))
150
151 (define* (make-dep name #:key (version '(0)) optional? (version-option "--version") (commands (list name)) file-name data)
152   (let* ((env-var (getenv (name->shell-name name)))
153          (commands (if env-var (cons env-var commands) commands)))
154     (make-dependency name version optional? version-option commands file-name data #f)))
155
156 (define (find-dep name deps)
157   (find (compose (cut equal? <> name) dependency-name) deps))
158
159 (define (file-name name deps)
160   (and=> (find-dep name deps) dependency-file-name))
161
162 (define (variable-name dependency)
163   (and=>
164    (dependency-name dependency)
165    name->shell-name))
166
167 (define (name->shell-name name)
168   (string-upcase (string-replace-char name #\- #\_)))
169
170 (define (->string o)
171   (cond ((number? o) (number->string o))
172         ((string? o) o)
173         (else (format #f "~a" o))))
174
175 (define (version->string version)
176   (and version (string-join (map ->string version) ".")))
177
178 (define (string->version string)
179   (let ((split (string-tokenize string
180                                 (char-set-adjoin char-set:digit #\.))))
181     (and (pair? split)
182          (let* ((version (sort split (lambda (a b) (> (string-length a) (string-length b)))))
183                 (version (car version))
184                 (version (string-tokenize version
185                                           (char-set-complement (char-set #\.)))))
186            (map string->number version)))))
187
188 (define (check-program-version dependency)
189   (let ((name (dependency-name dependency))
190         (expected (dependency-version-expected dependency))
191         (version-option (dependency-version-option dependency))
192         (commands (dependency-commands dependency)))
193     (let loop ((commands commands))
194       (if (null? commands) dependency
195           (let ((command (car commands)))
196             (stdout "checking for ~a~a... " name
197                     (if (null? expected) ""
198                         (format #f " [~a]" (version->string expected))))
199             (let* ((output (gulp-pipe* command version-option))
200                    ;;(foo (stderr "output=~s\n" output))
201                    (actual (string->version output))
202                    ;;(foo (stderr "actual=~s\n" actual))
203                    ;;(foo (stderr "expected=~s\n" expected))
204                    (pass? (and actual (tuple< expected actual)))
205                    ;;(foo (stderr "PASS?~s\n" pass?))
206                    (dependency (set-field dependency (dependency-version-found) actual)))
207               (stdout "~a ~a\n" (if pass? (if (pair? actual) "" " yes")
208                                     (if actual " no, found" "no"))
209                       (or (version->string actual) ""))
210               (if pass? (let ((file-name (or (PATH-search-path command)
211                                              (dependency-file-name dependency))))
212                           (set-field dependency (dependency-file-name) file-name))
213                   (loop (cdr commands)))))))))
214
215 (define (check-file dependency)
216   (stdout "checking for ~a... " (dependency-name dependency))
217   (let ((file-name (and (file-exists? (dependency-file-name dependency))
218                         (dependency-file-name dependency))))
219     (stdout "~a\n" (or file-name ""))
220     (set-field dependency (dependency-file-name) file-name)))
221
222 (define* (check-header-c cc dependency #:optional (check check-preprocess-header-c))
223   (let ((name (dependency-name dependency)))
224     (stderr "checking for ~a..." name)
225     (let ((result (check cc name)))
226       (stderr " ~a\n" (if result "yes" "no"))
227       (if result (set-field dependency (dependency-file-name) name)
228           dependency))))
229
230 (define* (check-compile-c cc dependency #:optional (check check-compile-string-c))
231   (let ((name (dependency-name dependency)))
232     (stderr "checking for ~a..." name)
233     (let ((result (check cc (dependency-data dependency))))
234       (stderr " ~a\n" (if result "yes" "no"))
235       (if result (set-field dependency (dependency-file-name) name)
236           dependency))))
237
238 (define* (check-link-c cc dependency #:optional (check check-link-string-c))
239   (let ((name (dependency-name dependency)))
240     (stderr "checking for ~a..." name)
241     (let ((result (check cc (dependency-data dependency))))
242       (stderr " ~a\n" (if result "yes" "no"))
243       (if result (set-field dependency (dependency-file-name) name)
244           dependency))))
245
246 (define (check-preprocess-header-c cc header)
247   (with-output-to-file ".config.c"
248     (cut format #t "#include \"~a\"" header))
249   (with-error-to-file "/dev/null"
250     (cut zero? (system* cc "-E" "-o" ".config.E" ".config.c"))))
251
252 (define (check-compile-string-c cc string)
253   (with-output-to-file ".config.c"
254     (cut display string))
255   (with-error-to-file "/dev/null"
256     (cut zero? (system* cc "--std=gnu99" "-c" "-o" ".config.o" ".config.c"))))
257
258 (define (check-link-string-c cc string)
259   (with-output-to-file ".config.c"
260     (cut display string))
261   (with-error-to-file "/dev/null"
262     (cut zero? (system* cc "--std=gnu99" "-o" ".config" ".config.c"))))
263
264 (define (parse-opts args)
265   (let* ((option-spec
266           '((build (value #t))
267             (host (value #t))
268
269             (prefix (value #t))
270             (program-prefix (value #t))
271             (bindir (value #t))
272             (datadir (value #t))
273             (docdir (value #t))
274             (libdir (value #t))
275             (srcdir (value #t))
276             (sysconfdir (value #t))
277
278             (mes)
279             (help (single-char #\h))
280             (verbose (single-char #\v))
281             (with-cheating)
282             (with-courage)
283             (infodir (value #t))
284             (mandir (value #t))
285             (disable-silent-rules)
286             (enable-silent-rules)
287
288             (enable-fast-install)       ; Ignored for Guix
289             (includedir (value #t))     ; Ignored for Debian
290             (mandir (value #t))         ; Ignored for Debian
291             (localstatedir (value #t))  ; Ignored for Debian
292             (libdir (value #t))         ; Ignored for Debian
293             (libexecdir (value #t))     ; Ignored for Debian
294             (runstatedir (value #t))    ; Ignored for Debian
295             (disable-maintainer-mode)   ; Ignored for Debian
296             (disable-dependency-tracking) ; Ignored for Debian
297             )))
298
299     (getopt-long args option-spec)))
300
301 (define* (print-help #:optional (port (current-output-port)))
302   (format port "\
303 `configure' configures ~a ~a to adapt to many kinds of systems.
304
305 Usage: ./configure [OPTION]... [VAR=VALUE]
306
307 To assign environment variables (e.g., CC, CFLAGS...), specify them as
308 VAR=VALUE.  See below for descriptions of some of the useful variables.
309
310 Defaults for the options are specified in brackets.
311
312 Options:
313   -h, --help           display this help
314       --build=BUILD    configure for building on BUILD [guessed]
315       --disable-silent-rules
316                        verbose build output [V=1]
317       --host=HOST      cross-compile to build programs to run on HOST [BUILD]
318       --mes            use Mes C Library
319   -v, --verbose        be verbose
320   --with-courage       assert being courageous to configure for unsupported platform
321   --with-cheating      cheat using Guile instead of Mes
322
323 Installation directories:
324   --prefix=DIR         install in prefix DIR [~a]
325   --infodir=DIR        info documentation [PREFIX/share/info]
326   --mandir=DIR         man pages [PREFIX/share/man]
327
328 Program names:
329   --program-prefix=PREFIX            prepend PREFIX to installed program names
330   --program-suffix=SUFFIX            append SUFFIX to installed program names
331
332 Ignored for Guix:
333   --enable-fast-install
334
335 Ignored for Debian:
336   --disable-dependency-tracking
337   --disable-maintainer-mode
338   --includedir=DIR
339   --libdir=DIR
340   --libexecdir=DIR
341   --localstatedir=DIR
342   --runstatedir=DIR
343
344 Some influential environment variables:
345   CC                C compiler command
346   CFLAGS            C compiler flags
347   GUILE             guile command
348   GUILD             guild command
349   MES_FOR_BUILD     build system MES [can be mes or guile]
350   MES_SEED          location of mes-seed
351   TINYCC_PREFIX     location of tinycc [for tests/test2]
352 " PACKAGE VERSION (getenv "prefix")))
353
354 (define (main args)
355   (let* ((options (parse-opts args))
356          (build-type (option-ref options 'build %host-type))
357
358          (host-type (option-ref options 'host %host-type))(prefix "/usr/local")
359
360          (prefix "/usr/local")
361          (prefix (option-ref options 'prefix prefix))
362          (program-prefix (option-ref options 'program-prefix ""))
363          (program-suffix (option-ref options 'program-suffix ""))
364          (infodir (option-ref options 'infodir "${prefix}/share/info"))
365          (mandir (option-ref options 'infodir "${prefix}/share/man"))
366          (sysconfdir (option-ref options 'sysconfdir "${prefix}/etc"))
367
368          (bindir (option-ref options 'bindir "${prefix}/bin"))
369          (datadir (option-ref options 'datadir "${prefix}/share"))
370          (docdir (option-ref options 'docdir "${datadir}/doc/mes-${VERSION}"))
371          (libdir (option-ref options 'libdir "${prefix}/lib"))
372          (moduledir "${datadir}/mes/module")
373          (moduledir/ (gulp-pipe* "echo" prefix "/share/mes/module/"))
374          (guile-effective-version (effective-version))
375          (guile-site-dir (if (equal? prefix ".") (canonicalize-path ".")
376                              (string-append prefix "/share/guile/site/" guile-effective-version)))
377          (guile-site-ccache-dir (if (equal? prefix ".") (canonicalize-path ".")
378                                     (string-append prefix "/lib/guile/" guile-effective-version "/site-ccache")))
379
380          (srcdir (dirname (car (command-line))))
381          (srcdest (if (equal? srcdir ".") ""
382                       (string-append srcdir "/")))
383          (abs-top-srcdir (canonicalize-path srcdir))
384          (abs-top-builddir (canonicalize-path (getcwd)))
385          (top-builddir (if (equal? srcdir ".") "."
386                            abs-top-builddir))
387
388          (with-cheating? (option-ref options 'with-cheating #f))
389          (with-courage? (option-ref options 'with-courage #f))
390          (disable-silent-rules? (option-ref options 'disable-silent-rules #f))
391          (enable-silent-rules? (option-ref options 'enable-silent-rules #f))
392          (vars (filter (cut string-index <> #\=) (option-ref options '() '())))
393          (help? (option-ref options 'help #f))
394          (mes? (option-ref options 'mes #f)))
395     (when help?
396       (print-help)
397       (exit 0))
398     (set! %verbose? (option-ref options 'verbose #f))
399     (when %verbose?
400       (stderr "configure args=~s\n" args))
401     (for-each (lambda (v) (apply setenv (string-split v #\=))) vars)
402     (let* ((mes-seed (or (getenv "MES_SEED")
403                          (string-append srcdest "../mes-seed")))
404            (mes-seed (and mes-seed
405                           (file-exists? (string-append mes-seed "/x86-mes/mes.S"))
406                           mes-seed))
407            (tinycc-prefix (or (getenv "TINYCC_PREFIX")
408                               (string-append srcdest "../tinycc-prefix")))
409            (gcc (or (getenv "CC") "gcc"))
410            (tcc (or (getenv "TCC") "tcc"))
411            (mescc (or (getenv "MESCC") "mescc"))
412            (deps (fold (lambda (program results)
413                          (cons (check-program-version program) results))
414                        '()
415                        (list (make-dep "hex2" #:version '(0 3))
416                              (make-dep "M1" #:version '(0 3))
417                              (make-dep "blood-elf" #:version '(0 1))
418                              (make-dep "guile" #:version '(2 0) #:commands '("guile-2.2" "guile-2.0" "guile-2" "guile") #:optional? #t)
419                              (make-dep "mes" #:version '(0 18) #:optional? #t)
420                              (make-dep "guix" #:version '(0 13) #:optional? #t)
421                              (make-dep "ar" #:version '(2 10) #:optional? #t)
422                              (make-dep "bash" #:version '(2 0) #:optional? #t)
423                              (make-dep "guild" #:version '(2 0) #:commands '("guild" "guile-tools"))
424                              (make-dep "cc" #:commands (list gcc tcc mescc) #:optional? #t)
425                              (make-dep "make" #:optional? #t)
426                              (make-dep "makeinfo" #:optional? #t)
427                              (make-dep "dot" #:version-option "-V" #:optional? #t)
428                              (make-dep "help2man" #:version '(1 47) #:optional? #t)
429                              (make-dep "perl" #:version '(5) #:optional? #t)
430                              (make-dep "git" #:version '(2) #:optional? #t))))
431            (guile (file-name "guile" deps))
432            (deps (if guile (cons (check-program-version (make-dep "nyacc" #:version '(0 86 0) #:commands (list (string-append guile " -c '(use-modules (nyacc lalr)) (display *nyacc-version*)'")) #:file-name #t))
433                                  deps)
434                      deps))
435            (guile (or guile "guile"))
436            (cc (file-name "cc" deps))
437            (deps (if cc
438                      (cons* (check-header-c cc (make-dep "limits.h"))
439                             (check-header-c cc (make-dep "stdio.h" #:optional? #t))
440                             deps)
441                      deps))
442            (deps (cons (check-file (make-dep "tinycc-prefix" #:optional? #t
443                                              #:file-name tinycc-prefix))
444                        deps))
445            (missing (filter (conjoin (negate dependency-file-name)
446                                      (negate dependency-optional?)) deps))
447            (deps (if cc
448                      (cons (check-compile-c cc (make-dep "cc is GNU C" #:data "#if !defined (__GNUC__)
449 #error no gnuc
450 #endif
451 "))
452                            deps)
453                      deps))
454            (gcc? (file-name "cc is GNU C" deps))
455            (deps (if cc
456                      (cons (check-compile-c cc (make-dep "cc is Mes C" #:data "#if !defined (__MESC__)
457 #error no mesc
458 #endif
459 "))
460                            deps)
461                      deps))
462            (mesc? (file-name "cc is Mes C" deps))
463            (deps (if cc
464                      (cons (check-compile-c cc (make-dep "cc is Tiny CC" #:data "#if !defined (__TINYCC__)
465 #error no tinycc
466 #endif
467 "))
468                            deps)
469                      deps))
470            (tcc? (file-name "cc is Tiny CC" deps))
471            (deps (if cc
472                      (cons (check-link-c cc (make-dep "if cc can create executables" #:data "int main () {return 0;}"))
473                            deps)
474                      deps))
475            (mes? (or mes? (not (file-name "if cc can create executables" deps))))
476            (build-type (or (and cc (gulp-pipe* cc "-dumpmachine")) build-type))
477            (arch (car (string-split build-type #\-)))
478            (arch (if (member arch '("i386" "i486" "i586" "i686")) "x86"
479                      arch))
480            (mes-arch arch)
481            (mes-arch (if mes? (string-append mes-arch "-mes") mes-arch))
482            (mes-arch (if gcc? (string-append mes-arch "-gcc") mes-arch))
483            (mes-arch (if tcc? (string-append mes-arch "-gcc") mes-arch))
484            (posix? (and (not mesc?) (not mes?))))
485
486       (define* (substitute file-name pairs
487                            #:key (target (if (string-suffix? ".in" file-name)
488                                              (string-drop-right file-name 3) file-name)))
489         (system* "mkdir" "-p" (dirname target))
490         (with-output-to-file target
491           (lambda _
492             (let ((in (open-input-file file-name)))
493               (let loop ((line (read-line in 'concat)))
494                 (when (not (eof-object? line))
495                   (display (fold (lambda (o result)
496                                    (string-replace-string/all result (car o) (cdr o)))
497                                  line pairs))
498                   (loop (read-line in 'concat))))))))
499
500       (when (and (not (member arch '("x86" "x86_64"))) (not with-courage?))
501         (stderr "platform not supported: ~a, try --with-courage\n" arch)
502         (exit 1))
503       (when (pair? missing)
504         (stderr "\nMissing dependencies: ~a\n" (string-join (map dependency-name missing)))
505         (exit 1))
506       (let ((git (find-dep "git" deps)))
507         (when (and git
508                    (not (file-exists? ".git")))
509           ;; Debian wants to run `make clean' from a tarball
510           (and (zero? (system* "git" "init"))
511                (zero? (system* "git" "add" "."))
512                (zero? (system* "git" "commit" "--allow-empty" "-m" "Import mes")))))
513
514       (let ((pairs `(("@PACKAGE@" . ,PACKAGE)
515                      ("@VERSION@" . ,VERSION)
516
517                      ("@arch@" . ,arch)
518                      ("@build@" . ,build-type)
519                      ("@host@" . ,host-type)
520
521                      ("@gcc_p@" . ,(if gcc? "1" ""))
522                      ("@mes_arch@" . ,mes-arch)
523                      ("@mes_p@" . ,(if mes? "1" ""))
524                      ("@mesc_p@" . ,(if mesc? "1" ""))
525                      ("@posix_p@" . ,(if posix? "1" ""))
526                      ("@tcc_p@" . ,(if tcc? "1" ""))
527
528                      ("@abs_top_srcdir@" . ,abs-top-srcdir)
529                      ("@abs_top_builddir@" . ,abs-top-builddir)
530                      ("@top_builddir@" . ,top-builddir)
531
532                      ("@srcdest@" . ,srcdest)
533                      ("@srcdir@" . ,srcdir)
534
535                      ("@prefix@" . ,prefix)
536                      ("@program_prefix@" . ,program-prefix)
537                      ("@bindir@" . ,bindir)
538                      ("@datadir@" . ,datadir)
539                      ("@docdir@" . ,docdir)
540                      ("@guile_site_ccache_dir@" . ,guile-site-ccache-dir)
541                      ("@guile_site_dir@" . ,guile-site-dir)
542                      ("@infodir@" . ,infodir)
543                      ("@libdir@" . ,libdir)
544                      ("@mandir@" . ,mandir)
545                      ("@moduledir@" . ,moduledir)
546                      ("@sysconfdir@" . ,sysconfdir)
547
548                      ("@GUILE_EFFECTIVE_VERSION@" . ,(effective-version))
549                      ("@V@" . ,(if disable-silent-rules? 1 0))
550
551                      ("@AR@" . ,(or (file-name "ar" deps) ""))
552                      ("@BASH@" . ,(or (file-name "bash" deps) ""))
553                      ("@CC@" . ,(or (file-name "cc" deps) ""))
554                      ("@DOT@" . ,(or (file-name "dot" deps) ""))
555                      ("@GIT@" . ,(or (file-name "git" deps) ""))
556                      ("@GUILE@" . ,guile)
557                      ("@GUIX@" . ,(or (file-name "guix" deps) ""))
558                      ("@HELP2MAN@" . ,(or (file-name "help2man" deps) ""))
559                      ("@MAKEINFO@" . ,(or (file-name "makeinfo" deps) ""))
560                      ("@MES_FOR_BUILD@" . ,(or (file-name "mes" deps)
561                                                guile))
562                      ("@MES_SEED@" . ,(or mes-seed ""))
563                      ("@PERL@" . ,(or (file-name "perl" deps) ""))
564
565                      ("@CFLAGS@" . ,(or (getenv "CFLAGS") ""))
566                      ("@HEX2FLAGS@" . ,(or (getenv "HEX2FLAGS") ""))
567                      ("@M1FLAGS@" . ,(or (getenv "M1FLAGS") ""))
568
569                      ("mes/module/" . ,(string-append moduledir/))
570                      ,@(map
571                         (lambda (o)
572                           (cons (string-append "@" (variable-name o) "@") (or (format #f "~a" (dependency-file-name o)) "")))
573                         deps))))
574
575         (when (and (not cc)
576                    (not mes-seed))
577           (format (current-error-port) "must supply C compiler or MES_SEED/x86-mes/mes.S\n")
578           (exit 2))
579         (for-each (lambda (o)
580                     (let* ((src (string-append srcdest o))
581                            (target (string-drop-right o 3))
582                            (target (if (not (string-prefix? "build-aux/" target)) target
583                                        (string-drop target (string-length "build-aux/")))))
584                       (substitute src pairs #:target target)))
585                   '(
586                     "build-aux/GNUmakefile.in"
587                     "build-aux/config.status.in"
588                     "build-aux/build.sh.in"
589                     "build-aux/check.sh.in"
590                     "build-aux/install.sh.in"
591                     "build-aux/pre-inst-env.in"
592                     "build-aux/uninstall.sh.in"
593                     "mes/module/mes/boot-0.scm.in"
594                     "scripts/mescc.scm.in"
595                     "scripts/mescc.in"
596                     ))
597         (chmod "pre-inst-env" #o755)
598         (chmod "scripts/mescc" #o755)
599         (chmod "scripts/mescc.scm" #o755)
600         (chmod "build.sh" #o755)
601         (chmod "check.sh" #o755)
602         (chmod "install.sh" #o755)
603         (chmod "uninstall.sh" #o755)
604         (substitute (string-append srcdest "build-aux/config.make.in") pairs #:target ".config.make"))
605
606       (let ((make (and=> (file-name "make" deps) basename)))
607         (format (current-output-port)
608                 "
609 GNU Mes is configured for ~a
610
611 Run:
612   ~a            to build mes
613   ~a help       for help on other targets\n"
614                 mes-arch
615                 (or make "./build.sh")
616                 (or make "./build.sh"))))))