~ chicken-core (chicken-5) f12ab503a5354a2e6f97872be0b938c325387313
commit f12ab503a5354a2e6f97872be0b938c325387313 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Sat Apr 16 22:40:12 2016 +0200 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Sat Apr 16 22:40:12 2016 +0200 basic implementation of egg-tree compilation diff --git a/egg-compile.scm b/egg-compile.scm index 7e625661..644e0618 100644 --- a/egg-compile.scm +++ b/egg-compile.scm @@ -11,10 +11,10 @@ '(synopsis authors category license version dependencies files source-file csc-options test-dependencies destination linkage build-dependencies components foreign-dependencies link-options - custom-bulild)) + custom-bulild target host)) (define nested-items - '(components)) + '(components target host)) (define named-items '(extension program data c-include scheme-include)) @@ -31,11 +31,10 @@ (define windows-executable-extension ".exe") (define unix-object-extension ".o") (define windows-object-extension ".obj") - -;XXX (define staticbuild (foreign-value "STATICBUILD" bool)) -(define staticbuild #f) +;;; validate egg-information tree + (define (validate-egg-info info) (unless (list? info) (error "egg-information has invalid structure")) @@ -52,7 +51,36 @@ (if (memq (car item) named-items) (cddr item) (cdr item)))))) info)) -(define (compile-egg-info info platform) + +;;; some utilities + +(define (object-extension platform) + (case platform + ((unix) unix-object-extension) + ((windows) windows-object-extension))) + +(define (executable-extension platform) + (case platform + ((unix) unix-executable-extension) + ((windows) windows-executable-extension))) + +(define (install-command platform) + (case platform + ((unix) "cp") + ((windows) "copy /y"))) + +(define (destination-repository mode) + (case mode + ((target) target-repo) + ((host) host-repo))) + +(define (uses-compiled-import-library? mode) + (not (and (eq? mode 'host) staticbuild))) + + +;;; compile an egg-information tree into abstract build/install operations + +(define (compile-egg-info info platform mode) (let ((exts '()) (prgs '()) (data '()) @@ -68,8 +96,8 @@ (deps '()) (lopts '()) (opts '()) - (objext #f) - (exeext #t)) + (objext (object-extension platform)) + (exeext (executable-extension platform))) (define (check-target t lst) (when (member t lst) (error "target multiply defined" t)) @@ -79,6 +107,8 @@ files) (define (compile-component info) (case (car info) + ((target) (when (eq? mode 'target) (for-each compile-component (cdr info)))) + ((host) (when (eq? mode 'host) (for-each compile-component (cdr info)))) ((extension) (fluid-let ((target (check-target (cadr info) exts)) (deps '()) @@ -94,7 +124,11 @@ (if staticbuild (conc target ".import.scm") (conc target ".import.so"))) - (set! exts (cons (list target deps src opts lopts link cbuild) exts)))) + (set! exts + (cons (list target dependencies: deps source: src options: opts + link-options: lopts linkage: link custom: cbuild + mode: mode) + exts)))) ((data) (fluid-let ((target (check-target (cadr info) data)) (dest #f) @@ -102,7 +136,10 @@ (for-each compile-data/include (cddr info)) (let ((dest (normalize-pathname (conc dest "/")))) (for-each addfiles (map (cut conc dest <>) files))) - (set! data (cons (list target '() files dest) data)))) + (set! data + (cons (list target dependencies: '() files: files + destination: dest mode: mode) + data)))) ((c-include) (fluid-let ((target (check-target (cadr info) cinc)) (dest #f) @@ -110,7 +147,10 @@ (for-each compile-data/include (cddr info)) (let ((dest (normalize-pathname (conc dest "/")))) (for-each addfiles (map (cut conc dest <>) files))) - (set! cinc (cons (list target '() files dest) cinc)))) + (set! cinc + (cons (list target dependencies: '() files: files + destination: dest mode: mode) + cinc)))) ((scheme-include) (fluid-let ((target (check-target (cadr info) scminc)) (dest #f)) @@ -118,7 +158,10 @@ (for-each compile-data/include (cddr info)) (let ((dest (normalize-pathname (conc dest "/")))) (for-each addfiles (map (cut conc dest <>) files))) - (set! scminc (cons (list target '() files dest) scminc))) + (set! scminc + (cons (list target dependencies: '() files: files + destination: dest mode: mode) + scminc))) ((program) (fluid-let ((target (check-target (cadr info) prgs)) (deps '()) @@ -129,9 +172,17 @@ (opts '())) (for-each compile-extension/program (cddr info)) (addfiles (conc target exeext)) - (set! prgs (cons (list target deps src opts lopts link cbuild) prgs)))))) + (set! prgs + (cons (list target dependencies: deps source: src options: opts + link-options: lopts linkage: link custom: cbuild + mode: mode) + prgs)))))) (define (compile-extension/program info) (case (car info) + ((target) + (when (eq? mode 'target) (for-each compile-extension/program (cdr info)))) + ((host) + (when (eq? mode 'host) (for-each compile-extension/program (cdr info)))) ((linkage) (set! link (cdr info))) ((custom-build) @@ -146,6 +197,8 @@ (set! deps (append deps (map ->dep (cdr info))))))) (define (compile-data/include info) (case (car info) + ((target) (when (eq? mode 'target) (for-each compile-data/include (cdr info)))) + ((host) (when (eq? mode 'host) (for-each compile-data/include (cdr info)))) ((destination) (set! dest (->string (arg info 1 name?)))) ((files) @@ -154,6 +207,8 @@ (if (name? x) x (error "invalid dependency" x))) (define (compile info) (case (car info) + ((target) (when (eq? mode 'target) (for-each compile (cdr info)))) + ((host) (when (eq? mode 'host) (for-each compile (cdr info)))) ((components) (for-each compile-component (cdr info))))) (define (arg info n #!optional (pred (constantly #t))) (when (< (length info) n) @@ -177,13 +232,6 @@ (assq dep scminc) (error "unknown component dependency" dep name)))) deps)) - (case platform - ((unix) - (set! objext unix-object-extension) - (set! exeext unix-executable-extension)) - ((windows) - (set! objext windows-object-extension) - (set! exeext windows-executable-extension))) ;; collect information (for-each compile info) ;; sort topologically, by dependencies @@ -191,7 +239,9 @@ (topological-sort (map (lambda (dep) (cons (car dep) - (filter-deps (car dep) (cadr dep)))) + (filter-deps + (car dep) + (get-keyword dependencies: (cdr dep))))) exts) dep=?)))) ;; generate + return build/install commands @@ -201,7 +251,7 @@ (foldr (lambda (t cmds) (let* ((data (assq t exts)) - (link (list-ref data 5))) + (link (get-keyword linkage: (cdr data)))) (append (if (memq 'static link) `((compile-static-extension ,@data)) @@ -209,12 +259,14 @@ (if (memq 'dynamic link) `((compile-dynamic-extension ,@data)) '()) - `((compile-import-library ,@data)) + (if (uses-compiled-import-library? mode) + `((compile-import-library ,@data)) + '()) cmds))) '() order) (foldr (lambda (prg cmds) - (let ((link (list-ref prg 5))) + (let ((link (get-keyword linkage: (cdr prg)))) (append (if (memq 'static link) `((compile-static-program ,@prg)) @@ -227,7 +279,22 @@ prgs)) ;; installation commands (append - (map (lambda (ext) `(install-extension ,@ext)) exts) + (append-map + (lambda (ext) + (let ((link (get-keyword linkage: (cdr ext)))) + (if (memq 'static link) + `((install-static-extension ,@ext)) + '()) + (if (memq 'dynamic link) + `((install-dynamic-extension ,@ext)) + '()))) + exts) + (append-map + (lambda (ext) + (if (uses-compiled-import-library? (get-keyword mode: ext)) + `((install-import-library ,@ext)) + '())) + exts) (map (lambda (prg) `(install-program ,@prg)) prgs) (map (lambda (data) `(install-data ,@data)) data) (map (lambda (cinc) `(install-c-include ,@cinc)) cinc) @@ -236,51 +303,114 @@ (cons `(installed-files ,@ifiles) info))))) -;;; shell code generation - -(define (gen-compile-static-extension platform name deps src opts lopts link cbuild) - ...) - -(define (gen-compile-dynamic-extension platform name deps src opts lopts link cbuild) - ...) - -(define (gen-compile-import-library platform name deps src opts lopts link cbuild) - ...) - -(define (gen-compile-dynamic-program platform name deps src opts lopts link cbuild) - ...) - -(define (gen-compile-static-program platform name deps src opts lopts link cbuild) - ...) - -(define (gen-install-extension platform name deps src opts lopts link cbuild) - ...) - -(define (gen-install-program platform name deps src opts lopts link cbuild) - ...) - -(define (gen-install-data platform name deps files dest) - ...) - -(define (gen-install-c-include platform name deps files dest) - ...) - -(define (gen-install-scheme-include platform name deps files dest) - ...) +;;; shell code generation - build operations + +(define (gen-compile-static-extension name #!key mode platform dependencies source + 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) " " 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) + (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) " " out " " cmd (arglist options) + (arglist link-options) " " src " -o " out " : " + src (arglist dependencies)))) + +(define (gen-compile-import-library name #!key platform dependencies source kmode + 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) " " 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) + (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) " " 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) + (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) " " 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)) + (ext (object-extension platform)) + (out (quotearg (target-file (conc name ext) mode))) + (dest (destination-repository mode))) + (conc cmd " " out " " (quotearg (conc dest "/" name ext))))) + +(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 (conc dest "/" name ".so"))))) + +(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 (conc dest "/" name ".import.so"))))) + +(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 (destination-repository mode))) + (conc cmd " " out " " (quotearg (conc dest "/" name ext))))) + +(define (gen-install-data name #!key platform files destination) + (let* ((cmd (install-command platform)) + (dest (or dest (if (eq? mode 'target) target-sharedir host-sharedir)))) + (conc cmd (arglist files) " " (quotearg dest)))) + +(define (gen-install-c-include name #!key platform deps files dest) + (let* ((cmd (install-command platform)) + (dest (or dest (if (eq? mode 'target) target-incdir host-incdir)))) + (conc cmd " " (arglist files) " " (quotearg dest)))) (define command-table `((compile-static-extension ,gen-compile-static-extension) (compile-dynamic-extension ,gen-compile-dynamic-extension) (compile-dynamic-program ,gen-compile-dynamic-program) (compile-static-program ,gen-compile-static-program) - (install-extension ,gen-install-extension) + (install-static-extension ,gen-install-static-extension) + (install-dynamic-extension ,gen-install-dynamic-extension) + (install-import-library ,gen-install-import-library) (install-data ,gen-install-data) (compile-import-library ,gen-compile-import-library) (install-data ,gen-install-data) (install-c-include ,gen-install-c-include) - (install-scheme-include ,gen-install-scheme-include) + (install-scheme-include ,gen-install-data))) ;; might be extended +;;; Generate shell or batch commands from abstract build/install operations + (define (generate-shell-commands platform cmds dest prefix suffix) (with-output-to-file dest (lambda () @@ -288,7 +418,8 @@ (for-each (lambda (cmd) (cond ((assq (car cmd) command-table) - => (lambda (op) (apply (cadr op) platform (cdr cmd)))) + => (lambda (op) + (apply (cadr op) (cons* platform: platform (cddr cmd))))) (else (error "invalid command" cmd)))) cmds) (suffix)))) @@ -298,7 +429,7 @@ (define (quotearg str) (let ((lst (string->list str))) - (if (foldl char-whitespace? #f lst) + (if (any char-whitespace? lst) (string-append "\"" str "\"") str))) @@ -315,8 +446,14 @@ (string-append "\"" str "\"") str)) +(define (target-file fname mode) + (if (eq? mode 'target) (string-append fname ".target") fname)) + +(define (arglist lst) + (apply conc (map (lambda (x) (conc " " (quotearg x))) lst))) + ;; (set! hyde (with-input-from-file "hyde.egg" read)) -(pp (receive (compile-egg-info hyde 'unix))) +(pp (receive (compile-egg-info hyde 'unix 'host)))Trap