mescc: support -c, -o.
[mes.git] / configure
index c389175aac180a701ef66db65ea145ecb1ff9a29..6b7cc98b5e61c244c68eea5b3a0e992e8079e2e2 100755 (executable)
--- a/configure
+++ b/configure
@@ -17,12 +17,11 @@ Missing dependencies, run
 EOF
     exit 1
 fi
-unset GUILE_AUTO_COMPILE GUILE_LOAD_COMPILED_PATH
 exec ${GUILE} --no-auto-compile -L $(pwd) -e '(@@ (configure) main)' -s "$0" ${1+"$@"}
 !#
 
 ;;; Mes --- Maxwell Equations of Software
-;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
+;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;
 ;;; configure: This file is part of Mes.
 ;;;
@@ -51,20 +50,13 @@ exec ${GUILE} --no-auto-compile -L $(pwd) -e '(@@ (configure) main)' -s "$0" ${1
 
 (define *shell* "sh")
 (define PACKAGE "mes")
-(define VERSION "0.0")
+(define VERSION "0.6")
 (define PREFIX "/usr/local")
-(define GUILE_EV (effective-version))
-(define CC (or (getenv "CC") "gcc"))
+(define GUILE_EFFECTIVE_VERSION (effective-version))
 (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)
@@ -76,6 +68,18 @@ exec ${GUILE} --no-auto-compile -L $(pwd) -e '(@@ (configure) main)' -s "$0" ${1
 (define (stdout string . rest)
   (apply logf (cons* (current-output-port) string rest)))
 
+(define *verbose?* #f)
+
+(define (verbose string . rest)
+  (if *verbose?* (apply stderr (cons string rest))))
+
+(define (gulp-pipe command)
+  (let* ((port (open-pipe* OPEN_READ *shell* "-c" command))
+         (output (read-string port))
+         (status (close-pipe port)))
+    (verbose "command[~a]: ~s => ~a\n" status command output)
+    (if (not (zero? status)) "" (string-trim-right output #\newline))))
+
 (define* ((->string #:optional (infix "")) h . t)
   (let ((o (if (pair? t) (cons h t) h)))
     (match o
@@ -107,53 +111,72 @@ exec ${GUILE} --no-auto-compile -L $(pwd) -e '(@@ (configure) main)' -s "$0" ${1
   (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
+(define* (check-version name expected
+                        #:key
                         (deb #f)
                         (version-option '--version)
-                        (compare tuple<=))
-  (stderr "checking for ~a~a..." command
+                        (compare tuple<=)
+                        (command name))
+  (stderr "checking for ~a~a..." name
           (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))
+  (let* ((output (gulp-pipe (format #f "~a ~a 2>&1" command version-option)))
+         (actual (string->version output))
          (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?))
+    (or pass?
+        (if (not (pair? name)) (begin (set! required (cons (or deb name) required)) pass?)
+            (check-version (cdr name) expected deb version-option compare)))))
 
 (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 ~s' | gcc -E - > /dev/null 2>&1" header)))
+       'yes))
+
 (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)))
+  (and (= 0 (system (format #f "echo '#include ~s' | 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++))
+(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* (check-header-c++ header deb #:optional (check check-compile-header-c++))
+  (check-header-c header deb check))
+
 (define guix?
-  (system "guix --version &>/dev/null"))
+  (and (zero? (system "guix --version 1>/dev/null 2>/dev/null")) 1))
 ;;;
 
+(define CC (or (getenv "CC") "gcc"))
+(define BUILD_TRIPLET (gulp-pipe (string-append CC " -dumpmachine 2>/dev/null")))
+(define ARCH (car (string-split BUILD_TRIPLET #\-)))
+(define CC32 (or (getenv "CC32")
+                 (if (member ARCH '("i686" "arm")) (string-append BUILD_TRIPLET "-" CC)
+                     "i686-unknown-linux-gnu-gcc")))
+
 (define (parse-opts args)
   (let* ((option-spec
          '((build (value #t))
+            (host (value #t))
             (help (single-char #\h))
             (prefix (value #t))
             (sysconfdir (value #t))
+            (verbose (single-char #\v))
+            (with-courage)
             ;;ignore
             (enable-fast-install)))
          (options (getopt-long args option-spec))
@@ -167,39 +190,58 @@ exec ${GUILE} --no-auto-compile -L $(pwd) -e '(@@ (configure) main)' -s "$0" ${1
              ((or (and usage? stderr) stdout) "\
 Usage: ./configure [OPTION]...
   -h, --help           display this help
+      --build=BUILD    configure for building on BUILD [guessed]
+      --host=HOST      cross-compile to build programs to run on HOST [BUILD]
   --prefix=DIR         install in PREFIX [~a]
   --sysconfdir=DIR     read-only single-machine data [PREFIX/etc]
+  -v, --verbose        be verbose
+  --with-courage       assert being courageous to configure for unsupported platform
 " 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))
+         (host-triplet (option-ref options 'host BUILD_TRIPLET))
          (prefix (option-ref options 'prefix PREFIX))
-         (sysconfdir (option-ref options 'sysconfdir SYSCONFDIR)))
+         (sysconfdir (option-ref options 'sysconfdir SYSCONFDIR))
+         (verbose? (option-ref options 'verbose #f))
+         (with-courage? (option-ref options 'with-courage #f)))
+    (set! *verbose?* verbose?)
     (check-version 'bash '(4 0))
-    (check-version 'gcc '(4 8))
+    (when (and (not (member ARCH '("i686" "x86_64"))) (not with-courage?))
+          (stderr "platform not supported: ~a, try --with-courage\n" ARCH)
+          (exit 1))
+    (check-version CC '(4 8))
+    (check-header-c "stdio.h" "libc-dev")
+    (check-header-c "limits.h" "linux-headers")
+    (check-version CC32 '(4 8))
     (check-version 'guile '(2 0))
     (check-version 'make '(4 0))
     (check-version 'perl '(5))
+    (check-version 'nyacc '(0 78 0) #:command (string-append GUILE " -c '(use-modules (nyacc lalr)) (display *nyacc-version*)'"))
 
     (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))
+      (stderr "\nMissing dependencies [~a], run\n\n" ((->string ", ") required))
+      (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 "build:=~a\n" build-triplet)
+        (stdout "host:=~a\n" host-triplet)
+        (stdout "srcdir:=.\n")
+        (stdout "ARCH:=~a\n" ARCH)
         (stdout "CC:=~a\n" CC)
+        (stdout "CC32:=~a\n" CC32)
         (stdout "GUILE:=~a\n" GUILE)
-        (stdout "GUILE_EV:=~a\n" GUILE_EV)
+        (stdout "GUILE_EFFECTIVE_VERSION:=~a\n" GUILE_EFFECTIVE_VERSION)
+        (stdout "GUIX_P:=~a\n" (if guix? guix? ""))
         (stdout "PACKAGE:=~a\n" PACKAGE)
         (stdout "VERSION:=~a\n" VERSION)
-        (stdout "PREFIX:=~a\n" prefix)
+        (stdout "PREFIX:=~a\n" (gulp-pipe (string-append "echo " prefix)))
         (stdout "SYSCONFDIR:=~a\n" sysconfdir)))
     (stdout "\nRun:
   make            to build mes