~ chicken-core (chicken-5) 34d36e0c22748d8efb6fe012e68b59d09fd280a9


commit 34d36e0c22748d8efb6fe012e68b59d09fd280a9
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Thu Aug 18 17:51:37 2016 +0200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Sun Nov 13 11:32:20 2016 +0100

    various corrections and enhancements in egg-compile/new-install

diff --git a/egg-compile.scm b/egg-compile.scm
index d6bc8831..a5018901 100644
--- a/egg-compile.scm
+++ b/egg-compile.scm
@@ -5,10 +5,11 @@
   '(synopsis authors category license version dependencies files
     source-file csc-options test-dependencies destination linkage
     build-dependencies components foreign-dependencies link-options
-    custom-bulild target host platform))  
+    custom-bulild target host platform doc-from-wiki extension program
+    data))  
 
 (define nested-items 
-  '(components target host))
+  '(components target host extension program data))
 
 (define named-items
   '(extension program data c-include scheme-include))
@@ -21,10 +22,11 @@
 (define default-dynamic-extension-link-options '())
 (define default-extension-linkage '(static dynamic))
 (define default-program-linkage '(dynamic))
-(define unix-executable-extension "")
-(define windows-executable-extension ".exe")
-(define unix-object-extension ".o")
-(define windows-object-extension ".obj")
+
+(define +unix-executable-extension+ "")
+(define +windows-executable-extension+ ".exe")
+(define +unix-object-extension+ ".o")
+(define +windows-object-extension+ ".obj")
 
 
 ;;; validate egg-information tree
@@ -34,15 +36,16 @@
     (error "egg-information has invalid structure"))
   (for-each
     (lambda (item)
-      (cond ((not (and (list? item) (pair? item) (symbol? (car item))))
-             (error "egg-information item has invalid structure" item))
-            ((not (memq (car item) valid-items))
-             (error "invalid item" item))
-            ((and (memq (car item) named-items) (not (symbol? (cadr item))))
-             (error "missing name for item" item))
-            ((memq (car item) nested-items)
-             (validate-egg-info 
-               (if (memq (car item) named-items) (cddr item) (cdr item))))))
+      (unless (and (list? item) (pair? item) (symbol? (car item)))
+        (error "egg-information item has invalid structure" item))
+      (when (and (memq (car item) named-items) (not (symbol? (cadr item))))
+        (error "missing name for item" item))
+      (if (memq (car item) nested-items)
+          (validate-egg-info (if (memq (car item) named-items)
+                                 (cddr item) 
+                                 (cdr item)))
+          (unless (memq (car item) valid-items)
+             (error "invalid item" item))))
     info)
   info)
 
@@ -69,19 +72,24 @@
 
 (define (object-extension platform)
   (case platform
-    ((unix) unix-object-extension)
-    ((windows) windows-object-extension)))
+    ((unix) +unix-object-extension+)
+    ((windows) +windows-object-extension+)))
 
 (define (executable-extension platform)
   (case platform
-     ((unix) unix-executable-extension)
-     ((windows) windows-executable-extension)))
+     ((unix) +unix-executable-extension+)
+     ((windows) +windows-executable-extension+)))
 
 (define (copy-directory-command platform)
   (case platform
     ((unix) "cp")
     ((windows) "xcopy /y")))
 
+(define (mkdir-command platform)
+  (case platform
+    ((unix) "mkdir -p")
+    ((windows) "mkdir")))
+
 (define install-command copy-directory-command)
 
 (define (destination-repository mode)
@@ -328,102 +336,122 @@
 ;;; shell code generation - build operations
 
 (define (gen-compile-static-extension name #!key mode platform dependencies source 
-                                      options custom)
+                                      (options '()) custom)
   (let ((cmd (or custom 
                  (conc default-csc " -D compiling-extension -c -J -unit " name
                        " -D compiling-static-extension")))
         (out (quotearg (target-file (conc name (object-extension platform)) mode)))
         (src (quotearg (or source (conc name ".scm")))))
-    (conc (slashify default-builder platform) " " out " " cmd (arglist options) 
-          " " src " -o " out " : "
-          src (arglist dependencies))))
+    (print (slashify default-builder platform) " " out " " cmd (arglist options) 
+           " " src " -o " out " : "
+           src (arglist dependencies))))
 
 (define (gen-compile-dynamic-extension name #!key mode platform dependencies mode
-                                       source options link-options custom)
+                                       source (options '()) (link-options '()) 
+                                       custom)
   (let ((cmd (or custom 
                  (conc default-csc " -D compiling-extension -J -s")))
         (out (quotearg (target-file (conc name ".so") mode)))
         (src (quotearg (or source (conc name ".scm")))))
-    (conc (slashify default-builder platform) " " out " " cmd (arglist options)
-          (arglist link-options) " " src " -o " out " : "
-          src (arglist dependencies))))
+    (print (slashify default-builder platform) " " out " " cmd (arglist options)
+           (arglist link-options) " " src " -o " out " : "
+           src (arglist dependencies))))
 
 (define (gen-compile-import-library name #!key platform dependencies source mode
-                                    options link-options custom)
+                                    (options '()) (link-options '())
+                                    custom)
   (let ((cmd (or custom (conc default-csc " -s")))
         (out (quotearg (target-file (conc name ".import.so") mode)))
         (src (quotearg (or source (conc name ".import.scm")))))
-    (conc (slashify default-builder platform) " " out " " cmd (arglist options)
-          (arglist link-options) " " src " -o " out " : "
-          src (arglist dependencies))))
+    (print (slashify default-builder platform) " " out " " cmd (arglist options)
+           (arglist link-options) " " src " -o " out " : "
+           src (arglist dependencies))))
 
 (define (gen-compile-dynamic-program name #!key platform dependencies source mode
-                                     options link-options custom)
+                                     (options '()) (link-options '())
+                                     custom)
   (let ((cmd (or custom default-csc))
         (out (quotearg 
                (target-file (conc name (executable-extension platform)) mode)))
         (src (quotearg (or source (conc name ".scm")))))
-    (conc (slashify default-builder platform) " " out " " cmd (arglist options)
-          (arglist link-options) " " src " -o " out " : "
-          src (arglist dependencies))))
+    (print (slashify default-builder platform) " " out " " cmd (arglist options)
+           (arglist link-options) " " src " -o " out " : "
+           src (arglist dependencies))))
 
 (define (gen-compile-static-program name #!key platform dependencies source
-                                    options link-options custom mode)
+                                    (options '()) (link-options '())
+                                    custom mode)
   (let ((cmd (or custom (conc default-csc " -static-libs")))
         (out (quotearg 
                (target-file (conc name (executable-extension platform)) mode)))
         (src (quotearg (or source (conc name ".scm")))))
-    (conc (slashify default-builder platform) " " out " " cmd (arglist options)
-          (arglist link-options) " " src " -o " out " : "
-          src (arglist dependencies))))
+    (print (slashify default-builder platform) " " out " " cmd (arglist options)
+           (arglist link-options) " " src " -o " out " : "
+           src (arglist dependencies))))
 
 
 ;; installation operations
 
 (define (gen-install-static-extension name #!key platform mode)
   (let* ((cmd (install-command platform))
+         (mkdir (mkdir-command platform))
          (ext (object-extension platform))
          (out (quotearg (target-file (conc name ext) mode)))
-         (dest (destination-repository mode)))
-    (conc cmd " " out " " (quotearg (slashify (conc dest "/" name ext) platform)))))
+         (dest (destination-repository mode))
+         (dfile (quotearg dest platform)))
+    (print mkdir " " dfile)
+    (print cmd " " out " " (quotearg (slashify dest "/" name ext) platform))))
 
 (define (gen-install-dynamic-extension name #!key platform mode)
-  (let ((cmd (install-command platform))
-        (out (quotearg (target-file (conc name ".so") mode)))
-        (dest (destination-repository mode)))
-    (conc cmd " " out " " (quotearg (slashify (conc dest "/" name ".so") platform)))))
+  (let* ((cmd (install-command platform))
+         (out (quotearg (target-file (conc name ".so") mode)))
+         (ext (object-extension platform))
+         (dest (destination-repository mode))
+         (dfile (quotearg (slashify dest platform))))
+    (print mkdir " " dfile)
+    (print cmd " " out " " (quotearg (slashify dest "/" name ".so") platform))))
 
 (define (gen-install-import-library name #!key platform mode)
-  (let ((cmd (install-command platform))
-        (out (quotearg (target-file (conc name ".import.so") mode)))
-        (dest (destination-repository mode)))
-    (conc cmd " " out " " 
-          (quotearg (slashify (conc dest "/" name ".import.so") platform)))))
+  (let* ((cmd (install-command platform))
+         (out (quotearg (target-file (conc name ".import.so") mode)))
+         (dest (destination-repository mode))
+         (dfile (quotearg (slashify dest platform))))
+    (print mkdir " " dfile)
+    (print cmd " " out " " 
+           (quotearg (slashify (conc dest "/" name ".import.so") platform)))))
 
 (define (gen-install-import-library-source name #!key platform mode)
-  (let ((cmd (install-command platform))
-        (out (quotearg (target-file (conc name ".import.scm") mode)))
-        (dest (destination-repository mode)))
-    (conc cmd " " out " " 
+  (let* ((cmd (install-command platform))
+         (out (quotearg (target-file (conc name ".import.scm") mode)))
+         (dest (destination-repository mode))
+         (dfile (quotearg (slashify dest platform))))
+    (print mkdir " " dfile)
+    (print cmd " " out " " 
           (quotearg (slashify (conc dest "/" name ".import.scm") platform)))))
 
 (define (gen-install-program name #!key platform mode)
   (let* ((cmd (install-command platform))
          (ext (executable-extension platform))
          (out (quotearg (target-file (conc name ext) mode)))
-         (dest (if (eq? mode 'target) target-bindir host-bindir)))
-    (conc cmd " " out " "
-          (quotearg (slashify (conc dest "/" name ext) platform)))))
+         (dest (if (eq? mode 'target) target-bindir host-bindir))
+         (dfile (quotearg (slashify dest platform))))
+    (print mkdir " " dfile)
+    (print cmd " " out " "
+           (quotearg (slashify (conc dest "/" name ext) platform)))))
 
 (define (gen-install-data name #!key platform files destination mode)
   (let* ((cmd (install-command platform))
-         (dest (or destination (if (eq? mode 'target) target-sharedir host-sharedir))))
-    (conc cmd (arglist files) " " (quotearg (slashify dest platform)))))
+         (dest (or destination (if (eq? mode 'target) target-sharedir host-sharedir)))
+         (dfile (quotearg (slashify dest platform))))
+    (print mkdir " " dfile)
+    (print cmd (arglist files) " " dfile)))
 
 (define (gen-install-c-include name #!key platform deps files dest mode)
   (let* ((cmd (install-command platform))
-         (dest (or dest (if (eq? mode 'target) target-incdir host-incdir))))
-    (conc cmd " " (arglist files) " " (quotearg (slashify dest platform)))))
+         (dest (or dest (if (eq? mode 'target) target-incdir host-incdir)))
+         (dfile (quotearg (slashify dest platform))))
+    (print mkdir " " dfile)
+    (print cmd " " (arglist files) " " dfile)))
 
 (define command-table
   `((compile-static-extension ,gen-compile-static-extension)
@@ -446,17 +474,76 @@
 (define (generate-shell-commands platform cmds dest prefix suffix)
   (with-output-to-file dest
     (lambda ()
-      (prefix)
+      (prefix platform)
       (for-each
         (lambda (cmd)
+          (d "~s~%" cmd)
           (cond ((assq (car cmd) command-table)
                   => (lambda (op) 
-                       (apply (cadr op) (cons* platform: platform (cddr cmd)))))
+                       (apply (cadr op) 
+                              (cons* (cadr cmd) platform: platform (cddr cmd)))))
                 (else (error "invalid command" cmd))))
         cmds)
-      (suffix))))
+      (suffix platform))))
                         
 
+;;; affixes for build- and install-scripts
+
+(define ((build-prefix mode name info) platform)
+  (case platform
+    ((unix)
+     (printf #<<EOF
+#!/bin/sh~%
+EOF
+             ))
+    ((windows)
+     (printf #<<EOF
+@echo off
+EOF
+             ))))
+
+(define ((build-suffix mode name info) platform)
+  (case platform
+    ((unix)
+     (printf #<<EOF
+EOF
+             ))
+    ((windows)
+     (printf #<<EOF
+EOF
+             ))))
+
+(define ((install-prefix mode name info) platform)
+  (case platform
+    ((unix)
+     (printf #<<EOF
+#!/bin/sh~%
+EOF
+             ))
+    ((windows)
+     (printf #<<EOF
+@echo off~%
+EOF
+             ))))
+
+(define ((install-suffix mode name info) platform)
+  (let ((infostr (with-output-to-string (cut pp info)))
+        (dest (make-pathname (destination-repository mode) name +egg-info-extension+)))
+    (case platform
+      ((unix)
+       (printf #<<EOF
+cat >~a <<ENDINFO
+~aENDINFO~%
+EOF
+               dest infostr))
+      ((windows)
+       (printf #<<EOF
+echo ~a >~a~%
+EOF
+               (string-intersperse (string-split infostr) "^\n")
+               dest)))))
+
+
 ;;; some utilities for mangling + quoting
 
 (define (quotearg str)
diff --git a/new-install.scm b/new-install.scm
index 2430a6c5..a2e3dce2 100644
--- a/new-install.scm
+++ b/new-install.scm
@@ -11,6 +11,7 @@
 (import (chicken format))
 (import (chicken irregex))
 (import (chicken tcp))
+(import (chicken ports))
 (import (chicken posix))
 (import (chicken io))
 (import (chicken time))
@@ -43,6 +44,7 @@
 (define proxy-port #f)
 (define proxy-user-pass #f)
 (define retrieve-only #f)
+(define do-not-build #f)
 (define list-versions-only #f)
 (define canonical-eggs '())
 (define dependencies '())
@@ -79,7 +81,17 @@
         'target
         'host)))
 
-  
+(define (build-script-extension mode platform)
+  (string-append "build"
+                 (if (eq? mode 'target) ".target" "")
+                 (if (eq? platform 'windows) ".bat" ".sh")))
+
+(define (install-script-extension mode platform)
+  (string-append "install"
+                 (if (eq? mode 'target) ".target" "")
+                 (if (eq? platform 'windows) ".bat" ".sh")))
+
+
 ;; usage information
   
 (define (usage code)
@@ -267,7 +279,7 @@
                   (> (- now (with-input-from-file timestamp read)) +one-hour+)
                   (not (check-server-version name version lversion)))
              (fetch)
-             (let ((info (load-egg-info eggfile)))
+             (let ((info (load-egg-info eggfile))) ; new egg info (fetched)
                (values cached (get-egg-property info 'version))))
             (else (values cached version))))))
     
@@ -282,21 +294,23 @@
 (define (fetch-egg-sources name version dest)
   (let loop ((locs default-locations))
     (cond ((null? locs)
-           (let loop ((srvs default-servers))
-             (receive (dir ver)
-               (try-download name (resolve-location (car srvs))
-                             version: version 
-                             destination: dest
-                             tests: run-tests 
-                             proxy-host: proxy-host
-                             proxy-port: proxy-port 
-                             proxy-user-pass: proxy-user-pass)
-              (cond (dir
-                     (with-output-to-file 
-                       (make-pathname dest +timestamp-file+)
-                       (lambda () (write (current-seconds)))))
-                    ((null? srvs) (error "extension or version not found"))
-                    (else (loop (cdr srvs)))))))
+           (let ((tmpdir (create-temporary-directory)))
+             (let loop ((srvs default-servers))
+               (receive (dir ver)
+                 (try-download name (resolve-location (car srvs))
+                               version: version 
+                               destination: tmpdir
+                               tests: run-tests 
+                               proxy-host: proxy-host
+                               proxy-port: proxy-port 
+                               proxy-user-pass: proxy-user-pass)
+                 (cond (dir
+                         (rename-file tmpdir dest)
+                         (with-output-to-file 
+                           (make-pathname dest +timestamp-file+)
+                           (lambda () (write (current-seconds)))))
+                       ((null? srvs) (error "extension or version not found"))
+                       (else (loop (cdr srvs))))))))
           ((probe-dir (make-pathname (car locs) name))
            => (lambda (dir)
                 (let* ((eggfile (make-pathname dir name +egg-extension+))
@@ -350,6 +364,7 @@
     (for-each
       (lambda (e+d+v)
         (unless (member (car e+d+v) checked-eggs)
+          (d "checking ~a ...~%" (car e+d+v))
           (set! checked-eggs (cons (car e+d+v) checked-eggs))
           (let* ((fname (make-pathname (cadr e+d+v) (car e+d+v) +egg-extension+))
                  (info (load-egg-info fname)))
@@ -379,7 +394,7 @@
                   #;(for-each
                     (lambda (e)
                       (d "removing previously installed extension `~a'" e)
-                      (remove-extension e) )
+                      (remove-extension e) )  ; - not implemented yet
                     ueggs)
                   (retrieve-eggs ueggs) ) ) ) ) ) )
       canonical-eggs)))
@@ -401,7 +416,7 @@
 
 (define (get-egg-dependencies info)
   (append (get-egg-property info 'dependencies '())
-          (if run-tests (get-egg-property info 'test-dependencies '()))))
+          (if run-tests (get-egg-property info 'test-dependencies '()) '())))
 
 (define (check-dependency dep)
   (cond ((or (symbol? dep) (string? dep))
@@ -542,8 +557,69 @@
 ;; perform installation of retrieved eggs
   
 (define (install-eggs)
-  ;; ...
-  #f)
+  (for-each
+    (lambda (egg)
+      (let* ((name (car egg))
+             (dir (cadr egg))
+             (eggfile (make-pathname dir name +egg-extension+))
+             (info (load-egg-info eggfile #f)))
+        (when (or host-extension 
+                  (and (not target-extension)
+                       (not host-extension)))
+          (let-values (((build install info) (compile-egg-info info platform 'host)))
+            (let ((bscript (make-pathname dir name 
+                                          (build-script-extension 'host platform)))
+                  (iscript (make-pathname dir name 
+                                          (install-script-extension 'host
+                                                                    platform))))
+              (generate-shell-commands platform build bscript
+                                       (build-prefix 'host name info)
+                                       (build-suffix 'host name info))
+              (generate-shell-commands platform install iscript
+                                       (install-prefix 'host name info)
+                                       (install-suffix 'host name info))
+              (run-script dir bscript platform)
+              (run-script dir iscript platform))))
+        (when target-extension
+          (let-values (((build install info) (compile-egg-info info platform 'target)))
+            (let ((bscript (make-pathname dir name 
+                                          (build-script-extension 'target platform)))
+                  (iscript (make-pathname dir name 
+                                          (install-script-extension 'target 
+                                                                    platform))))
+              (generate-shell-commands platform build bscript
+                                       (build-prefix 'target name info)
+                                       (build-suffix 'target name info))
+              (generate-shell-commands platform install iscript
+                                       (install-prefix 'target name info)
+                                       (install-suffix 'target name info))
+              (run-script dir bscript platform)
+              (run-script dir iscript platform))))))
+    canonical-eggs))
+
+(define (run-script dir script platform)
+  (if do-not-build
+      (print script)
+      (let ((old (current-directory)))
+        (change-directory dir)
+        (d "running script ~a~%" script)
+        (if (eq? platform 'windows)
+            (exec script)
+            (exec (string-append "sh " (make-pathname "." script))))
+        (change-directory old))))
+
+(define (write-info name info mode)
+  (d "writing info for egg ~a~%" name info)
+  (let ((infofile (make-pathname name (destination-repository mode))))
+    (when (eq? platform 'unix)
+      (exec (string-append "chmod a+r " (quotearg infofile))))))
+
+(define (exec cmd)
+  (d "executing: ~s~%" cmd)
+  (let ((r (system cmd)))
+    (unless (zero? r)
+      (error "shell command terminated with nonzero exit code" r cmd))))
+
 
 ;; command line parsing and selection of operations
   
@@ -554,6 +630,7 @@
            (map (lambda (fname)
                   (list (pathname-file fname) (current-directory) #f))
              (glob "*.egg")))
+         (retrieve-eggs '())
          (install-eggs))
         (else
           (let ((eggs (apply-mappings eggs)))
@@ -594,6 +671,9 @@
                   ((equal? arg "-target")
                    (set! host-extension #f)
                    (loop (cdr args)))
+                  ((equal? arg "-n")
+                   (set! do-not-build #t)
+                   (loop (cdr args)))
 
                   ;;XXX 
                   
Trap