ARM: Support comparing 32 bit values.
[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,2019 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 (define *shell* "sh")
36 (define PACKAGE "mes")
37 (define PACKAGE-NAME "GNU Mes")
38 (define PACKAGE-BUGREPORT "bug-mes@gnu.org")
39 (define VERSION "0.22")
40
41 (cond-expand
42  (guile)
43  (mes (mes-use-module (srfi srfi-1))
44       (mes-use-module (srfi srfi-9))
45       (mes-use-module (srfi srfi-9 gnu))
46       (mes-use-module (srfi srfi-26))
47       (mes-use-module (mes getopt-long))
48       (mes-use-module (mes guile))
49       (mes-use-module (mes misc))
50       (mes-use-module (mes optargs))
51       (define %host-type "x86_64-unknown-linux-gnu")
52       (define OPEN_READ "r")
53       (define (canonicalize-path o)
54         (if (string-prefix? "/" o) o
55             (string-append (getcwd) "/" o)))
56       (define (sort lst less)
57         lst)
58       (define (close-pipe o) 0)
59       (define (open-pipe* OPEN_READ . commands)
60         (let ((fake-pipe ".pipe"))
61           (with-output-to-file fake-pipe
62             (lambda _
63               (let ((status (apply system* (append commands))))
64                 (set! close-pipe (lambda _ status)))))
65           (open-input-file fake-pipe)))))
66
67 (define* (PATH-search-path name #:key (default name) warn?)
68   (or (search-path (string-split (getenv "PATH") #\:) name)
69       (and (and warn? (format (current-error-port) "warning: not found: ~a\n" name))
70            default)))
71
72 ;;; Utility
73 (define (logf port string . rest)
74   (apply format (cons* port string rest))
75   (force-output port)
76   #t)
77
78 (define (stderr string . rest)
79   (apply logf (cons* (current-error-port) string rest)))
80
81 (define (stdout string . rest)
82   (apply logf (cons* (current-output-port) string rest)))
83
84 (define %verbose? #f)
85
86 (define (verbose string . rest)
87   (if %verbose? (apply stderr (cons string rest))))
88
89 (define (gulp-pipe command)
90   (let* ((err (current-error-port))
91          (foo (set-current-error-port (open-output-file ".error")))
92          (port (open-pipe command "r"))
93          (output (read-string port))
94          (status (close-pipe port))
95          (error (with-input-from-file ".error" read-string)))
96     (when (file-exists? ".error")
97       (delete-file ".error"))
98     (set-current-error-port err)
99     (verbose "command[~a]: ~s => ~a [~a]\n" status command output error)
100     (if (not (zero? status)) ""
101         (string-trim-right (string-append output error)))))
102
103 (define (gulp-pipe* . command)
104   (gulp-pipe (string-join command)))
105
106 (define (tuple< a b)
107   (cond
108    ((and (null? a) (null? b)) #t)
109    ((null? a) (not (null? b)))
110    ((null? b) #f)
111    ((and (not (< (car a) (car b)))
112          (not (< (car b) (car a))))
113     (tuple< (cdr a) (cdr b)))
114    (else (< (car a) (car b)))))
115
116 (define (tuple<= a b)
117   (or (equal? a b) (tuple< a b)))
118
119 (define (conjoin . predicates)
120   (lambda (. arguments)
121     (every (cut apply <> arguments) predicates)))
122
123 (define (char->char from to char)
124   (if (eq? char from) to char))
125
126 (define (string-replace-char string from to)
127   (string-map (cut char->char from to <>) string))
128
129 (define (string-replace-string string from to)
130   (cond ((string-contains string from)
131          => (lambda (i) (string-replace string to i (+ i (string-length from)))))
132         (else string)))
133
134 (define (string-replace-string/all string from to)
135   (or (and=> (string-contains string from)
136              (lambda (i)
137                (string-append
138                 (substring string 0 i)
139                 to
140                 (string-replace-string/all
141                  (substring string (+ i (string-length from))) from to))))
142       string))
143
144 ;;; Configure
145
146 (define-immutable-record-type <dependency>
147   (make-dependency name version-expected optional? version-option commands file-name data version-found)
148   dependency?
149   (name dependency-name)
150   (version-expected dependency-version-expected)
151   (optional? dependency-optional?)
152   (version-option dependency-version-option)
153   (commands dependency-commands)
154   (file-name dependency-file-name)
155   (data dependency-data)
156   (version-found dependency-version-found))
157
158 (define* (make-dep name #:key (version '()) optional? (version-option "--version") (commands (list name)) file-name data)
159   (let* ((env-var (getenv (name->shell-name name)))
160          (commands (if env-var (cons env-var commands) commands)))
161     (make-dependency name version optional? version-option commands file-name data #f)))
162
163 (define (find-dep name deps)
164   (find (compose (cut equal? <> name) dependency-name) deps))
165
166 (define (file-name name deps)
167   (and=> (find-dep name deps) dependency-file-name))
168
169 (define (variable-name dependency)
170   (and=>
171    (dependency-name dependency)
172    name->shell-name))
173
174 (define (name->shell-name name)
175   (string-upcase (string-replace-char name #\- #\_)))
176
177 (define (->string o)
178   (cond ((number? o) (number->string o))
179         ((string? o) o)
180         (else (format #f "~a" o))))
181
182 (define (version->string version)
183   (and version (string-join (map ->string version) ".")))
184
185 (define (string->version string)
186   (let ((split (string-tokenize string
187                                 (char-set-adjoin char-set:digit #\.))))
188     (and (pair? split)
189          (let* ((version (sort split (lambda (a b)
190                                        (let ((len-a (length (string-split a #\.)))
191                                              (len-b (length (string-split b #\.))))
192                                          (cond ((> len-a len-b) #t)
193                                                ((< len-a len-b) #f)
194                                                (else (> (string-length a) (string-length b))))))))
195                 (version (car version))
196                 (version (string-tokenize version
197                                           (char-set-complement (char-set #\.)))))
198            (map string->number version)))))
199
200 (define (check-program-version dependency)
201   (let ((name (dependency-name dependency))
202         (expected (dependency-version-expected dependency))
203         (version-option (dependency-version-option dependency))
204         (commands (dependency-commands dependency)))
205     (let loop ((commands commands))
206       (if (or (null? commands)
207               (not (car commands))) dependency
208           (let ((command (car commands)))
209             (stdout "checking for ~a~a... " (if (string-index command #\space) name command)
210                     (if (null? expected) ""
211                         (format #f " [~a]" (version->string expected))))
212             (let* ((output (gulp-pipe (string-append command " " (if version-option version-option ""))))
213                    (actual (string->version output))
214                    (pass? (and actual (tuple< expected actual)))
215                    (dependency (set-field dependency (dependency-version-found) actual)))
216               (stdout "~a ~a\n" (if pass? (if (pair? actual) "" "yes")
217                                     (if actual " no, found" "no"))
218                       (or (version->string actual) ""))
219               (if pass? (let ((file-name (or (PATH-search-path command)
220                                              (dependency-file-name dependency))))
221                           (set-field dependency (dependency-file-name) file-name))
222                   (loop (cdr commands)))))))))
223
224 (define (check-file dependency)
225   (stdout "checking for ~a... " (dependency-name dependency))
226   (let ((file-name (and (file-exists? (dependency-file-name dependency))
227                         (dependency-file-name dependency))))
228     (stdout "~a\n" (or file-name ""))
229     (set-field dependency (dependency-file-name) file-name)))
230
231 (define* (check-header-c cc dependency #:optional (check check-preprocess-header-c))
232   (let ((name (dependency-name dependency)))
233     (stderr "checking for ~a..." name)
234     (let ((result (check cc name)))
235       (when (file-exists? ".config.c")
236         (delete-file ".config.c"))
237       (stderr " ~a\n" (if result "yes" "no"))
238       (if result (set-field dependency (dependency-file-name) name)
239           dependency))))
240
241 (define* (check-compile-c cc dependency #:optional (check check-compile-string-c))
242   (let ((name (dependency-name dependency)))
243     (stderr "checking for ~a..." name)
244     (let ((result (check cc (dependency-data dependency))))
245       (when (file-exists? ".config.c")
246         (delete-file ".config.c"))
247       (stderr " ~a\n" (if result "yes" "no"))
248       (if result (set-field dependency (dependency-file-name) name)
249           dependency))))
250
251 (define* (check-link-c cc dependency #:optional (check check-link-string-c))
252   (let ((name (dependency-name dependency)))
253     (stderr "checking for ~a..." name)
254     (let ((result (check cc (dependency-data dependency))))
255       (when (file-exists? ".config.c")
256         (delete-file ".config.c"))
257       (stderr " ~a\n" (if result "yes" "no"))
258       (if result (set-field dependency (dependency-file-name) name)
259           dependency))))
260
261 (define (cflags-list)
262   (let ((cflags (getenv "CFLAGS")))
263     (if cflags (list cflags)
264         '())))
265
266 (define (ldflags-list)
267   (let ((ldflags (getenv "LDFLAGS")))
268     (if ldflags (list ldflags)
269         '())))
270
271 (define (check-preprocess-header-c cc header)
272   (with-output-to-file ".config.c"
273     (cut format #t "#include \"~a\"" header))
274   (let ((test (lambda _ (apply system* `(,cc "-E" "-o" ".config.E" ,@(cflags-list) ".config.c")))))
275     (zero? (if %verbose? (test)
276                (with-error-to-file "/dev/null"
277                  test)))))
278
279 (define (check-compile-string-c cc string)
280   (with-output-to-file ".config.c"
281     (cut display string))
282   (let ((test (lambda _ (apply system* `(,cc "-std=gnu99" "-c" "-o" ".config.o" ,@(cflags-list) ".config.c")))))
283     (zero? (if %verbose? (test)
284                (with-error-to-file "/dev/null"
285                  test)))))
286
287 (define (check-link-string-c cc string)
288   (with-output-to-file ".config.c"
289     (cut display string))
290   (let ((test (lambda _ (apply system* `(,cc "-std=gnu99" "-o" ".config" ,@(cflags-list) ,@(ldflags-list) ".config.c")))))
291     (zero? (if %verbose? (test)
292                (with-error-to-file "/dev/null"
293                  test)))))
294
295 (define (parse-opts args)
296   (let* ((option-spec
297           '((build (value #t))
298             (host (value #t))
299
300             (prefix (value #t))
301             (program-prefix (value #t))
302             (bindir (value #t))
303             (datadir (value #t))
304             (docdir (value #t))
305             (includedir (value #t))
306             (libdir (value #t))
307             (srcdir (value #t))
308             (sysconfdir (value #t))
309
310             (mes)
311             (help (single-char #\h))
312             (verbose (single-char #\v))
313             (with-bootstrap)
314             (with-cheating)
315             (with-courage)
316             (infodir (value #t))
317             (mandir (value #t))
318             (disable-colors)
319             (enable-colors)
320             (disable-silent-rules)
321             (enable-silent-rules)
322             (with-system-libc)
323
324             (enable-fast-install)       ; Ignored for Guix
325             (mandir (value #t))         ; Ignored for Debian
326             (localstatedir (value #t))  ; Ignored for Debian
327             (libexecdir (value #t))     ; Ignored for Debian
328             (runstatedir (value #t))    ; Ignored for Debian
329             (disable-maintainer-mode)   ; Ignored for Debian
330             (disable-dependency-tracking) ; Ignored for Debian
331             )))
332
333     (getopt-long args option-spec)))
334
335 (define* (print-help #:optional (port (current-output-port)))
336   (format port "\
337 `configure' configures ~a ~a to adapt to many kinds of systems.
338
339 Usage: ./configure [OPTION]... [VAR=VALUE]
340
341 To assign environment variables (e.g., CC, CFLAGS...), specify them as
342 VAR=VALUE.  See below for descriptions of some of the useful variables.
343
344 Defaults for the options are specified in brackets.
345
346 Options:
347   -h, --help           display this help
348       --build=BUILD    configure for building on BUILD [guessed]
349       --colors         no colorized output
350       --disable-silent-rules
351                        verbose build output [V=1]
352       --host=HOST      cross-compile to build programs to run on HOST [BUILD]
353   -v, --verbose        be verbose
354   --with-bootstrap     After building mes with CC, build mes with MesCC
355   --with-courage       Assert that even if this platform is unsupported,
356                        you will be courageous and port GNU Mes to it
357                        (see \"Porting GNU Mes\" in the manual.)
358   --with-cheating      cheat using Guile instead of Mes
359   --with-system-libc   use system libc
360
361 Installation directories:
362   --prefix=DIR         install in prefix DIR [~a]
363
364   --bindir=DIR         user executables [PREFIX/bin]
365   --includedir=DIR     C header files [PREFIX/include]
366   --infodir=DIR        info documentation [PREFIX/share/info]
367   --libdir=DIR         object code libraries [EPREFIX/lib]
368   --mandir=DIR         man pages [PREFIX/share/man]
369
370 Program names:
371   --program-prefix=PREFIX            prepend PREFIX to installed program names
372   --program-suffix=SUFFIX            append SUFFIX to installed program names
373
374 Ignored for Guix:
375   --enable-fast-install
376
377 Ignored for Debian:
378   --disable-dependency-tracking
379   --disable-maintainer-mode
380   --libexecdir=DIR
381   --localstatedir=DIR
382   --runstatedir=DIR
383
384 Some influential environment variables:
385   CC                C compiler command
386   CFLAGS            C compiler flags
387   CPPFLAGS          C preprocessor flags
388   LDFLAGS           C linker flags
389   GUILE             guile command
390   GUILD             guild command
391   GUILE_LOAD_PATH   guile load path; where to find Nyacc
392   MES_FOR_BUILD     build system MES [can be mes or guile]
393 " PACKAGE VERSION (getenv "prefix")))
394
395 (define (main args)
396   (let* ((options (parse-opts args))
397          (build-type (option-ref options 'build %host-type))
398          (host-type (option-ref options 'host build-type))
399
400          (prefix "/usr/local")
401          (prefix (option-ref options 'prefix prefix))
402          (program-prefix (option-ref options 'program-prefix ""))
403          (program-suffix (option-ref options 'program-suffix ""))
404          (infodir (option-ref options 'infodir "${prefix}/share/info"))
405          (mandir (option-ref options 'mandir "${prefix}/share/man"))
406          (sysconfdir (option-ref options 'sysconfdir "${prefix}/etc"))
407
408          (bindir (option-ref options 'bindir "${prefix}/bin"))
409          (datadir (option-ref options 'datadir "${prefix}/share"))
410          (docdir (option-ref options 'docdir "${datadir}/doc/mes"))
411          (includedir (option-ref options 'includedir "${prefix}/include"))
412          (libdir (option-ref options 'libdir "${prefix}/lib"))
413          (pkgdatadir (string-append datadir "/mes"))
414          (guile-load-path (if (and (pair? %load-path) (equal? (car %load-path) ".")) (cdr %load-path)
415                               %load-path))
416          (guile-effective-version (effective-version))
417          (guile-site-dir (if (equal? prefix ".") (canonicalize-path ".")
418                              (string-append prefix "/share/guile/site/" guile-effective-version)))
419          (guile-site-ccache-dir (if (equal? prefix ".") (canonicalize-path ".")
420                                     (string-append prefix "/lib/guile/" guile-effective-version "/site-ccache")))
421
422          (srcdir (dirname (car (command-line))))
423          (srcdest (if (equal? srcdir ".") ""
424                       (string-append srcdir "/")))
425          (abs-top-srcdir (canonicalize-path srcdir))
426          (abs-top-builddir (canonicalize-path (getcwd)))
427          (top-builddir (if (equal? srcdir ".") "."
428                            abs-top-builddir))
429
430          (with-bootstrap? (option-ref options 'with-bootstrap #f))
431          (with-cheating? (option-ref options 'with-cheating #f))
432          (with-courage? (option-ref options 'with-courage #f))
433          (disable-colors? (option-ref options 'disable-colors #f))
434          (enable-colors? (option-ref options 'enable-colors #f))
435          (disable-silent-rules? (option-ref options 'disable-silent-rules #f))
436          (enable-silent-rules? (option-ref options 'enable-silent-rules #f))
437          (with-system-libc? (option-ref options 'with-system-libc #f))
438          (vars (filter (cut string-index <> #\=) (option-ref options '() '())))
439          (help? (option-ref options 'help #f))
440          (mes? (option-ref options 'mes #f)))
441     (when help?
442       (print-help)
443       (exit 0))
444     (set! %verbose? (option-ref options 'verbose #f))
445     (when %verbose?
446       (stderr "configure args=~s\n" args))
447     (for-each (lambda (v) (apply setenv (string-split v #\=))) vars)
448     (let* ((cross? (not (equal? host-type build-type)))
449            (gcc (if cross? (string-append host-type "-" "gcc") "gcc"))
450            (tcc (if cross? (string-append host-type "-" "tcc") "tcc"))
451            (mescc (if cross? (string-append host-type "-" "mescc") "mescc"))
452            (deps (fold (lambda (program results)
453                          (cons (check-program-version program) results))
454                        '()
455                        (list (make-dep "hex2")
456                              (make-dep "M1")
457                              (make-dep "blood-elf")
458                              (make-dep "diff" #:optional? #t)
459                              (make-dep "guile" #:version '(2 0) #:commands '("guile-2.2" "guile-2.0" "guile-2" "guile") #:optional? #t)
460                              (make-dep "mes" #:version '(0 20) #:optional? #t)
461                              (make-dep "guix" #:version '() #:optional? #t)
462                              (make-dep "ar" #:version '(2 10) #:optional? #t)
463                              (make-dep "sh" #:optional? #t)
464                              (make-dep "bash" #:version '(2 0) #:optional? #t)
465                              (make-dep "guild" #:version '(2 0) #:commands '("guild" "guile-tools" "true"))
466                              (make-dep "CC" #:commands `(,(getenv "CC")) #:optional? #t)
467                              (make-dep "CC-v" #:commands `(,(getenv "CC")) #:optional? #t #:version-option "-v")
468                              (make-dep "cc" #:commands '("cc") #:optional? #t)
469                              (make-dep "gcc" #:commands `(,gcc "gcc") #:optional? #t)
470                              (make-dep "mescc" #:commands `(,mescc "mescc") #:optional? #t)
471                              (make-dep "tcc" #:commands `(,tcc "tcc") #:optional? #t #:version-option "-v")
472                              (make-dep "cc-v" #:commands '("cc") #:optional? #t #:version-option "-v")
473                              (make-dep "make" #:optional? #t #:commands '("gmake" "make"))
474                              (make-dep "makeinfo" #:version '(6) #:optional? #t)
475                              (make-dep "dot" #:version-option "-V" #:optional? #t)
476                              (make-dep "help2man" #:version '(1 47) #:optional? #t)
477                              (make-dep "perl" #:version '(5) #:optional? #t))))
478            (guile (file-name "guile" deps))
479            (deps (if guile (cons (check-program-version (make-dep "nyacc" #:version '(0 99 0) #:commands (list (string-append guile " -c '(use-modules (nyacc lalr)) (display *nyacc-version*)'")) #:file-name #t #:version-option #f))
480                                  deps)
481                      deps))
482            (guile (or guile "guile"))
483            (cc (or (file-name "CC" deps)
484                    (file-name "CC-v" deps)
485                    (file-name "tcc" deps)
486                    (file-name "gcc" deps)
487                    (file-name "cc" deps)
488                    (file-name "cc-v" deps)
489                    (file-name "mescc" deps)))
490            (deps (if cc
491                      (cons* (check-header-c cc (make-dep "limits.h"))
492                             (check-header-c cc (make-dep "stdio.h" #:optional? #t))
493                             deps)
494                      deps))
495            (missing (filter (conjoin (negate dependency-file-name)
496                                      (negate dependency-optional?)) deps))
497            (deps (if cc
498                      (cons (check-compile-c cc (make-dep "cc is GNU C" #:data "#if !defined (__GNUC__)
499 #error no gnuc
500 #endif
501 "))
502                            deps)
503                      deps))
504            (gcc? (file-name "cc is GNU C" deps))
505            (deps (if cc
506                      (cons (check-compile-c cc (make-dep "cc is Mes C" #:data "#if !defined (__MESC__)
507 #error no mesc
508 #endif
509 "))
510                            deps)
511                      deps))
512            (mesc? (file-name "cc is MES C" deps))
513            (deps (if cc
514                      (cons (check-compile-c cc (make-dep "cc is Tiny C" #:data "#if !defined (__TINYC__)
515 #error no tinycc
516 #endif
517 "))
518                            deps)
519                      deps))
520            (tcc? (file-name "cc is Tiny C" deps))
521            (deps (if cc
522                      (cons (check-link-c cc (make-dep "whether cc can create executables" #:data "int main () {return 0;}"))
523                            deps)
524                      deps))
525            (system-libc? (and with-system-libc? (file-name "if cc can create executables" deps)))
526            (host-type (or (and cc (let ((dump (gulp-pipe* cc "-dumpmachine")))
527                                     (and (not (string-null? dump)) dump))) host-type))
528            (host-type-list (string-split host-type #\-))
529            (mes-cpu (car host-type-list))
530            (mes-cpu (cond ((member mes-cpu '("i386" "i486" "i586" "i686")) "x86")
531                           ((member mes-cpu '("arm" "armv4" "armv7l")) "arm")
532                           (else mes-cpu)))
533            (mes-bits (if (member mes-cpu '("x86_64")) "64"
534                          "32"))
535            (mes-libc (if system-libc? "system" "mes"))
536            (mes-kernel (car (filter
537                              (compose not
538                                       (cut member <> '("pc" "portbld" "unknown")))
539                              (cdr host-type-list))))
540            (mes-kernel (if (string-prefix? "freebsd" mes-kernel) "freebsd" mes-kernel))
541            (mes-compiler (cond (gcc? "gcc") (tcc? "gcc") (else "mescc")))
542            (mes-system (string-join (list mes-cpu mes-kernel "mes") "-"))
543            (bash (or (and (file-exists? "/bin/bash") "/bin/bash")
544                      (file-name "bash" deps)
545                      ""))
546            (shell (or (and (file-exists? "/bin/bash") "/bin/bash")
547                       (file-name "bash" deps)
548                       (and (file-exists? "/bin/sh") "/bin/sh")
549                       (file-name "sh" deps)
550                       "sh"))
551            (hex2 (file-name "hex2" deps))
552            (numbered-arch? (begin
553                              (stdout "checking for stage0 architecture flag... ")
554                              (let ((numbered? (and hex2 (string-contains (gulp-pipe (string-append hex2 " --help 2>&1" )) "--Architecture 12345"))))
555                                (stdout (if numbered? "numbered\n" "named\n"))
556                                numbered?))))
557
558       (define* (substitute file-name pairs
559                            #:key (target (if (string-suffix? ".in" file-name)
560                                              (string-drop-right file-name 3) file-name)))
561         (system* "mkdir" "-p" (dirname target))
562         (with-output-to-file target
563           (lambda _
564             (let ((in (open-input-file file-name)))
565               (let loop ((line (read-line in 'concat)))
566                 (when (not (eof-object? line))
567                   (display (fold (lambda (o result)
568                                    (string-replace-string/all result (car o) (cdr o)))
569                                  line pairs))
570                   (loop (read-line in 'concat))))))))
571
572       (when (and (not (member mes-system '("arm-linux-mes"
573                                            "x86-linux-mes"
574                                            "x86_64-linux-mes")))
575                  (not with-courage?))
576         (stderr "platform not supported: ~a
577 See \"Porting GNU Mes\" in the manual, or try --with-courage\n" mes-system)
578         (exit 1))
579       (when (pair? missing)
580         (stderr "\nMissing dependencies: ~a\n" (string-join (map dependency-name missing)))
581         (exit 1))
582       (let ((pairs `(("@PACKAGE@" . ,PACKAGE)
583                      ("@PACKAGE_NAME@" . ,PACKAGE-NAME)
584                      ("@PACKAGE_BUGREPORT@" . ,PACKAGE-BUGREPORT)
585                      ("@VERSION@" . ,VERSION)
586
587                      ("@build@" . ,build-type)
588                      ("@host@" . ,host-type)
589
590                      ("@bootstrap@" . ,(if with-bootstrap? "true" "false"))
591                      ("@courageous@" . ,(if with-courage? "true" "false"))
592                      ("@compiler@" . ,mes-compiler)
593                      ("@mes_bits@" . ,mes-bits)
594                      ("@mes_kernel@" . ,mes-kernel)
595                      ("@mes_cpu@" . ,mes-cpu)
596                      ("@mes_libc@" . ,mes-libc)
597                      ("@mes_system@" . ,mes-system)
598
599                      ("@abs_top_srcdir@" . ,abs-top-srcdir)
600                      ("@abs_top_builddir@" . ,abs-top-builddir)
601                      ("@top_builddir@" . ,top-builddir)
602
603                      ("@srcdest@" . ,srcdest)
604                      ("@srcdir@" . ,srcdir)
605
606                      ("@prefix@" . ,prefix)
607                      ("@program_prefix@" . ,program-prefix)
608                      ("@bindir@" . ,bindir)
609                      ("@datadir@" . ,datadir)
610                      ("@pkgdatadir@" . ,pkgdatadir)
611                      ("@docdir@" . ,docdir)
612                      ("@guile_site_ccache_dir@" . ,guile-site-ccache-dir)
613                      ("@guile_site_dir@" . ,guile-site-dir)
614                      ("@infodir@" . ,infodir)
615                      ("@includedir@" . ,includedir)
616                      ("@libdir@" . ,libdir)
617                      ("@mandir@" . ,mandir)
618                      ("@sysconfdir@" . ,sysconfdir)
619
620                      ("@colors@" . ,(if disable-colors? "no" "yes"))
621                      ("@V@" . ,(if disable-silent-rules? "1" "0"))
622
623                      ("@AR@" . ,(or (file-name "ar" deps) ""))
624                      ("@BASH@" . ,bash)
625                      ("@CC@" . ,cc)
626                      ("@DIFF@" . ,(or (file-name "diff" deps) (string-append abs-top-builddir "/pre-inst-env diff.scm")))
627                      ("@DOT@" . ,(or (file-name "dot" deps) ""))
628                      ("@GIT@" . ,(or (file-name "git" deps) ""))
629                      ("@GUILE@" . ,guile)
630                      ("@GUILE_EFFECTIVE_VERSION@" . ,(effective-version))
631                      ("@GUILE_LOAD_PATH@" . ,(string-join guile-load-path ":"))
632                      ("@GUIX@" . ,(or (file-name "guix" deps) ""))
633                      ("@HELP2MAN@" . ,(or (file-name "help2man" deps) ""))
634                      ("@MAKEINFO@" . ,(or (file-name "makeinfo" deps) ""))
635                      ("@MES_FOR_BUILD@" . ,(or (file-name "mes" deps)
636                                                guile))
637                      ("@PERL@" . ,(or (file-name "perl" deps) ""))
638                      ("#SCHEME=\"@SCHEME@\"" . ,(if with-cheating? (string-append "\nSCHEME=\"" guile "\"") ""))
639                      ("@SCHEME@" . ,(if with-cheating? guile ""))
640                      ("@SHELL@" . ,shell)
641
642                      ("@CFLAGS@" . ,(or (getenv "CFLAGS") "-static -g"))
643                      ("@CPPFLAGS@" . ,(or (getenv "CPPFLAGS") ""))
644                      ("@LDFLAGS@" . ,(or (getenv "LDFLAGS") "-static -g"))
645                      ("@HEX2FLAGS@" . ,(or (getenv "HEX2FLAGS") ""))
646                      ("@M1FLAGS@" . ,(or (getenv "M1FLAGS") ""))
647                      ("@numbered_arch@" . ,(if numbered-arch? "true" "false"))
648
649                      ,@(map
650                         (lambda (o)
651                           (cons (string-append "@" (variable-name o) "@") (or (format #f "~a" (dependency-file-name o)) "")))
652                         deps))))
653
654         (unless cc
655           (format (current-error-port) "must supply a C compiler")
656           (exit 2))
657         (for-each (lambda (o)
658                     (let* ((src (string-append srcdest o))
659                            (target (string-drop-right o 3))
660                            (target (if (not (string-prefix? "build-aux/" target)) target
661                                        (string-drop target (string-length "build-aux/")))))
662                       (substitute src pairs #:target target)))
663                   '(
664                     "build-aux/GNUmakefile.in"
665                     "build-aux/config.sh.in"
666                     "build-aux/build.sh.in"
667                     "build-aux/check.sh.in"
668                     "build-aux/install.sh.in"
669                     "build-aux/pre-inst-env.in"
670                     "build-aux/uninstall.sh.in"
671                     "scripts/mesar.in"
672                     "scripts/mescc.scm.in"
673                     "scripts/mescc.in"
674                     ))
675         (chmod "pre-inst-env" #o755)
676         (chmod "scripts/mesar" #o755)
677         (chmod "scripts/mescc" #o755)
678         (chmod "scripts/mescc.scm" #o755)
679         (chmod "build.sh" #o755)
680         (chmod "check.sh" #o755)
681         (chmod "install.sh" #o755)
682         (chmod "uninstall.sh" #o755)
683
684         (system* "mkdir" "-p" "include/mes")
685         (let ((pkgdatadir (gulp-pipe* "sh" "-c" (string-append "prefix=" prefix
686                                                                ";datadir=" datadir
687                                                                ";echo ${datadir}/mes"))))
688           (with-output-to-file "include/mes/config.h"
689             (lambda _
690               (if system-libc?
691                   (display "#define SYSTEM_LIBC 1
692 ")
693                   (display "#undef SYSTEM_LIBC
694 "))
695               (display (string-append "
696 #define MES_VERSION \"" VERSION "\"
697 ")))))
698         (substitute (string-append srcdest "build-aux/config.make.in") pairs #:target ".config.make"))
699
700       (let ((make (and=> (file-name "make" deps) basename)))
701         (display (string-append "
702 GNU Mes is configured for
703    compiler:   " mes-compiler "
704    cpu:        " mes-cpu "
705    bits:       " mes-bits "
706    libc:       " mes-libc "
707    kernel:     " mes-kernel "
708    system:     " mes-system "
709    tools:      " (if numbered-arch? "numbered" "named") " arch
710    bootstrap:  " (if with-bootstrap? "yes" "no") "
711    courageous: " (if with-courage? "yes" "no") "
712
713 Run:
714   " (or make "./build.sh") "           to build mes
715   " (or make "./build.sh") " help      for help on other targets\n"))))))