unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH 0/12]: Add asdf-build-system.
@ 2016-09-27  4:15 Andy Patterson
  2016-09-27  4:15 ` [PATCH 01/12] build-system: " Andy Patterson
                   ` (15 more replies)
  0 siblings, 16 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

Hello,

As promised, here's my work toward adding a build system for Common Lisp
software. I still have some issues with it as follows:

Getting things to work "out of the box": I'd like to set up an environment
variable to allow implementations to find installed libraries, but it's a bit
tricky:

Essentially I'd like to have, in each profile, a setup something like

export CL_SOURCE_FRAGMENT=#+sbcl \
  (:directory \"${GUIX_PROFILE}/share/common-lisp/sbcl-bundle-systems/\") \
  #+ecl ... \
  ${CL_SOURCE_FRAGMENT}

followed by

export CL_SOURCE_REGISTRY=\
  (:source-registry ${CL_SOURCE_FRAGMENT} \
  (:directory \"${GUIX_PROFILE}/share/common-lisp/systems/\") \
  :inherit-configuration)

This would allow each implementation to pick up their own compiled libraries,
as well as systems installed as source as a fallback. I don't know how to
achieve that kind of a setup, so I'd like some help. I'm also worried about
either blowing away user configuration, or having it shadow the desired
configuration, since this isn't a simple search path which could be appended
to. Should we try to patch the asdf implementations to handle a separate
variable just for guix?

I'd also like to hear your thoughts on how packages are laid out using the
system, so I've included some examples. I was thinking that something like
package-with-python2 could also be helpful here; is that the right way
forward?

Thanks.

--
Andy

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH 01/12] build-system: Add asdf-build-system.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 02/12] gnu: Add alexandria Andy Patterson
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* guix/build-system/asdf.scm: New file.
* guix/build/asdf-build-system.scm: New file.
* guix/build/lisp-utils.scm: New file.
* Makefile.am: Add them.
* doc/guix.texi: Add section on 'asdf-build-system/source'.
---
 Makefile.am                      |   3 +
 doc/guix.texi                    |  53 +++++
 guix/build-system/asdf.scm       | 231 ++++++++++++++++++++++
 guix/build/asdf-build-system.scm | 417 +++++++++++++++++++++++++++++++++++++++
 guix/build/lisp-utils.scm        | 240 ++++++++++++++++++++++
 5 files changed, 944 insertions(+)
 create mode 100644 guix/build-system/asdf.scm
 create mode 100644 guix/build/asdf-build-system.scm
 create mode 100644 guix/build/lisp-utils.scm

diff --git a/Makefile.am b/Makefile.am
index 43a33c8..a23e5fd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -63,6 +63,7 @@ MODULES =					\
   guix/build-system/ant.scm			\
   guix/build-system/cmake.scm			\
   guix/build-system/emacs.scm			\
+  guix/build-system/asdf.scm			\
   guix/build-system/glib-or-gtk.scm		\
   guix/build-system/gnu.scm			\
   guix/build-system/haskell.scm			\
@@ -84,6 +85,7 @@ MODULES =					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
   guix/build/emacs-build-system.scm		\
+  guix/build/asdf-build-system.scm		\
   guix/build/git.scm				\
   guix/build/hg.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
@@ -106,6 +108,7 @@ MODULES =					\
   guix/build/syscalls.scm                       \
   guix/build/gremlin.scm			\
   guix/build/emacs-utils.scm			\
+  guix/build/lisp-utils.scm			\
   guix/build/graft.scm				\
   guix/build/bournish.scm			\
   guix/build/qt-utils.scm			\
diff --git a/doc/guix.texi b/doc/guix.texi
index 808fbdc..8e9b510 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2965,6 +2965,59 @@ that should be run during the @code{build} phase.  By default the
 
 @end defvr
 
+@defvr {Scheme Variable} asdf-build-system/source
+@defvrx {Scheme Variable} asdf-build-system/sbcl
+@defvrx {Scheme Variable} asdf-build-system/ecl
+
+These variables, exported by @code{(guix build-system sbcl)}, implement
+build procedures for Common Lisp packages using the
+@url{https://common-lisp.net/project/asdf/, ``ASDF''} system.
+
+The @code{asdf-build-system/source} system installs the packages in
+source form, and can be loaded using any common lisp implementation, via
+ASDF. The others, such as @code{asdf-build-system/sbcl}, install binary
+systems in the format which a particular implementation
+understands. These build systems can also be used to produce executable
+programs, or lisp images which contain a set of packages pre-loaded.
+
+The build system uses conventions to determine the roles of inputs in
+the build system. For binary packages, the package itself as well as its
+dependencies should end their name with the lisp implementation, such as
+@code{-sbcl} for @code{asdf-build-system/sbcl}. Additionally, the
+corresponding source package should be labelled using the same name as
+the package, but with this suffix dropped. If it cannot be labelled that
+way, the label can be overriden by the @code{#:source-input} parameter.
+
+One package should be defined for each ASDF system.
+
+The package outputs control whether or not executable programs and
+images are built alongside the package's usual output, using the
+@code{bin} and @code{image} outputs, respectively.
+
+Packages can also be built which combine other packages into an
+executable program or image only, without building another
+system. Specifying one of the @code{#:binary?} or @code{#:image?}
+parameters will produce this behaviour.
+
+When building an executable program, the @code{#:entry-program}
+parameter, which should be a list of Common Lisp expressions, must be
+used to specify what program should be run. In this program,
+@code{arguments} will be bound to the command-line arguments passed.
+
+The @code{#:image-dependencies} parameter can be used to add packages to
+the pre-loaded systems included in the executable program or
+image. @code{#:compile-dependencies} specifies a list of additional
+systems which should be loaded before a system is compiled. If the
+package depends on special systems exported by the implementation
+itself, the @code{#:special-dependencies} parameter should be used to
+specify them.
+
+If a package must modify its source while building, the
+@code{build-in-tree} parameter can specify an output in which the source
+will be stored after the package has been built.
+
+@end defvr
+
 @defvr {Scheme Variable} cmake-build-system
 This variable is exported by @code{(guix build-system cmake)}.  It
 implements the build procedure for packages using the
diff --git a/guix/build-system/asdf.scm b/guix/build-system/asdf.scm
new file mode 100644
index 0000000..401708f
--- /dev/null
+++ b/guix/build-system/asdf.scm
@@ -0,0 +1,231 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build-system asdf)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix packages)
+  #:use-module (guix derivations)
+  #:use-module (guix search-paths)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build asdf-build-system)
+  #:use-module (ice-9 match)
+  #:use-module (srfi srfi-26)
+  #:export (%asdf-build-system-modules
+            asdf-build
+            asdf-build-system/sbcl
+            asdf-build-system/ecl
+            asdf-build-system/source))
+
+;; Commentary:
+;;
+;; Standard build procedure for asdf packages.  This is implemented as an
+;; extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define %asdf-build-system-modules
+  `((guix build asdf-build-system)
+    (guix build lisp-utils)
+    ,@%gnu-build-system-modules))
+
+(define (default-lisp implementation)
+  "Return the default package for the lisp IMPLEMENTATION."
+  ;; Lazily resolve the binding to avoid a circular dependancy.
+  (let ((lisp-module (resolve-interface '(gnu packages lisp))))
+    (module-ref lisp-module implementation)))
+
+(define* (lower/source name
+                       #:key source inputs outputs native-inputs system target
+                       #:allow-other-keys
+                       #:rest arguments)
+  "Return a bag for NAME"
+  (define private-keywords
+    '(#:target #:inputs #:native-inputs))
+
+  (and (not target)
+       (bag
+         (name name)
+         (system system)
+         (host-inputs `(,@(if source
+                              `(("source" ,source))
+                              '())
+                        ,@inputs
+                        ,@(standard-packages)))
+         (build-inputs native-inputs)
+         (outputs outputs)
+         (build asdf-build/source)
+         (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define* (asdf-build/source store name inputs
+                            #:key source outputs
+                            (phases '(@ (guix build asdf-build-system)
+                                        %standard-phases/source))
+                            (search-paths '())
+                            (system (%current-system))
+                            (guile #f)
+                            (imported-modules %asdf-build-system-modules)
+                            (modules '((guix build asdf-build-system)
+                                       (guix build utils)
+                                       (guix build lisp-utils))))
+  (define builder
+    `(begin
+       (use-modules ,@modules)
+       (asdf-build/source #:name ,name
+                          #:source ,(match (assoc-ref inputs "source")
+                                      (((? derivation? source))
+                                       (derivation->output-path source))
+                                      ((source) source)
+                                      (source source))
+                          #:system ,system
+                          #:phases ,phases
+                          #:outputs %outputs
+                          #:search-paths ',(map search-path-specification->sexp
+                                                search-paths)
+                          #:inputs %build-inputs)))
+
+  (define guile-for-build
+    (match guile
+      ((? package?)
+       (package-derivation store guile system #:graft? #f))
+      (#f
+       (let* ((distro (resolve-interface '(gnu packages commencement)))
+              (guile (module-ref distro 'guile-final)))
+         (package-derivation store guile system #:graft? #f)))))
+
+  (build-expression->derivation store name builder
+                                #:inputs inputs
+                                #:system system
+                                #:modules imported-modules
+                                #:outputs outputs
+                                #:guile-for-build guile-for-build))
+
+
+(define (lower lisp-implementation)
+  (lambda* (name
+            #:key source inputs outputs native-inputs system target
+            (lisp (default-lisp (string->symbol lisp-implementation)))
+            #:allow-other-keys
+            #:rest arguments)
+    "Return a bag for NAME"
+    (define private-keywords
+      '(#:target #:inputs #:native-inputs))
+
+    (and (not target)
+         (bag
+           (name name)
+           (system system)
+           (host-inputs `(,@(if source
+                                `(("source" ,source))
+                                '())
+                          ,@inputs
+                          ,@(standard-packages)))
+           (build-inputs `((,lisp-implementation ,lisp)
+                           ,@native-inputs))
+           (outputs outputs)
+           (build (asdf-build lisp-implementation))
+           (arguments (strip-keyword-arguments private-keywords arguments))))))
+
+(define (asdf-build lisp-implementation)
+  (lambda* (store name inputs
+                  #:key source outputs
+                  (tests? #t)
+                  (special-dependencies ''())
+                  (entry-program #f)
+                  (image-dependencies ''())
+                  (compile-dependencies ''())
+                  (source-input #f)
+                  (build-in-tree #f)
+                  (image? #f)
+                  (binary? #f)
+                  (test-only-systems ''())
+                  (lisp lisp-implementation)
+                  (phases `(@ (guix build asdf-build-system)
+                              ,(string->symbol
+                                (string-append "%standard-phases/" lisp))))
+                  (search-paths '())
+                  (system (%current-system))
+                  (guile #f)
+                  (imported-modules %asdf-build-system-modules)
+                  (modules '((guix build asdf-build-system)
+                             (guix build utils)
+                             (guix build lisp-utils))))
+
+    (define builder
+      `(begin
+         (use-modules ,@modules)
+         (asdf-build #:name ,name
+                     #:source ,(match (assoc-ref inputs "source")
+                                 (((? derivation? source))
+                                  (derivation->output-path source))
+                                 ((source) source)
+                                 (source source))
+                     #:lisp ,lisp
+                     #:special-dependencies ,special-dependencies
+                     #:entry-program ,entry-program
+                     #:image-dependencies ,image-dependencies
+                     #:compile-dependencies ,compile-dependencies
+                     #:source-input ,source-input
+                     #:build-in-tree ,build-in-tree
+                     #:image? ,image?
+                     #:binary? ,binary?
+                     #:test-only-systems ,test-only-systems
+                     #:system ,system
+                     #:tests? ,tests?
+                     #:phases ,phases
+                     #:outputs %outputs
+                     #:search-paths ',(map search-path-specification->sexp
+                                           search-paths)
+                     #:inputs %build-inputs)))
+
+    (define guile-for-build
+      (match guile
+        ((? package?)
+         (package-derivation store guile system #:graft? #f))
+        (#f
+         (let* ((distro (resolve-interface '(gnu packages commencement)))
+                (guile (module-ref distro 'guile-final)))
+           (package-derivation store guile system #:graft? #f)))))
+
+    (build-expression->derivation store name builder
+                                  #:inputs inputs
+                                  #:system system
+                                  #:modules imported-modules
+                                  #:outputs outputs
+                                  #:guile-for-build guile-for-build)))
+
+(define asdf-build-system/sbcl
+  (build-system
+    (name 'asdf/sbcl)
+    (description "The build system for asdf binary packages using sbcl")
+    (lower (lower "sbcl"))))
+
+(define asdf-build-system/ecl
+  (build-system
+    (name 'asdf/ecl)
+    (description "The build system for asdf binary packages using ecl")
+    (lower (lower "ecl"))))
+
+(define asdf-build-system/source
+  (build-system
+    (name 'asdf/source)
+    (description "The build system for asdf source packages")
+    (lower lower/source)))
+
+;;; asdf.scm ends here
diff --git a/guix/build/asdf-build-system.scm b/guix/build/asdf-build-system.scm
new file mode 100644
index 0000000..7229f32
--- /dev/null
+++ b/guix/build/asdf-build-system.scm
@@ -0,0 +1,417 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build asdf-build-system)
+  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+  #:use-module (guix build utils)
+  #:use-module (guix build lisp-utils)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 receive)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 format)
+  #:export (%standard-phases/sbcl
+            %standard-phases/ecl
+            %standard-phases/source
+            asdf-build
+            asdf-build/source))
+
+;; Commentary:
+;;
+;; System for building ASDF packages; creating executable programs and images
+;; from them.
+;;
+;; Code:
+
+(define %object-prefix "/lib")
+
+(define %source-install-prefix
+  (string-append %install-prefix "/source"))
+
+(define %system-install-prefix
+  (string-append %install-prefix "/systems"))
+
+(define (output-path->package-name path)
+  (package-name->name+version (strip-store-file-name path)))
+
+(define (outputs->name outputs)
+  (output-path->package-name
+   (assoc-ref outputs "out")))
+
+(define (wrap-source-registry registry)
+  `(:source-registry
+    ,@registry
+    :inherit-configuration))
+
+(define (wrap-output-translations translations)
+  `(:output-translations
+    ,@translations
+    :inherit-configuration))
+
+(define (source-directory output name)
+  (string-append output %source-install-prefix "/" name))
+
+(define (library-directory output lisp)
+  (string-append output %object-prefix
+                 "/" lisp))
+
+(define (output-translation source-output
+                            source-name
+                            object-output
+                            lisp)
+  "Return a translation for the system's source output
+to it's binary output."
+  `((,(source-directory source-output source-name)
+     :**/ :*.*.*)
+    (,(library-directory object-output lisp)
+     :**/ :*.*.*)))
+
+(define (source-registry source-path)
+  `(:tree ,source-path))
+
+(define (lisp-dependency-names lisp inputs)
+  (map first (lisp-dependencies lisp inputs)))
+
+(define (copy-files-to-output outputs output name)
+  "Copy all files from OUTPUT to \"out\". Create an extra link to any
+system-defining files in the source to a convenient location. This is done
+before any compiling so that the compiled source locations will be valid."
+  (let* ((out (assoc-ref outputs output))
+         (source (getcwd))
+         (target (source-directory out name))
+         (system-path (string-append out %system-install-prefix)))
+    (copy-recursively source target)
+    (mkdir-p system-path)
+    (for-each
+     (lambda (file)
+       (symlink file
+                (string-append system-path "/" (basename file))))
+     (find-files target "\\.asd$"))
+    #t))
+
+(define* (install #:key outputs #:allow-other-keys)
+  "Copy and symlink all the source files."
+  (copy-files-to-output outputs "out" (outputs->name outputs)))
+
+(define* (copy-source #:key outputs build-in-tree lisp
+                      image? binary?
+                      #:allow-other-keys)
+  "Copy the source to the output named by BUILD-IN-TREE."
+  (when (and build-in-tree (not image?) (not binary?))
+    (let* ((out (assoc-ref outputs "out"))
+           (name (remove-lisp-from-name (output-path->package-name out) lisp)))
+      (copy-files-to-output outputs build-in-tree name)))
+  #t)
+
+(define* (build #:key outputs inputs lisp
+                compile-dependencies
+                source-input
+                build-in-tree
+                image?
+                binary?
+                #:allow-other-keys)
+  "Compile the system."
+
+  (unless (or binary? image?)
+    (let* ((out (assoc-ref outputs "out"))
+           (name (remove-lisp-from-name (output-path->package-name out) lisp))
+           (source (cond
+                    (source-input
+                     (assoc-ref inputs source-input))
+                    (build-in-tree (assoc-ref outputs build-in-tree))
+                    (else (assoc-ref inputs name))))
+           (source-name (or source-input name))
+           (source-path (string-append source %source-install-prefix "/"
+                                       source-name))
+           (translations (wrap-output-translations
+                          `(,(output-translation source
+                                                 source-name
+                                                 out
+                                                 lisp))))
+           (registry (map (match-lambda
+                            ((_ . path) (source-registry path)))
+                          (lisp-dependencies lisp inputs))))
+
+      (setenv "ASDF_OUTPUT_TRANSLATIONS"
+              (replace-escaped-macros (format #f "~S" translations)))
+      (setenv "CL_SOURCE_REGISTRY"
+              (replace-escaped-macros
+               (format #f "~S" (wrap-source-registry
+                                `(,(source-registry source-path)
+                                  ,@registry)))))
+
+      (setenv "HOME" out) ; ecl's asdf sometimes wants to create $HOME/.cache
+
+      (parameterize ((%lisp (string-append
+                             (assoc-ref inputs lisp) "/bin/" lisp)))
+        (compile-system name lisp compile-dependencies))
+
+      ;; As above, ecl will sometimes create this even though it doesn't use it
+
+      (let ((cache-directory (string-append out "/.cache")))
+        (when (directory-exists? cache-directory)
+          (delete-file-recursively cache-directory)))))
+  #t)
+
+(define* (check #:key lisp tests? outputs inputs
+                compile-dependencies
+                image?
+                binary?
+                #:allow-other-keys)
+  "Test the system."
+
+  (if (and tests? (not image?) (not binary?))
+      (parameterize ((%lisp (string-append
+                             (assoc-ref inputs lisp) "/bin/" lisp)))
+        (test-system
+         (remove-lisp-from-name (outputs->name outputs) lisp)
+         lisp
+         compile-dependencies))
+      (format #t "test suite not run~%"))
+  #t)
+
+(define* (patch-asd-files #:key outputs
+                          inputs
+                          lisp
+                          special-dependencies
+                          image?
+                          binary?
+                          test-only-systems
+                          #:allow-other-keys)
+  "Patch any asd files created by the compilation process so that they
+can find their dependencies. Exclude any TEST-ONLY-SYSTEMS which were only
+included to run tests. Add any SPECIAL-DEPENDENCIES which the LISP
+implementation itself provides."
+  (unless (or image? binary?)
+    (let* ((out (assoc-ref outputs "out"))
+           (name (remove-lisp-from-name (output-path->package-name out) lisp))
+           (registry (lset-difference
+                      (lambda (input system)
+                        (match input
+                          ((name . path) (string=? name system))))
+                      (lisp-dependencies lisp inputs)
+                      test-only-systems))
+           (lisp-systems (map first registry)))
+
+      (for-each
+       (lambda (asd-file)
+         (patch-asd-file asd-file registry lisp
+                         (append lisp-systems special-dependencies)))
+       (find-files out "\\.asd$"))))
+  #t)
+
+(define* (symlink-asd-files #:key outputs lisp
+                            image? binary?
+                            #:allow-other-keys)
+  "Create an extra reference to the system in a convenient location."
+  (unless (or image? binary?)
+    (let* ((out (assoc-ref outputs "out")))
+      (for-each
+       (lambda (asd-file)
+         (receive (new-asd-file asd-file-directory)
+             (bundle-asd-file out asd-file lisp)
+           (mkdir-p asd-file-directory)
+           (symlink asd-file new-asd-file)))
+
+       (find-files out "\\.asd$"))))
+  #t)
+
+(define* (generate-binary #:key outputs
+                          inputs
+                          image-dependencies
+                          entry-program
+                          lisp
+                          binary?
+                          #:allow-other-keys)
+  "Generate a binary program for the system, either in \"bin\" if the package
+also contains a library system, or in \"out\" otherwise."
+  (define output (if binary? "out" "bin"))
+  (generate-executable #:outputs outputs
+                       #:inputs inputs
+                       #:image-dependencies image-dependencies
+                       #:entry-program entry-program
+                       #:lisp lisp
+                       #:output output
+                       #:needs-own-system? (not binary?)
+                       #:type "program")
+  (and=>
+   (assoc-ref outputs output)
+   (lambda (bin)
+     (let* ((full-name (outputs->name outputs))
+            (name (if binary? full-name
+                      (remove-lisp-from-name full-name lisp)))
+            (bin-directory (string-append bin "/bin")))
+       (with-directory-excursion bin-directory
+         (rename-file (string-append name "-exec")
+                      name)))))
+  #t)
+
+(define* (generate-image #:key outputs
+                         inputs
+                         image-dependencies
+                         lisp
+                         image?
+                         #:allow-other-keys)
+  "Generate an image for the system, possibly standalone, either in \"image\"
+if the package also contains a library system, or in \"out\" otherwise."
+  (define output (if image? "out" "image"))
+  (generate-executable #:outputs outputs
+                       #:inputs inputs
+                       #:image-dependencies image-dependencies
+                       #:entry-program '(nil)
+                       #:lisp lisp
+                       #:output output
+                       #:needs-own-system? (not image?)
+                       #:type "image")
+  (and=>
+   (assoc-ref outputs output)
+   (lambda (image)
+     (let* ((full-name (outputs->name outputs))
+            (name (if image? full-name
+                      (remove-lisp-from-name full-name lisp)))
+            (bin-directory (string-append image "/bin")))
+       (with-directory-excursion bin-directory
+         (rename-file (string-append name "-exec--all-systems.image")
+                      (string-append name ".image"))))))
+  #t)
+
+(define* (generate-executable #:key outputs
+                              image-dependencies
+                              entry-program
+                              lisp
+                              output
+                              inputs
+                              type
+                              needs-own-system?
+                              #:allow-other-keys)
+  "Generate an executable by using asdf's TYPE-op, containing whithin the
+image all IMAGE-DEPNDENCIES, and running ENTRY-PROGRAM in the case of an
+executable."
+  (and=>
+   (assoc-ref outputs output)
+   (lambda (out)
+     (let* ((bin-directory (string-append out "/bin"))
+            (full-name (outputs->name outputs))
+            (name (if needs-own-system?
+                      (remove-lisp-from-name full-name lisp)
+                      full-name)))
+       (mkdir-p out)
+       (with-directory-excursion out
+         (generate-executable-wrapper-system name
+                                             image-dependencies
+                                             needs-own-system?)
+         (generate-executable-entry-point name entry-program))
+
+       (setenv "CL_SOURCE_REGISTRY"
+               (replace-escaped-macros
+                (format
+                 #f "~S"
+                 (wrap-source-registry
+                  `(,(source-registry (assoc-ref outputs "out"))
+                    ,(source-registry out)
+                    ,@(map (lambda (dependency)
+                             (source-registry (assoc-ref inputs dependency)))
+                           image-dependencies))))))
+
+       (setenv "ASDF_OUTPUT_TRANSLATIONS"
+               (replace-escaped-macros
+                (format
+                 #f "~S"
+                 (wrap-output-translations
+                  `(((,out :**/ :*.*.*)
+                     (,bin-directory :**/ :*.*.*)))))))
+
+       (parameterize ((%lisp (string-append
+                              (assoc-ref inputs lisp) "/bin/" lisp)))
+         (generate-executable-for-system type name lisp))
+
+       (delete-file (string-append out "/" name "-exec.asd"))
+       (delete-file (string-append out "/" name "-exec.lisp"))))))
+
+(define* (cleanup-files/sbcl #:key outputs binary? image? lisp
+                             #:allow-other-keys)
+  "Remove any compiled files which are not a part of the final bundle."
+  (unless (or binary? image?)
+    (let ((out (assoc-ref outputs "out")))
+      (for-each
+       (lambda (file)
+         (unless (string-suffix? "--system.fasl" file)
+           (delete-file file)))
+       (find-files out "\\.fasl$"))))
+  #t)
+
+(define* (cleanup-files/ecl #:key outputs binary? image?
+                             #:allow-other-keys)
+  "Remove any compiled files which are not a part of the final bundle."
+  (unless (or binary? image?)
+    (let ((out (assoc-ref outputs "out")))
+      (for-each delete-file
+                (append (find-files out "\\.fas$")
+                        (find-files out "\\.o$")))))
+  #t)
+
+(define %standard-phases/source
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'check)
+    (delete 'build)
+    (replace 'install install)))
+
+(define %standard-phases
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'install)
+    (replace 'build build)
+    (add-before 'build 'copy-source copy-source)
+    (replace 'check check)
+    (add-after 'check 'link-dependencies patch-asd-files)
+    (add-after 'link-dependencies 'create-symlinks symlink-asd-files)
+    (add-after 'create-symlinks 'cleanup cleanup-files/sbcl)
+    (add-after 'cleanup 'generate-binary generate-binary)
+    (add-after 'generate-binary 'generate-image generate-image)))
+
+(define %standard-phases/sbcl
+  (modify-phases %standard-phases
+    ;; stripping sbcl binaries removes their entry program and extra systems
+    (delete 'strip)))
+
+(define %standard-phases/ecl
+  (modify-phases %standard-phases
+    (replace 'cleanup cleanup-files/ecl)))
+
+(define* (asdf-build #:key inputs
+                     (phases %standard-phases)
+                     #:allow-other-keys
+                     #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+(define* (asdf-build/source #:key inputs
+                            (phases %standard-phases/source)
+                            #:allow-other-keys
+                            #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+;;; asdf-build-system.scm ends here
diff --git a/guix/build/lisp-utils.scm b/guix/build/lisp-utils.scm
new file mode 100644
index 0000000..33755f7
--- /dev/null
+++ b/guix/build/lisp-utils.scm
@@ -0,0 +1,240 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build lisp-utils)
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (%lisp
+            %install-prefix
+            lisp-eval-program
+            compile-system
+            test-system
+            replace-escaped-macros
+            generate-executable-wrapper-system
+            generate-executable-entry-point
+            generate-executable-for-system
+            patch-asd-file
+            bundle-install-prefix
+            lisp-dependencies
+            bundle-asd-file
+            remove-lisp-from-name))
+
+;;; Commentary:
+;;;
+;;; Tools to evaluate lisp programs within a lisp session, generate wrapper
+;;; systems for executables. Compile, test, and produce images for systems and
+;;; programs, and link them with their dependencies.
+;;;
+;;; Code:
+
+(define %lisp
+  (make-parameter "lisp"))
+
+(define %install-prefix "/share/common-lisp")
+
+(define (bundle-install-prefix lisp)
+  (string-append %install-prefix "/" lisp "-bundle-systems"))
+
+(define (remove-lisp-from-name name lisp)
+  (string-drop-right name (1+ (string-length lisp))))
+
+(define (lisp-eval-program lisp program)
+  "Evaluate PROGRAM with a given LISP implementation."
+  (unless (zero? (apply system*
+                        (lisp-invoke lisp (format #f "~S" program))))
+    (error "lisp-eval-program failed!" lisp program)))
+
+(define (lisp-invoke lisp program)
+  "Return a list of arguments for system* determining how to invoke LISP
+with PROGRAM."
+  (match lisp
+    ("sbcl" `(,(%lisp) "--non-interactive" "--eval" ,program))
+    ("ecl" `(,(%lisp) "-eval" ,program "-eval" "(quit)"))))
+
+(define (asdf-load-all systems)
+  (map (lambda (system)
+         `(funcall
+           (find-symbol
+            (symbol-name :load-system)
+            (symbol-name :asdf))
+           ,system))
+       systems))
+
+(define (compile-system system lisp other-required-systems)
+  "Use a lisp implementation to compile SYSTEM using asdf. Loads
+OTHER-REQUIRED-SYSTEMS before beginning compilation."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       ,@(asdf-load-all other-required-systems)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :compile-bundle-op)
+                                 (symbol-name :asdf))
+                                ,system)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :deliver-asd-op)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (test-system system lisp other-required-systems)
+  "Use a lisp implementation to test SYSTEM using asdf. Loads
+OTHER-REQUIRED-SYSTEMS before beginning to test."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       ,@(asdf-load-all other-required-systems)
+                       (funcall (find-symbol
+                                 (symbol-name :test-system)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (string->lisp-keyword . strings)
+  "Return a lisp keyword for the concatenation of STRINGS."
+  (string->symbol (apply string-append ":" strings)))
+
+(define (generate-executable-for-system type system lisp)
+  "Use LISP to generate an executable, whose TYPE can be \"image\"
+or \"program\". The latter will always be standalone. Depends on having
+created a \"SYSTEM-exec\" system which contains the entry program."
+  (lisp-eval-program
+   lisp
+   `(progn
+     (require :asdf)
+     (funcall (find-symbol
+               (symbol-name :operate)
+               (symbol-name :asdf))
+              (find-symbol
+               (symbol-name ,(string->lisp-keyword type "-op"))
+               (symbol-name :asdf))
+              ,(string-append system "-exec")))))
+
+(define (generate-executable-wrapper-system system
+                                            dependencies
+                                            needs-system?)
+  "Generates a system which can be used by asdf to produce an image or program
+inside the current directory. The image or program will contain SYSTEM and all
+other DEPENDENCIES, which may not be depended on by the SYSTEM itself. SYSTEM
+will be excluded unless NEEDS-SYSTEM? is #t."
+  (with-output-to-file (string-append system "-exec.asd")
+    (lambda _
+      (format #t "~y~%"
+              `(defsystem ,(string->lisp-keyword system "-exec")
+                 :entry-point ,(string-append system "-exec:main")
+                 :depends-on (:uiop
+                              ,@(if needs-system?
+                                    `(,(string->lisp-keyword system))
+                                    '())
+                              ,@(map string->lisp-keyword
+                                     dependencies))
+                 :components ((:file ,(string-append system "-exec"))))))))
+
+(define (generate-executable-entry-point system entry-program)
+  "Generates an entry point program from the list of lisp statements
+ENTRY-PROGRAM for SYSTEM within the current directory."
+  (with-output-to-file (string-append system "-exec.lisp")
+    (lambda _
+      (let ((system (string->lisp-keyword system "-exec")))
+        (format #t "~{~y~%~%~}"
+                `((defpackage ,system
+                    (:use :cl)
+                    (:export :main))
+
+                  (in-package ,system)
+
+                  (defun main ()
+                    (let ((arguments uiop:*command-line-arguments*))
+                      (declare (ignorable arguments))
+                      ,@entry-program))))))))
+
+(define (wrap-perform-method lisp registry dependencies file-name)
+  "Creates a wrapper method which allows the system to locate its dependent
+systems from REGISTRY, an alist of the same form as %outputs, which contains
+lisp systems which the systems is dependent on. All DEPENDENCIES which
+the system depends on will the be loaded before this system."
+  (let* ((system (string-drop-right (basename file-name) 4))
+         (system-symbol (string->lisp-keyword system)))
+
+    `(defmethod asdf:perform :before
+       (op (c (eql (asdf:find-system ,system-symbol))))
+       (asdf/source-registry:ensure-source-registry)
+       ,@(map (match-lambda
+                ((name . path)
+                 (let ((asd-file (string-append path
+                                                (bundle-install-prefix lisp)
+                                                "/" name ".asd")))
+                   `(setf
+                     (gethash ,name
+                              asdf/source-registry:*source-registry*)
+                     ,(string->symbol "#p")
+                     ,(bundle-asd-file path asd-file lisp)))))
+              registry)
+       ,@(map (lambda (system)
+                `(asdf:load-system ,(string->lisp-keyword system)))
+              dependencies))))
+
+(define (patch-asd-file asd-file registry lisp dependencies)
+  "Patches ASD-FILE with a perform method as described in WRAP-PERFORM-METHOD."
+  (chmod asd-file #o644)
+  (let ((port (open-file asd-file "a")))
+    (dynamic-wind
+      (lambda _ #t)
+      (lambda _
+        (display
+         (replace-escaped-macros
+          (format #f "~%~y~%"
+                  (wrap-perform-method lisp registry
+                                       dependencies asd-file)))
+         port))
+      (lambda _ (close-port port))))
+  (chmod asd-file #o444))
+
+(define (lisp-dependencies lisp inputs)
+  "Determine which inputs are lisp system dependencies, by using the convention
+that a lisp system dependency will resemble \"system-LISP\"."
+  (filter-map (match-lambda
+                ((name . value)
+                 (and (string-suffix? lisp name)
+                      (string<> lisp name)
+                      `(,(remove-lisp-from-name name lisp)
+                        . ,value))))
+              inputs))
+
+(define (bundle-asd-file output-path original-asd-file lisp)
+  "Find the symlinked bundle file for ORIGINAL-ASD-FILE by looking
+in OUTPUT-PATH/lib/LISP/<system>.asd. Returns two values: the asd
+file itself and the directory in which it resides."
+  (let ((bundle-asd-path (string-append output-path
+                                        (bundle-install-prefix lisp))))
+    (values (string-append bundle-asd-path "/" (basename original-asd-file))
+            bundle-asd-path)))
+
+(define (replace-escaped-macros string)
+  "Replace simple lisp forms that the guile writer escapes, for
+example by replacing #{#p}# with #p. Should only be used to replace
+truly simple forms which are not nested."
+  (regexp-substitute/global #f "(#\\{)(\\S*)(\\}#)" string
+                            'pre 2 'post))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 02/12] gnu: Add alexandria.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
  2016-09-27  4:15 ` [PATCH 01/12] build-system: " Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-10-08 12:43   ` Ludovic Courtès
  2016-09-27  4:15 ` [PATCH 03/12] gnu: Add fiveam Andy Patterson
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (alexandria, alexandria-sbcl, alexandria-ecl):
  New variables.
---
 gnu/packages/lisp.scm | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index d1180a7..e6e69a2 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -33,6 +33,7 @@
   #:use-module (guix git-download)
   #:use-module (guix utils)
   #:use-module (guix build-system gnu)
+  #:use-module (guix build-system asdf)
   #:use-module (gnu packages base)
   #:use-module (gnu packages multiprecision)
   #:use-module (gnu packages bdw-gc)
@@ -530,3 +531,40 @@ simple, elegant Scheme dialect.  It is a lisp-1 with lexical scope.
 The core is 12 builtin special forms and 33 builtin functions.")
       (home-page "https://github.com/JeffBezanson/femtolisp")
       (license license:bsd-3))))
+
+(define-public alexandria
+  (let ((revision "1")
+        (commit "926a066611b7b11cb71e26c827a271e500888c30"))
+    (package
+      (name "alexandria")
+      (version (string-append "0.0.0-" revision "." (string-take commit 7)))
+      (source (origin
+                (method git-fetch)
+                (uri
+                 (git-reference
+                  (url "https://gitlab.common-lisp.net/alexandria/alexandria.git")
+                  (commit commit)))
+                (sha256
+                 (base32 "18yncicdkh294j05rhgm23gzi36y9qy6vrfba8vg69jrxjp1hx8l"))
+                (file-name (string-append name "-" version "-checkout"))))
+      (build-system asdf-build-system/source)
+      (synopsis "Collection of portable utilities for Common Lisp")
+      (description "Alexandria is a collection of portable utilities.  It does
+not contain conceptual extensions to Common Lisp.  It is conservative in
+scope, and portable between implementations.")
+      (home-page "https://common-lisp.net/project/alexandria/")
+      (license license:public-domain))))
+
+(define-public alexandria-sbcl
+  (package
+    (inherit alexandria)
+    (name "alexandria-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("alexandria" ,alexandria)))))
+
+(define-public alexandria-ecl
+  (package
+    (inherit alexandria)
+    (name "alexandria-ecl")
+    (build-system asdf-build-system/ecl)
+    (inputs `(("alexandria" ,alexandria)))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 03/12] gnu: Add fiveam.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
  2016-09-27  4:15 ` [PATCH 01/12] build-system: " Andy Patterson
  2016-09-27  4:15 ` [PATCH 02/12] gnu: Add alexandria Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-10-08 12:48   ` Ludovic Courtès
  2016-09-27  4:15 ` [PATCH 04/12] gnu: Add bordeaux-threads Andy Patterson
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (fiveam, fiveam-sbcl, fiveam-ecl): New
  variables.
---
 gnu/packages/lisp.scm | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index e6e69a2..64bfc92 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -568,3 +568,43 @@ scope, and portable between implementations.")
     (name "alexandria-ecl")
     (build-system asdf-build-system/ecl)
     (inputs `(("alexandria" ,alexandria)))))
+
+(define-public fiveam
+  (package
+    (name "fiveam")
+    (version "1.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/sionescu/fiveam/archive/v"
+             version ".tar.gz"))
+       (sha256
+        (base32 "0f48pcbhqs3wwwzjl5nk57d4hcbib4l9xblxc66b8c2fhvhmhxnv"))
+       (file-name (string-append name "-" version ".tar.gz"))))
+    (propagated-inputs `(("alexandria" ,alexandria)))
+    (build-system asdf-build-system/source)
+    (synopsis "Common Lisp testing framework")
+    (description "FiveAM is a simple (as far as writing and running tests
+goes) regression testing framework.  It has been designed with Common Lisp's
+interactive development model in mind.")
+    (home-page "https://common-lisp.net/project/fiveam/")
+    (license license:bsd-3)))
+
+(define-public fiveam-sbcl
+  (package
+    (inherit fiveam)
+    (name "fiveam-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("fiveam" ,fiveam)
+              ("alexandria-sbcl" ,alexandria-sbcl)))
+    (propagated-inputs '())))
+
+(define-public fiveam-ecl
+  (package
+    (inherit fiveam)
+    (name "fiveam-ecl")
+    (build-system asdf-build-system/ecl)
+    (inputs `(("fiveam" ,fiveam)
+              ("alexandria-ecl" ,alexandria-ecl)))
+    (propagated-inputs '())))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 04/12] gnu: Add bordeaux-threads.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (2 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 03/12] gnu: Add fiveam Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 05/12] gnu: Add trivial-gray-streams Andy Patterson
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (bordeaux-threads, bordeaux-threads-sbcl)
  (bordeaux-threads-ecl): New variables.
---
 gnu/packages/lisp.scm | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 64bfc92..91f24ca 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -608,3 +608,48 @@ interactive development model in mind.")
     (inputs `(("fiveam" ,fiveam)
               ("alexandria-ecl" ,alexandria-ecl)))
     (propagated-inputs '())))
+
+(define-public bordeaux-threads
+  (package
+    (name "bordeaux-threads")
+    (version "0.8.5")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/sionescu/bordeaux-threads/archive/v"
+                    version ".tar.gz"))
+              (sha256
+               (base32 "10ryrcx832fwqdawb6jmknymi7wpdzhi30qzx7cbrk0cpnka71w2"))
+              (file-name (string-append name "-" version ".tar.gz"))))
+    (propagated-inputs `(("alexandria" ,alexandria)))
+    (build-system asdf-build-system/source)
+    (synopsis "Portable shared-state concurrency library for Common Lisp")
+    (description "BORDEAUX-THREADS is a proposed standard for a minimal
+MP/Threading interface.  It is similar to the CLIM-SYS threading and lock
+support.")
+    (home-page "https://common-lisp.net/project/bordeaux-threads/")
+    (license license:expat)))
+
+(define-public bordeaux-threads-sbcl
+  (package
+    (inherit bordeaux-threads)
+    (name "bordeaux-threads-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("bordeaux-threads" ,bordeaux-threads)
+              ("alexandria-sbcl" ,alexandria-sbcl)
+              ("fiveam-sbcl" ,fiveam-sbcl)))
+    (propagated-inputs '())
+    (arguments
+     '(#:test-only-systems '("fiveam")))))
+
+(define-public bordeaux-threads-ecl
+  (package
+    (inherit bordeaux-threads)
+    (name "bordeaux-threads-ecl")
+    (build-system asdf-build-system/ecl)
+    (inputs `(("bordeaux-threads" ,bordeaux-threads)
+              ("alexandria-ecl" ,alexandria-ecl)
+              ("fiveam-ecl" ,fiveam-ecl)))
+    (propagated-inputs '())
+    (arguments
+     '(#:test-only-systems '("fiveam")))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 05/12] gnu: Add trivial-gray-streams.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (3 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 04/12] gnu: Add bordeaux-threads Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 06/12] gnu: Add flexi-streams Andy Patterson
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (trivial-gray-streams)
  (trivial-gray-streams-sbcl, trivial-gray-streams-ecl): New variables.
---
 gnu/packages/lisp.scm | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 91f24ca..da38ec2 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -653,3 +653,42 @@ support.")
     (propagated-inputs '())
     (arguments
      '(#:test-only-systems '("fiveam")))))
+
+(define-public trivial-gray-streams
+  (let ((revision "1")
+        (commit "0483ade330508b4b2edeabdb47d16ec9437ee1cb"))
+    (package
+      (name "trivial-gray-streams")
+      (version (string-append "0.0.0-" revision "." (string-take commit 7)))
+      (source
+       (origin
+         (method git-fetch)
+         (uri
+          (git-reference
+           (url "https://github.com/trivial-gray-streams/trivial-gray-streams.git")
+           (commit commit)))
+         (sha256
+          (base32 "0m3rpf2x0zmdk3nf1qfa01j6a55vj7gkwhyw78qslcgbjlgh8p4d"))
+         (file-name (string-append name "-" version "-checkout"))))
+      (build-system asdf-build-system/source)
+      (synopsis "Compatibility layer for Gray streams implementations")
+      (description "Gray streams is an interface proposed for inclusion with
+ANSI CL by David N. Gray.  The proposal did not make it into ANSI CL, but most
+popular CL implementations implement it.  This package provides an extremely
+thin compatibility layer for gray streams.")
+      (home-page "http://www.cliki.net/trivial-gray-streams")
+      (license license:x11))))
+
+(define-public trivial-gray-streams-sbcl
+  (package
+    (inherit trivial-gray-streams)
+    (name "trivial-gray-streams-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("trivial-gray-streams" ,trivial-gray-streams)))))
+
+(define-public trivial-gray-streams-ecl
+  (package
+    (inherit trivial-gray-streams)
+    (name "trivial-gray-streams-ecl")
+    (build-system asdf-build-system/ecl)
+    (inputs `(("trivial-gray-streams" ,trivial-gray-streams)))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 06/12] gnu: Add flexi-streams.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (4 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 05/12] gnu: Add trivial-gray-streams Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 07/12] gnu: Add cl-ppcre Andy Patterson
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (flexi-streams, flexi-streams-sbcl)
  (flexi-streams-ecl): New variables.
---
 gnu/packages/lisp.scm | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index da38ec2..d54dbd3 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -692,3 +692,50 @@ thin compatibility layer for gray streams.")
     (name "trivial-gray-streams-ecl")
     (build-system asdf-build-system/ecl)
     (inputs `(("trivial-gray-streams" ,trivial-gray-streams)))))
+
+(define-public flexi-streams
+  (package
+    (name "flexi-streams")
+    (version "1.0.12")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/edicl/flexi-streams/archive/v"
+             version ".tar.gz"))
+       (sha256
+        (base32 "16grnxvs7vqm5s6myf8a5s7vwblzq1kgwj8i7ahz8vwvihm9gzfi"))
+       (file-name (string-append name "-" version ".tar.gz"))))
+    (build-system asdf-build-system/source)
+    (synopsis "Implementation of virtual bivalent streams for Common Lisp")
+    (description "Flexi-streams is an implementation of \"virtual\" bivalent
+streams that can be layered atop real binary or bivalent streams and that can
+be used to read and write character data in various single- or multi-octet
+encodings which can be changed on the fly.  It also supplies in-memory binary
+streams which are similar to string streams.")
+    (home-page "http://weitz.de/flexi-streams/")
+    (license license:bsd-3)))
+
+(define-public flexi-streams-sbcl
+  (package
+    (inherit flexi-streams)
+    (name "flexi-streams-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("flexi-streams" ,flexi-streams)
+              ("trivial-gray-streams-sbcl" ,trivial-gray-streams-sbcl)))
+    (propagated-inputs '())
+    (outputs '("out" "src"))
+    (arguments
+     '(#:build-in-tree "src"))))
+
+(define-public flexi-streams-ecl
+  (package
+    (inherit flexi-streams)
+    (name "flexi-streams-ecl")
+    (build-system asdf-build-system/ecl)
+    (inputs `(("flexi-streams" ,flexi-streams)
+              ("trivial-gray-streams-ecl" ,trivial-gray-streams-ecl)))
+    (propagated-inputs '())
+    (outputs '("out" "src"))
+    (arguments
+     '(#:build-in-tree "src"))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 07/12] gnu: Add cl-ppcre.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (5 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 06/12] gnu: Add flexi-streams Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 08/12] gnu: Add clx Andy Patterson
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-ppcre, cl-ppcre-sbcl, cl-ppcre-ecl): New
  variables.
---
 gnu/packages/lisp.scm | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index d54dbd3..67cb684 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -739,3 +739,44 @@ streams which are similar to string streams.")
     (outputs '("out" "src"))
     (arguments
      '(#:build-in-tree "src"))))
+
+(define-public cl-ppcre
+  (package
+    (name "cl-ppcre")
+    (version "2.0.11")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/edicl/cl-ppcre/archive/v"
+             version ".tar.gz"))
+       (sha256
+        (base32 "1i7daxf0wnydb0pgwiym7qh2wy70n14lxd6dyv28sy0naa8p31gd"))
+       (file-name (string-append name "-" version ".tar.gz"))))
+    (build-system asdf-build-system/source)
+    (synopsis "Portable regular expression library for Common Lisp")
+    (description "CL-PPCRE is a portable regular expression library for Common
+Lisp, which is compatible with perl.  It is pretty fast, thread-safe, and
+compatible with ANSI-compliant Common Lisp implementations.")
+    (home-page "http://weitz.de/cl-ppcre/")
+    (license license:bsd-2)))
+
+(define-public cl-ppcre-sbcl
+  (package
+    (inherit cl-ppcre)
+    (name "cl-ppcre-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("cl-ppcre" ,cl-ppcre)
+              ("flexi-streams-sbcl" ,flexi-streams-sbcl)))
+    (arguments
+     '(#:test-only-systems '("flexi-streams")))))
+
+(define-public cl-ppcre-ecl
+  (package
+    (inherit cl-ppcre)
+    (name "cl-ppcre-ecl")
+    (build-system asdf-build-system/ecl)
+    (inputs `(("cl-ppcre" ,cl-ppcre)
+              ("flexi-streams-ecl" ,flexi-streams-ecl)))
+    (arguments
+     '(#:test-only-systems '("flexi-streams")))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 08/12] gnu: Add clx.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (6 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 07/12] gnu: Add cl-ppcre Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 09/12] gnu: Add stumpwm Andy Patterson
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (clx, clx-sbcl, clx-ecl): New variables.
* gnu/packages/patches/clx-remove-demo: New variable.
* gnu/local.mk: Add it.
---
 gnu/local.mk                               |  1 +
 gnu/packages/lisp.scm                      | 67 ++++++++++++++++++++++++++++++
 gnu/packages/patches/clx-remove-demo.patch | 27 ++++++++++++
 3 files changed, 95 insertions(+)
 create mode 100644 gnu/packages/patches/clx-remove-demo.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index c2cdf8b..1ad1581 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -471,6 +471,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/clang-libc-search-path.patch		\
   %D%/packages/patches/clang-3.8-libc-search-path.patch		\
   %D%/packages/patches/clucene-pkgconfig.patch			\
+  %D%/packages/patches/clx-remove-demo.patch			\
   %D%/packages/patches/cmake-fix-tests.patch			\
   %D%/packages/patches/cpio-gets-undeclared.patch		\
   %D%/packages/patches/cpio-CVE-2016-2037.patch			\
diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 67cb684..1616b32 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -780,3 +780,70 @@ compatible with ANSI-compliant Common Lisp implementations.")
               ("flexi-streams-ecl" ,flexi-streams-ecl)))
     (arguments
      '(#:test-only-systems '("flexi-streams")))))
+
+(define-public clx
+  (let ((revision "1")
+        ;; 114e0de
+        (commit "1c62774b03c1cf3fe6e5cb532df8b14b44c96b95"))
+    (package
+      (name "clx")
+      (version (string-append "0.0.0-" revision "." (string-take commit 7)))
+      (source
+       (origin
+         (method git-fetch)
+         (uri
+          (git-reference
+           (url "https://github.com/sharplispers/clx.git")
+           (commit commit)))
+         (sha256
+          (base32 "0qffag03ns52kwq9xjns2qg1yr0bf3ba507iwq5cmx5xz0b0rmjm"))
+         (file-name (string-append name "-" version "-checkout"))
+         (patches
+          (list
+           (search-patch "clx-remove-demo.patch")))))
+      (build-system asdf-build-system/source)
+      (home-page "http://www.cliki.net/portable-clx")
+      (arguments
+       '(#:phases
+         (modify-phases %standard-phases/source
+           (add-before 'install 'remove-demos-and-test
+             ;; These removed files cause the compiled system to crash when
+             ;; loading.
+             (lambda _
+               (delete-file-recursively "demo")
+               (delete-file "test/trapezoid.lisp")
+               (substitute* "clx.asd"
+                 (("\\(:file \"trapezoid\"\\)") ""))
+               #t)))))
+      (synopsis "X11 client library for Common Lisp")
+      (description "CLX is an X11 client library for Common Lisp.  The code was
+originally taken from a CMUCL distribution, was modified somewhat in order to
+make it compile and run under SBCL, then a selection of patches were added
+from other CLXes around the net.")
+      (license license:x11))))
+
+(define-public clx-sbcl
+  (package
+    (inherit clx)
+    (name "clx-sbcl")
+    (source #f)
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("clx" ,clx)))
+    (arguments
+     '(#:special-dependencies '("sb-bsd-sockets")
+       #:phases
+       (modify-phases %standard-phases/sbcl
+         (delete 'unpack))))))
+
+(define-public clx-ecl
+  (package
+    (inherit clx)
+    (name "clx-ecl")
+    (source #f)
+    (build-system asdf-build-system/ecl)
+    (inputs `(("clx" ,clx)))
+    (arguments
+     '(#:special-dependencies '("sb-bsd-sockets")
+       #:phases
+       (modify-phases %standard-phases/ecl
+         (delete 'unpack))))))
diff --git a/gnu/packages/patches/clx-remove-demo.patch b/gnu/packages/patches/clx-remove-demo.patch
new file mode 100644
index 0000000..c5fffea
--- /dev/null
+++ b/gnu/packages/patches/clx-remove-demo.patch
@@ -0,0 +1,27 @@
+--- a/clx.asd	2016-02-16 00:06:48.161596976 -0500
++++ b/clx.asd	2016-02-16 00:06:54.793774658 -0500
+@@ -79,24 +79,6 @@
+                (:file "xtest")
+                (:file "screensaver")
+                (:file "xinerama")))
+-     (:module demo
+-	      :default-component-class example-source-file
+-	      :components
+-	      ((:file "bezier")
+-	       ;; KLUDGE: this requires "bezier" for proper operation,
+-	       ;; but we don't declare that dependency here, because
+-	       ;; asdf doesn't load example files anyway.
+-	       (:file "beziertest")
+-	       (:file "clclock")
+-               (:file "clipboard")
+-	       (:file "clx-demos")
+-	       (:file "gl-test")
+-	       ;; FIXME: compiling this generates 30-odd spurious code
+-	       ;; deletion notes.  Find out why, and either fix or
+-	       ;; workaround the problem.
+-	       (:file "mandel")
+-	       (:file "menu")
+-	       (:file "zoid")))
+      (:module test
+ 	      :default-component-class example-source-file
+ 	      :components
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 09/12] gnu: Add stumpwm.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (7 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 08/12] gnu: Add clx Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 10/12] gnu: Add slynk Andy Patterson
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (stumpwm, stumpwm-sbcl, stumpwm-ecl): New
  variables.
---
 gnu/packages/lisp.scm | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 1616b32..1c78875 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -847,3 +847,74 @@ from other CLXes around the net.")
        #:phases
        (modify-phases %standard-phases/ecl
          (delete 'unpack))))))
+
+(define-public stumpwm
+  (package
+    (name "stumpwm")
+    (version "0.9.9")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/stumpwm/stumpwm/archive/"
+                    version ".tar.gz"))
+              (sha256
+               (base32 "1fqabij4zcsqg1ywgdv2irp1ys23dwc8ms9ai55lb2i47hgv7z3x"))
+              (file-name (string-append name "-" version ".tar.gz"))))
+    (build-system asdf-build-system/source)
+    (propagated-inputs `(("cl-ppcre" ,cl-ppcre)
+                         ("clx" ,clx)))
+    (synopsis "Window manager written in Common Lisp")
+    (description "Stumpwm is a window manager written entirely in Common Lisp.
+It attempts to be highly customizable while relying entirely on the keyboard
+for input.  These design decisions reflect the growing popularity of
+productive, customizable lisp based systems.")
+    (home-page "http://github.com/stumpwm/stumpwm")
+    (license license:gpl2+)))
+
+(define-public stumpwm-sbcl
+  (package
+    (inherit stumpwm)
+    (name "stumpwm-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("stumpwm" ,stumpwm)
+              ("cl-ppcre-sbcl" ,cl-ppcre-sbcl)
+              ("clx-sbcl" ,clx-sbcl)))
+    (propagated-inputs '())
+    (outputs '("out" "bin"))
+    (arguments
+     '(#:special-dependencies '("sb-posix")
+       #:entry-program
+       '((stumpwm:stumpwm)
+         0)
+       #:phases
+       (modify-phases %standard-phases/sbcl
+         (add-after 'generate-binary 'create-desktop-file
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((bin (assoc-ref outputs "bin"))
+                   (xsessions "/share/xsessions"))
+               (mkdir-p (string-append bin xsessions))
+               (with-output-to-file
+                   (string-append bin xsessions
+                                  "/stumpwm.desktop")
+                 (lambda _
+                   (display
+                    "[Desktop Entry]
+Name=stumpwm
+Comment=The Stump Window Manager
+Exec=stumpwm
+TryExec=stumpwm
+Icon=
+Type=Application
+")))
+               #t))))))))
+
+(define-public stumpwm-ecl
+  (package
+    (inherit stumpwm)
+    (name "stumpwm-ecl")
+    (build-system asdf-build-system/ecl)
+    (inputs `(("stumpwm" ,stumpwm)
+              ("cl-ppcre-ecl" ,cl-ppcre-ecl)
+              ("clx-ecl" ,clx-ecl)))
+    (propagated-inputs '())
+    (outputs '("out"))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 10/12] gnu: Add slynk.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (8 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 09/12] gnu: Add stumpwm Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-10-08 12:59   ` Ludovic Courtès
  2016-09-27  4:15 ` [PATCH 11/12] gnu: Add stumpwm-with-slynk-sbcl Andy Patterson
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (slynk, slynk-sbcl, slynk-ecl): New variables.
---
 gnu/packages/lisp.scm | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 333 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 1c78875..21ca073 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -918,3 +918,336 @@ Type=Application
               ("clx-ecl" ,clx-ecl)))
     (propagated-inputs '())
     (outputs '("out"))))
+
+(define-public slynk
+  (package
+    (name "slynk")
+    (version "1.0.0-beta")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "https://github.com/capitaomorte/sly/archive/"
+                           version ".tar.gz"))
+       (sha256
+        (base32 "0mc3w6afgx97y2bh3pjv29dndidm016adpd11zn86kp7zq6xf8sv"))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (modules '((guix build utils)))
+       (snippet
+        '(begin
+           ;; Move the contribs into the main source directory for easier
+           ;; access
+           (substitute* "slynk/slynk.asd"
+             (("\\.\\./contrib")
+              "contrib"))
+           (substitute* "contrib/slynk-trace-dialog.lisp"
+             (("\\(slynk::reset-inspector\\)") ; Causes problems on load
+              "nil"))
+           (mkdir-p "slynk/contrib")
+           (copy-recursively "contrib" "slynk/contrib")))))
+    (build-system asdf-build-system/source)
+    (synopsis "Common Lisp IDE for Emacs")
+    (description "SLY is a fork of SLIME.  It also featrues a completely
+redesigned REPL based on Emacs's own full-featured comint.el, live code
+annotations, and a consistent interactive button interface.  Everything can be
+copied to the REPL.  One can create multiple inspectors with independent
+history.")
+    (home-page "https://github.com/capitaomorte/sly")
+    (license license:public-domain)
+    (arguments
+     '(#:phases
+       (modify-phases %standard-phases/source
+         (add-before 'install 'change-directory
+           (lambda _
+             (chdir "slynk")
+             #t)))))))
+
+(define slynk-sbcl-boot0
+  (package
+    (inherit slynk)
+    (name "slynk-sbcl")
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("slynk" ,slynk)))
+    (arguments
+     '(#:tests? #f ; no test suite
+       #:phases
+       (modify-phases %standard-phases/sbcl
+         (delete 'cleanup))))))
+
+(define slynk-ecl-boot0
+  (package
+    (inherit slynk-sbcl-boot0)
+    (name "slynk-ecl")
+    (build-system asdf-build-system/ecl)
+    (arguments
+     (substitute-keyword-arguments (package-arguments slynk-sbcl-boot0)
+       ((#:phases _)
+        '(modify-phases %standard-phases/ecl
+           (delete 'cleanup)))))))
+
+(define slynk-arglists-sbcl
+  (package
+    (inherit slynk-sbcl-boot0)
+    (name "slynk-arglists-sbcl")
+    (inputs `(("slynk-sbcl" ,slynk-sbcl-boot0)
+              ,@(package-inputs slynk-sbcl-boot0)))
+    (arguments
+     (substitute-keyword-arguments
+         `(#:compile-dependencies '("slynk")
+           #:source-input "slynk"
+           ,@(package-arguments slynk-sbcl-boot0))
+       ((#:phases _)
+        '(modify-phases %standard-phases/sbcl
+           (add-before 'build 'copy-output
+             (lambda* (#:key outputs inputs lisp #:allow-other-keys)
+               (let ((out (assoc-ref outputs "out"))
+                     (slynk (assoc-ref inputs
+                                       (string-append "slynk-" lisp))))
+                 (copy-recursively slynk out)
+                 (for-each delete-file
+                           (find-files out "\\.asd$")))))
+           (add-after 'copy-output 'delete-bundle
+             (lambda* (#:key outputs lisp #:allow-other-keys)
+               (let ((out (assoc-ref outputs "out")))
+                 (delete-file
+                  (string-append out "/lib/" lisp "/slynk--system.fasl")))))))))))
+
+(define slynk-arglists-ecl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-arglists-ecl")
+    (inputs `(("slynk-ecl" ,slynk-ecl-boot0)
+              ,@(package-inputs slynk-ecl-boot0)))
+    (build-system asdf-build-system/ecl)
+    (arguments
+     (substitute-keyword-arguments (package-arguments slynk-arglists-sbcl)
+       ((#:phases phases)
+        `(modify-phases %standard-phases/ecl
+           (add-before 'build 'copy-output
+             (assoc-ref ,phases 'copy-output))
+           (add-after 'copy-output 'delete-bundle
+             (lambda* (#:key outputs inputs lisp #:allow-other-keys)
+               (let ((out (assoc-ref outputs "out")))
+                 (delete-file
+                  (string-append out "/lib/" lisp "/slynk.fasb"))
+                 (delete-file
+                  (string-append out "/lib/" lisp "/slynk.a")))))))))))
+
+(define slynk-util-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-util-sbcl")))
+
+(define slynk-util-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-util-ecl")))
+
+(define slynk-fuzzy-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-fuzzy-sbcl")
+    (inputs `(("slynk-util-sbcl" ,slynk-util-sbcl)
+              ,@(package-inputs slynk-arglists-sbcl)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments slynk-arglists-sbcl)
+       ((#:compile-dependencies _)
+        ''("slynk" "slynk-util"))))))
+
+(define slynk-fuzzy-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-fuzzy-ecl")
+    (inputs `(("slynk-util-ecl" ,slynk-util-ecl)
+              ,@(package-inputs slynk-arglists-ecl)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments slynk-arglists-ecl)
+       ((#:compile-dependencies _)
+        ''("slynk" "slynk-util"))))))
+
+(define slynk-c-p-c-sbcl
+  (package
+    (inherit slynk-fuzzy-sbcl)
+    (name "slynk-c-p-c-sbcl")))
+
+(define slynk-c-p-c-ecl
+  (package
+    (inherit slynk-fuzzy-ecl)
+    (name "slynk-c-p-c-ecl")))
+
+(define slynk-fancy-inspector-sbcl
+  (package
+    (inherit slynk-fuzzy-sbcl)
+    (name "slynk-fancy-inspector-sbcl")))
+
+(define slynk-fancy-inspector-ecl
+  (package
+    (inherit slynk-fuzzy-ecl)
+    (name "slynk-fancy-inspector-ecl")))
+
+(define slynk-package-fu-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-package-fu-sbcl")))
+
+(define slynk-package-fu-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-package-fu-ecl")))
+
+(define slynk-mrepl-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-mrepl-sbcl")))
+
+(define slynk-mrepl-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-mrepl-ecl")))
+
+(define slynk-trace-dialog-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-trace-dialog-sbcl")))
+
+(define slynk-trace-dialog-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-trace-dialog-ecl")))
+
+(define slynk-profiler-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-profiler-sbcl")))
+
+(define slynk-profiler-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-profiler-ecl")))
+
+(define slynk-stickers-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-stickers-sbcl")))
+
+(define slynk-stickers-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-stickers-ecl")))
+
+(define slynk-indentation-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-indentation-sbcl")))
+
+(define slynk-indentation-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-indentation-ecl")))
+
+(define slynk-retro-sbcl
+  (package
+    (inherit slynk-arglists-sbcl)
+    (name "slynk-retro-sbcl")))
+
+(define slynk-retro-ecl
+  (package
+    (inherit slynk-arglists-ecl)
+    (name "slynk-retro-ecl")))
+
+(define-public slynk-sbcl
+  (let ((dependencies
+         '("slynk-util"
+           "slynk-arglists"
+           "slynk-c-p-c"
+           "slynk-fuzzy"
+           "slynk-fancy-inspector"
+           "slynk-package-fu"
+           "slynk-mrepl"
+           "slynk-profiler"
+           "slynk-trace-dialog"
+           "slynk-stickers"
+           "slynk-indentation"
+           "slynk-retro")))
+    (package
+      (inherit slynk-sbcl-boot0)
+      (name "slynk-sbcl")
+      (inputs `(("slynk" ,slynk-sbcl-boot0)
+                ("slynk-util" ,slynk-util-sbcl)
+                ("slynk-arglists" ,slynk-arglists-sbcl)
+                ("slynk-c-p-c" ,slynk-c-p-c-sbcl)
+                ("slynk-fuzzy" ,slynk-fuzzy-sbcl)
+                ("slynk-fancy-inspector" ,slynk-fancy-inspector-sbcl)
+                ("slynk-package-fu" ,slynk-package-fu-sbcl)
+                ("slynk-mrepl" ,slynk-mrepl-sbcl)
+                ("slynk-profiler" ,slynk-profiler-sbcl)
+                ("slynk-trace-dialog" ,slynk-trace-dialog-sbcl)
+                ("slynk-stickers" ,slynk-stickers-sbcl)
+                ("slynk-indentation" ,slynk-indentation-sbcl)
+                ("slynk-retro" ,slynk-retro-sbcl)))
+      (outputs '("out" "image"))
+      (arguments
+       (substitute-keyword-arguments
+           `(#:image-dependencies ',dependencies
+             ,@(package-arguments slynk-sbcl-boot0))
+         ((#:phases _)
+          `(modify-phases %standard-phases/sbcl
+             (add-before 'build 'copy-slynk
+               (lambda* (#:key outputs inputs #:allow-other-keys)
+                 (let ((out (assoc-ref outputs "out"))
+                       (slynk (assoc-ref inputs "slynk")))
+                   (copy-recursively slynk out))))
+             (add-after 'generate-image 'link-contribs
+               (lambda* (#:key outputs inputs lisp #:allow-other-keys)
+                 (let* ((out (assoc-ref outputs "out"))
+                        (asd-file (string-append out "/lib/" lisp "/slynk.asd"))
+                        (link-file (string-append
+                                    out "/share/common-lisp/" lisp
+                                    "-bundle-systems/slynk.asd")))
+                   (patch-asd-file
+                    asd-file
+                    (map
+                     (lambda (dependency)
+                       `(,dependency
+                         . ,(string-append
+                             (assoc-ref inputs dependency))))
+                     ',dependencies)
+                    lisp
+                    '())
+                   (delete-file link-file)
+                   (symlink asd-file link-file))))
+             (delete 'build)
+             (delete 'check)
+             (delete 'link-dependencies)
+             (delete 'create-symlinks))))))))
+
+(define-public slynk-ecl
+  (package
+    (inherit slynk-sbcl)
+    (name "slynk-ecl")
+    (inputs `(("slynk" ,slynk-ecl-boot0)
+              ("slynk-util" ,slynk-util-ecl)
+              ("slynk-arglists" ,slynk-arglists-ecl)
+              ("slynk-c-p-c" ,slynk-c-p-c-ecl)
+              ("slynk-fuzzy" ,slynk-fuzzy-ecl)
+              ("slynk-fancy-inspector" ,slynk-fancy-inspector-ecl)
+              ("slynk-package-fu" ,slynk-package-fu-ecl)
+              ("slynk-mrepl" ,slynk-mrepl-ecl)
+              ("slynk-profiler" ,slynk-profiler-ecl)
+              ("slynk-trace-dialog" ,slynk-trace-dialog-ecl)
+              ("slynk-stickers" ,slynk-stickers-ecl)
+              ("slynk-indentation" ,slynk-indentation-ecl)
+              ("slynk-retro" ,slynk-retro-ecl)))
+    (outputs '("out"))
+    (build-system asdf-build-system/ecl)
+    (arguments
+     (substitute-keyword-arguments (package-arguments slynk-sbcl)
+       ((#:phases phases)
+        `(modify-phases %standard-phases/ecl
+           (add-before 'build 'copy-slynk
+             (assoc-ref ,phases 'copy-slynk))
+           (add-after 'generate-image 'link-contribs
+             (assoc-ref ,phases 'link-contribs))
+           (delete 'build)
+           (delete 'check)
+           (delete 'link-dependencies)
+           (delete 'create-symlinks)))))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 11/12] gnu: Add stumpwm-with-slynk-sbcl.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (9 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 10/12] gnu: Add slynk Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27  4:15 ` [PATCH 12/12] gnu: Add stumpwm-with-slynk-image-sbcl Andy Patterson
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (stumpwm+slynk-sbcl): New variable.
---
 gnu/packages/lisp.scm | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 21ca073..5250a43 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -1251,3 +1251,20 @@ history.")
            (delete 'check)
            (delete 'link-dependencies)
            (delete 'create-symlinks)))))))
+
+(define-public stumpwm+slynk-sbcl
+  (package
+    (inherit stumpwm-sbcl)
+    (name "stumpwm-with-slynk-sbcl")
+    (native-inputs `(("stumpwm" ,stumpwm-sbcl)
+                     ("slynk" ,slynk-sbcl)))
+    (outputs '("out"))
+    (arguments
+     '(#:binary? #t
+       #:image-dependencies
+       '("stumpwm"
+         "slynk")
+       #:entry-program
+       '((stumpwm:stumpwm)
+         0)))))
+
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 12/12] gnu: Add stumpwm-with-slynk-image-sbcl.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (10 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 11/12] gnu: Add stumpwm-with-slynk-sbcl Andy Patterson
@ 2016-09-27  4:15 ` Andy Patterson
  2016-09-27 12:51 ` [PATCH 0/12]: Add asdf-build-system James Richardson
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-09-27  4:15 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (stumpwm+slynk-image-sbcl): New variable.
---
 gnu/packages/lisp.scm | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 5250a43..5bbd672 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -1268,3 +1268,15 @@ history.")
        '((stumpwm:stumpwm)
          0)))))
 
+(define-public stumpwm+slynk-image-sbcl
+  (package
+    (inherit stumpwm-sbcl)
+    (name "stumpwm-with-slynk-image-sbcl")
+    (native-inputs `(("stumpwm" ,stumpwm-sbcl)
+                     ("slynk" ,slynk-sbcl)))
+    (outputs '("out"))
+    (arguments
+     '(#:image? #t
+       #:image-dependencies
+       '("stumpwm"
+         "slynk")))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (11 preceding siblings ...)
  2016-09-27  4:15 ` [PATCH 12/12] gnu: Add stumpwm-with-slynk-image-sbcl Andy Patterson
@ 2016-09-27 12:51 ` James Richardson
  2016-09-29  2:30 ` Andy Patterson
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 51+ messages in thread
From: James Richardson @ 2016-09-27 12:51 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel


Andy Patterson writes:

> Hello,
>
> As promised, here's my work toward adding a build system for Common Lisp
> software. I still have some issues with it as follows:
>
Thank you!

> Getting things to work "out of the box": I'd like to set up an environment
> variable to allow implementations to find installed libraries, but it's a bit
> tricky:
>
> Essentially I'd like to have, in each profile, a setup something like
>
> export CL_SOURCE_FRAGMENT=#+sbcl \
>   (:directory \"${GUIX_PROFILE}/share/common-lisp/sbcl-bundle-systems/\") \
>   #+ecl ... \
>   ${CL_SOURCE_FRAGMENT}
>
> followed by
>
> export CL_SOURCE_REGISTRY=\
>   (:source-registry ${CL_SOURCE_FRAGMENT} \
>   (:directory \"${GUIX_PROFILE}/share/common-lisp/systems/\") \
>   :inherit-configuration)
>
> This would allow each implementation to pick up their own compiled libraries,
> as well as systems installed as source as a fallback. I don't know how to
> achieve that kind of a setup, so I'd like some help. I'm also worried about
> either blowing away user configuration, or having it shadow the desired
> configuration, since this isn't a simple search path which could be appended
> to. Should we try to patch the asdf implementations to handle a separate
> variable just for guix?
>
> I'd also like to hear your thoughts on how packages are laid out using the
> system, so I've included some examples. I was thinking that something like
> package-with-python2 could also be helpful here; is that the right way
> forward?
>

I don't really know enough to offer valid suggestions yet. There are
mostly the same questions/issues I hit when trying to package a lisp
program with dependencies. The Debian project came up with a thing
called common-lisp-controller
(http://ci-debian.alioth.debian.org/clid/clid.html/ch-clc.html) which
address some of the issues. It seems to build an abstraction layer over
asdf. I'm not advocating this as it does seem to presume a Debian-ish
infrastructure, just mentioning as a source of potential ideas.


> Thanks.

--
James Richardson

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (12 preceding siblings ...)
  2016-09-27 12:51 ` [PATCH 0/12]: Add asdf-build-system James Richardson
@ 2016-09-29  2:30 ` Andy Patterson
  2016-09-30 11:45   ` 宋文武
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
  2016-10-08 13:00 ` [PATCH 0/12]: " Ludovic Courtès
  15 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-09-29  2:30 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 714 bytes --]

On Tue, 27 Sep 2016 00:15:20 -0400
Andy Patterson <ajpatter@uwaterloo.ca> wrote:

> Getting things to work "out of the box": I'd like to set up an
> environment variable to allow implementations to find installed
> libraries, but it's a bit tricky:

After having thought about it some more, and having tried some things, I
came up with another solution which is able to integrate with guix's
existing environment variable handling. I've attached it as patches,
which would probably best be applied right after the first patch in
the main series, but could really go anywhere.

With these changes, the system is functionally complete, so I'm just
waiting for comments. Any suggestions are welcome.

Thanks,

--
Andy

[-- Attachment #2: 0001-gnu-sbcl-Honour-GUIX_SBCL_SOURCE_REGISTRY.patch --]
[-- Type: text/x-patch, Size: 2565 bytes --]

From ec4e6fef499dede3b591282c4ced2153dde4f661 Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Wed, 28 Sep 2016 19:04:44 -0400
Subject: [PATCH 1/2] gnu: sbcl: Honour GUIX_SBCL_SOURCE_REGISTRY.

* gnu/packages/lisp.scm (asdf-substitutions): New variable.
(sbcl) [source]: Add snippet.
[native-search-paths]: Add GUIX_SBCL_SOURCE_REGISTRY.
---
 gnu/packages/lisp.scm | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 5bbd672..4564549 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -47,6 +47,20 @@
   #:use-module (gnu packages version-control)
   #:use-module (ice-9 match))
 
+(define (asdf-substitutions lisp)
+  `((("\\(defun environment-source-registry \\(\\)")
+     (format #f
+             "
+  (defun guix-source-registry () (getenv \"GUIX_~a_SOURCE_REGISTRY\"))
+
+  (defun environment-source-registry ()"
+             ,(string-upcase lisp)))
+    (("\\(environment-source-registry")
+     "(guix-source-registry
+      environment-source-registry")
+    (("#:environment-source-registry")
+     "#:environment-source-registry #:guix-source-registry")))
+
 (define-public gcl
   (package
     (name "gcl")
@@ -226,7 +240,12 @@ an interpreter, a compiler, a debugger, and much more.")
        (uri (string-append "mirror://sourceforge/sbcl/sbcl/" version "/sbcl-"
                            version "-source.tar.bz2"))
        (sha256
-        (base32 "0fjdqnb2rsm2vi9794ywp27jr239ddvzc4xfr0dk49jd4v7p2kc5"))))
+        (base32 "0fjdqnb2rsm2vi9794ywp27jr239ddvzc4xfr0dk49jd4v7p2kc5"))
+       (modules '((guix build utils)))
+       (snippet
+        ;; Add $GUIX_SBCL_SOURCE_REGISTRY to *default-source-registries*
+        `(substitute* "contrib/asdf/asdf.lisp"
+           ,@(asdf-substitutions name)))))
     (build-system gnu-build-system)
     (outputs '("out" "doc"))
     ;; Bootstrap with CLISP.
@@ -315,6 +334,11 @@ an interpreter, a compiler, a debugger, and much more.")
                #t))))
          ;; No 'check' target, though "make.sh" (build phase) runs tests.
          #:tests? #f))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "GUIX_SBCL_SOURCE_REGISTRY")
+            (files '("share/common-lisp/sbcl-bundle-systems"
+                     "share/common-lisp/systems")))))
     (home-page "http://www.sbcl.org/")
     (synopsis "Common Lisp implementation")
     (description "Steel Bank Common Lisp (SBCL) is a high performance Common
-- 
2.10.0


[-- Attachment #3: 0002-gnu-ecl-Honour-GUIX_ECL_SOURCE_REGISTRY.patch --]
[-- Type: text/x-patch, Size: 1948 bytes --]

From aa81b363dfcaec8b82e66dd9db9f0c4fa0ef52f8 Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Wed, 28 Sep 2016 19:06:22 -0400
Subject: [PATCH 2/2] gnu: ecl: Honour GUIX_ECL_SOURCE_REGISTRY.

* gnu/packages/lisp.scm (ecl)[source]: Add snippet.
[native-search-paths]: Add GUIX_ECL_SOURCE_REGISTRY.
---
 gnu/packages/lisp.scm | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 4564549..4ec163a 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -126,7 +126,12 @@ interface to the Tk widget system.")
              "https://common-lisp.net/project/ecl/static/files/release/"
              name "-" version ".tgz"))
        (sha256
-        (base32 "16ab8qs3awvdxy8xs8jy82v8r04x4wr70l9l2j45vgag18d2nj1d"))))
+        (base32 "16ab8qs3awvdxy8xs8jy82v8r04x4wr70l9l2j45vgag18d2nj1d"))
+       (modules '((guix build utils)))
+       (snippet
+        ;; Add $GUIX_ECL_SOURCE_REGISTRY to *default-source-registries*
+        `(substitute* "contrib/asdf/asdf.lisp"
+           ,@(asdf-substitutions name)))))
     (build-system gnu-build-system)
     ;; src/configure uses 'which' to confirm the existence of 'gzip'.
     (native-inputs `(("which" ,which)))
@@ -167,6 +172,11 @@ interface to the Tk widget system.")
                  `("LIBRARY_PATH" suffix ,library-directories)
                  `("LD_LIBRARY_PATH" suffix ,library-directories)))))
          (add-after 'wrap 'check (assoc-ref %standard-phases 'check)))))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "GUIX_ECL_SOURCE_REGISTRY")
+            (files '("share/common-lisp/ecl-bundle-systems"
+                     "share/common-lisp/systems")))))
     (home-page "http://ecls.sourceforge.net/")
     (synopsis "Embeddable Common Lisp")
     (description "ECL is an implementation of the Common Lisp language as
-- 
2.10.0


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-09-29  2:30 ` Andy Patterson
@ 2016-09-30 11:45   ` 宋文武
  2016-10-03  2:41     ` Andy Patterson
  0 siblings, 1 reply; 51+ messages in thread
From: 宋文武 @ 2016-09-30 11:45 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

Andy Patterson <ajpatter@uwaterloo.ca> writes:

> On Tue, 27 Sep 2016 00:15:20 -0400
> Andy Patterson <ajpatter@uwaterloo.ca> wrote:
>
>> Getting things to work "out of the box": I'd like to set up an
>> environment variable to allow implementations to find installed
>> libraries, but it's a bit tricky:
>
> After having thought about it some more, and having tried some things, I
> came up with another solution which is able to integrate with guix's
> existing environment variable handling. I've attached it as patches,
> which would probably best be applied right after the first patch in
> the main series, but could really go anywhere.
>
> With these changes, the system is functionally complete, so I'm just
> waiting for comments. Any suggestions are welcome.

Amazing works, thanks!


I'd like to suggest 2 changes:

- Name generic (source) packages with 'cl-...', and specified (compiled)
  packages with 'sbcl-...', 'ecl-...', etc.  Same with our python and
  perl packages, etc.
  
- Put the source-registry customization 'GUIX_SBCL_SOURCE_REGISTRY'
  below the 'asdf/source-registry:default-user-source-registry' in
  'asdf/source-registry:*default-source-registries*'.  IIUC, otherwise
  CL systems installed from Guix will be prefered over user managed
  systems by quicklisp or under ~/common-lisp, etc.


Also, I find that ASDF already knowing the source systems well without
any additional evironment variable.  Due to XDG_DATA_DIRS is honored by

  'asdf/source-registry:default-system-source-registry'

So, I think we can change this:
--8<---------------cut here---------------start------------->8---
    (defun default-system-source-registry ()
    `(:source-registry
      ,@(loop :for dir :in (xdg-data-dirs "common-lisp/")
              :collect `(:directory (,dir "systems/"))
              :collect `(:tree (,dir "source/")))
      :inherit-configuration))
--8<---------------cut here---------------end--------------->8---

To:
--8<---------------cut here---------------start------------->8---
    (defun default-system-source-registry ()
    `(:source-registry
      ,@(loop :for dir :in (xdg-data-dirs "common-lisp/")
              :collect `(:directory (,dir "@LISP@-bundle-systems/")))
              
      ,@(loop :for dir :in (xdg-data-dirs "common-lisp/")
              :collect `(:directory (,dir "systems/"))
              :collect `(:tree (,dir "source/")))
      :inherit-configuration))
--8<---------------cut here---------------end--------------->8---

For the same effects.


Last, I guess the use of 'CL_SOURCE_REGISTRY' in asdf-build-system can
be removed safely (for either way, with GUIX_SBCL_SOURCE_REGISTRY or
XDG_DATA_DIRS).  Those environment variables should work in both the
builder (concatenated from directories from inputs) and profile.


What do you think?

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-09-30 11:45   ` 宋文武
@ 2016-10-03  2:41     ` Andy Patterson
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: 宋文武; +Cc: guix-devel

Hi 宋文武. Thanks for your suggestions!

On Fri, 30 Sep 2016 19:45:18 +0800
iyzsong@member.fsf.org (宋文武) wrote:

> I'd like to suggest 2 changes:
> 
> - Name generic (source) packages with 'cl-...', and specified
> (compiled) packages with 'sbcl-...', 'ecl-...', etc.  Same with our
> python and perl packages, etc.
>

Ok.
   
> - Put the source-registry customization 'GUIX_SBCL_SOURCE_REGISTRY'
>   below the 'asdf/source-registry:default-user-source-registry' in
>   'asdf/source-registry:*default-source-registries*'.  IIUC, otherwise
>   CL systems installed from Guix will be prefered over user managed
>   systems by quicklisp or under ~/common-lisp, etc.
>

The main concern was that there was no way to add an empty string into
the configuration (all files have some directory pre-pended), and asdf
uses an empty string to specify the inherited configuration. This
would have meant any preceding configurations being ignored,
unfortunately.
 
> 
> Also, I find that ASDF already knowing the source systems well without
> any additional evironment variable.  Due to XDG_DATA_DIRS is honored
> by
> 
>   'asdf/source-registry:default-system-source-registry'
> 
> So, I think we can change this:
> --8<---------------cut here---------------start------------->8---
>     (defun default-system-source-registry ()
>     `(:source-registry
>       ,@(loop :for dir :in (xdg-data-dirs "common-lisp/")
>               :collect `(:directory (,dir "systems/"))
>               :collect `(:tree (,dir "source/")))
>       :inherit-configuration))
> --8<---------------cut here---------------end--------------->8---
> 
> To:
> --8<---------------cut here---------------start------------->8---
>     (defun default-system-source-registry ()
>     `(:source-registry
>       ,@(loop :for dir :in (xdg-data-dirs "common-lisp/")
>               :collect `(:directory (,dir "@LISP@-bundle-systems/")))
>               
>       ,@(loop :for dir :in (xdg-data-dirs "common-lisp/")
>               :collect `(:directory (,dir "systems/"))
>               :collect `(:tree (,dir "source/")))
>       :inherit-configuration))
> --8<---------------cut here---------------end--------------->8---
> 
> For the same effects.
>

I really like this idea. It will give system priority to
system-installed packages, as expected. I decided to do this and scrap
the other environment variables. Thanks!
 
> 
> Last, I guess the use of 'CL_SOURCE_REGISTRY' in asdf-build-system can
> be removed safely (for either way, with GUIX_SBCL_SOURCE_REGISTRY or
> XDG_DATA_DIRS).  Those environment variables should work in both the
> builder (concatenated from directories from inputs) and profile.
> 

This is now true; although the registry still needs to be set for the
system which is being compiled. I removed any inputs from being added
to that variable, as you suggest.

> 
> What do you think?

Thanks for the good ideas =). I made some other changes as well which
I'll describe in the updated patch-set.

--
Andy

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v2 00/13]: Add asdf-build-system.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (13 preceding siblings ...)
  2016-09-29  2:30 ` Andy Patterson
@ 2016-10-03  2:41 ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 01/13] build-system: " Andy Patterson
                     ` (14 more replies)
  2016-10-08 13:00 ` [PATCH 0/12]: " Ludovic Courtès
  15 siblings, 15 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

Here's the next round of the series. In addition to the changes proposed by
宋文武, I homogenized the phases of the compiled packages, in order to
simplify transformations. I also added a package transformer system similar to
package-with-python2. Finally, I decided to have all packages bundle a copy of
their source, and use it while building, rather than using the source packages
as a build input, which had some complications.

Further comments are appreciated.

Thanks,

--
Andy

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-05  4:55     ` 宋文武
  2016-10-07  8:07     ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 02/13] gnu: sbcl: Honour XDG_DATA_DIRS Andy Patterson
                     ` (13 subsequent siblings)
  14 siblings, 2 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* guix/build-system/asdf.scm: New file.
* guix/build/asdf-build-system.scm: New file.
* guix/build/lisp-utils.scm: New file.
* Makefile.am: Add them.
* doc/guix.texi: Add section on 'asdf-build-system/source'.
---
 Makefile.am                      |   3 +
 doc/guix.texi                    |  60 ++++++
 guix/build-system/asdf.scm       | 385 +++++++++++++++++++++++++++++++++++++
 guix/build/asdf-build-system.scm | 400 +++++++++++++++++++++++++++++++++++++++
 guix/build/lisp-utils.scm        | 240 +++++++++++++++++++++++
 5 files changed, 1088 insertions(+)
 create mode 100644 guix/build-system/asdf.scm
 create mode 100644 guix/build/asdf-build-system.scm
 create mode 100644 guix/build/lisp-utils.scm

diff --git a/Makefile.am b/Makefile.am
index 43a33c8..a23e5fd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -63,6 +63,7 @@ MODULES =					\
   guix/build-system/ant.scm			\
   guix/build-system/cmake.scm			\
   guix/build-system/emacs.scm			\
+  guix/build-system/asdf.scm			\
   guix/build-system/glib-or-gtk.scm		\
   guix/build-system/gnu.scm			\
   guix/build-system/haskell.scm			\
@@ -84,6 +85,7 @@ MODULES =					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
   guix/build/emacs-build-system.scm		\
+  guix/build/asdf-build-system.scm		\
   guix/build/git.scm				\
   guix/build/hg.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
@@ -106,6 +108,7 @@ MODULES =					\
   guix/build/syscalls.scm                       \
   guix/build/gremlin.scm			\
   guix/build/emacs-utils.scm			\
+  guix/build/lisp-utils.scm			\
   guix/build/graft.scm				\
   guix/build/bournish.scm			\
   guix/build/qt-utils.scm			\
diff --git a/doc/guix.texi b/doc/guix.texi
index f5bbb92..53db367 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2965,6 +2965,66 @@ that should be run during the @code{build} phase.  By default the
 
 @end defvr
 
+@defvr {Scheme Variable} asdf-build-system/source
+@defvrx {Scheme Variable} asdf-build-system/sbcl
+@defvrx {Scheme Variable} asdf-build-system/ecl
+
+These variables, exported by @code{(guix build-system sbcl)}, implement
+build procedures for Common Lisp packages using the
+@url{https://common-lisp.net/project/asdf/, ``ASDF''} system.
+
+The @code{asdf-build-system/source} system installs the packages in
+source form, and can be loaded using any common lisp implementation, via
+ASDF.  The others, such as @code{asdf-build-system/sbcl}, install binary
+systems in the format which a particular implementation understands.
+These build systems can also be used to produce executable programs, or
+lisp images which contain a set of packages pre-loaded.
+
+The build system uses conventions to determine the roles of inputs in
+the build system.  For binary packages, the package itself as well as
+its dependencies should begin their name with the lisp implementation,
+such as @code{sbcl-} for @code{asdf-build-system/sbcl}.  If dependencies
+are used only for tests, it is convenient to use a different prefix in
+order to avoid having a run-time dependency on such systems.  For
+example,
+
+@example
+(define-public sbcl-bordeaux-threads
+  (package
+    ...
+    (native-inputs `(("tests:cl-fiveam" ,sbcl-fiveam)))
+    ...))
+@end example
+
+Additionally, the corresponding source package should be labelled using
+the same convention as python packages (see @ref{Python Modules}), using
+the @code{cl-} prefix.
+
+One package should be defined for each ASDF system.
+
+The package outputs control whether or not executable programs and
+images are built alongside the package's usual output, using the
+@code{bin} and @code{image} outputs, respectively.
+
+Packages can also be built which combine other packages into an
+executable program or image only, without building another system.
+Specifying one of the @code{#:binary?} or @code{#:image?} parameters
+will produce this behaviour.
+
+When building an executable program, the @code{#:entry-program}
+parameter, which should be a list of Common Lisp expressions, must be
+used to specify what program should be run.  In this program,
+@code{arguments} will be bound to the command-line arguments passed.
+
+The @code{#:image-dependencies} parameter can be used to add packages to
+the pre-loaded systems included in the executable program or image.
+@code{#:compile-dependencies} specifies a list of additional systems
+which should be loaded before a system is compiled.  If the package
+depends on special systems exported by the implementation itself, the
+@code{#:special-dependencies} parameter should be used to specify them.
+
+@end defvr
+
 @defvr {Scheme Variable} cmake-build-system
 This variable is exported by @code{(guix build-system cmake)}.  It
 implements the build procedure for packages using the
diff --git a/guix/build-system/asdf.scm b/guix/build-system/asdf.scm
new file mode 100644
index 0000000..eb8b7d9
--- /dev/null
+++ b/guix/build-system/asdf.scm
@@ -0,0 +1,385 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build-system asdf)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix packages)
+  #:use-module (guix derivations)
+  #:use-module (guix search-paths)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system gnu)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (%asdf-build-system-modules
+            %asdf-build-modules
+            asdf-build
+            asdf-build-system/sbcl
+            asdf-build-system/ecl
+            asdf-build-system/source
+            sbcl-package->cl-source-package
+            sbcl-package->ecl-package))
+
+;; Commentary:
+;;
+;; Standard build procedure for asdf packages.  This is implemented as an
+;; extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define %asdf-build-system-modules
+  ;; Imported build-side modules
+  `((guix build asdf-build-system)
+    (guix build lisp-utils)
+    ,@%gnu-build-system-modules))
+
+(define %asdf-build-modules
+  ;; Used (visible) build-side modules
+  '((guix build asdf-build-system)
+    (guix build utils)
+    (guix build lisp-utils)))
+
+(define (default-lisp implementation)
+  "Return the default package for the lisp IMPLEMENTATION."
+  ;; Lazily resolve the binding to avoid a circular dependancy.
+  (let ((lisp-module (resolve-interface '(gnu packages lisp))))
+    (module-ref lisp-module implementation)))
+
+(define* (lower/source name
+                       #:key source inputs outputs native-inputs system target
+                       #:allow-other-keys
+                       #:rest arguments)
+  "Return a bag for NAME"
+  (define private-keywords
+    '(#:target #:inputs #:native-inputs))
+
+  (and (not target)
+       (bag
+         (name name)
+         (system system)
+         (host-inputs `(,@(if source
+                              `(("source" ,source))
+                              '())
+                        ,@inputs
+                        ,@(standard-packages)))
+         (build-inputs native-inputs)
+         (outputs outputs)
+         (build asdf-build/source)
+         (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define* (asdf-build/source store name inputs
+                            #:key source outputs
+                            (phases '(@ (guix build asdf-build-system)
+                                        %standard-phases/source))
+                            (search-paths '())
+                            (system (%current-system))
+                            (guile #f)
+                            (imported-modules %asdf-build-system-modules)
+                            (modules %asdf-build-modules))
+  (define builder
+    `(begin
+       (use-modules ,@modules)
+       (asdf-build/source #:name ,name
+                          #:source ,(match (assoc-ref inputs "source")
+                                      (((? derivation? source))
+                                       (derivation->output-path source))
+                                      ((source) source)
+                                      (source source))
+                          #:system ,system
+                          #:phases ,phases
+                          #:outputs %outputs
+                          #:search-paths ',(map search-path-specification->sexp
+                                                search-paths)
+                          #:inputs %build-inputs)))
+
+  (define guile-for-build
+    (match guile
+      ((? package?)
+       (package-derivation store guile system #:graft? #f))
+      (#f
+       (let* ((distro (resolve-interface '(gnu packages commencement)))
+              (guile (module-ref distro 'guile-final)))
+         (package-derivation store guile system #:graft? #f)))))
+
+  (build-expression->derivation store name builder
+                                #:inputs inputs
+                                #:system system
+                                #:modules imported-modules
+                                #:outputs outputs
+                                #:guile-for-build guile-for-build))
+
+(define* (package-with-build-system from-build-system to-build-system
+                                    from-prefix to-prefix
+                                    #:key variant-property
+                                    phases-transformer)
+  "Return a precedure which takes a package PKG which uses FROM-BUILD-SYSTEM,
+and returns one using TO-BUILD-SYSTEM. If PKG was prefixed by FROM-PREFIX, the
+resulting package will be prefixed by TO-PREFIX. Inputs of PKG are recursively
+transformed using the same rule. The result's #:phases argument will be
+modified by PHASES-TRANSFORMER, a list which evaluates on the build side to a
+procedure of one argument.
+
+VARIANT-PROPERTY can be added to a package's properties to indicate that the
+corresponding package promise should be used as the result of this
+transformation. This allows the result to differ from what the transformation
+would otherwise produce.
+
+If TO-BUILD-SYSTEM is asdf-build-system/source, the resulting package will be
+set up using CL source package conventions."
+  (define target-is-source? (eq? 'asdf/source
+                                 (build-system-name to-build-system)))
+
+  (define (transform-package-name name)
+    (if (string-prefix? from-prefix name)
+        (let ((new-name (string-drop name (string-length from-prefix))))
+          (if (string-prefix? to-prefix new-name)
+              new-name
+              (string-append to-prefix new-name)))
+        name))
+
+  (define (has-from-build-system? pkg)
+    (eq? (build-system-name from-build-system)
+         (build-system-name (package-build-system pkg))))
+
+  (define transform
+    (memoize
+     (lambda (pkg)
+       (define rewrite
+         (match-lambda
+           ((name content . rest)
+            (let* ((is-package? (package? content))
+                   (new-content (if is-package? (transform content) content))
+                   (new-name (if (and is-package?
+                                      (string-prefix? from-prefix name))
+                                 (package-name new-content)
+                                 name)))
+              `(,new-name ,new-content ,@rest)))))
+
+       ;; Special considerations for source packages: CL inputs become
+       ;; propagated, and un-handled arguments are removed. Native inputs are
+       ;; removed as are extraneous outputs.
+       (define new-propagated-inputs
+         (if target-is-source?
+             (map rewrite
+                  (filter (match-lambda
+                            ((_ input . _)
+                             (has-from-build-system? input)))
+                          (package-inputs pkg)))
+             '()))
+
+       (define new-inputs
+         (if target-is-source?
+             (map rewrite
+                  (filter (match-lambda
+                            ((_ input . _)
+                             (not (has-from-build-system? input))))
+                          (package-inputs pkg)))
+             (map rewrite (package-inputs pkg))))
+
+       (define base-arguments
+         (if target-is-source?
+             (strip-keyword-arguments
+              '(#:tests? #:special-dependencies #:entry-program
+                #:image-dependencies #:compile-dependencies #:image?
+                #:binary? #:test-only-systems #:lisp)
+              (package-arguments pkg))
+             (package-arguments pkg)))
+
+       (cond
+        ((and variant-property
+              (assoc-ref (package-properties pkg) variant-property))
+         => force)
+
+        ((has-from-build-system? pkg)
+         (package
+           (inherit pkg)
+           (location (package-location pkg))
+           (name (transform-package-name (package-name pkg)))
+           (build-system to-build-system)
+           (arguments
+            (substitute-keyword-arguments base-arguments
+              ((#:phases phases) (list phases-transformer phases))))
+           (inputs new-inputs)
+           (propagated-inputs new-propagated-inputs)
+           (native-inputs (if target-is-source?
+                              '()
+                              (map rewrite (package-native-inputs pkg))))
+           (outputs (if target-is-source?
+                        '("out")
+                        (package-outputs pkg)))))
+        (else pkg)))))
+
+  transform)
+
+(define (strip-variant-as-necessary variant pkg)
+  (define properties (package-properties pkg))
+  (if (assoc variant properties)
+      (package
+        (inherit pkg)
+        (properties (alist-delete variant properties)))
+      pkg))
+
+(define (lower lisp-implementation)
+  (lambda* (name
+            #:key source inputs outputs native-inputs system target
+            (lisp (default-lisp (string->symbol lisp-implementation)))
+            #:allow-other-keys
+            #:rest arguments)
+    "Return a bag for NAME"
+    (define private-keywords
+      '(#:target #:inputs #:native-inputs #:lisp))
+
+    (and (not target)
+         (bag
+           (name name)
+           (system system)
+           (host-inputs `(,@(if source
+                                `(("source" ,source))
+                                '())
+                          ,@inputs
+                          ,@(standard-packages)))
+           (build-inputs `((,lisp-implementation ,lisp)
+                           ,@native-inputs))
+           (outputs outputs)
+           (build (asdf-build lisp-implementation))
+           (arguments (strip-keyword-arguments private-keywords arguments))))))
+
+(define (asdf-build lisp-implementation)
+  (lambda* (store name inputs
+                  #:key source outputs
+                  (tests? #t)
+                  (special-dependencies ''())
+                  (entry-program #f)
+                  (image-dependencies ''())
+                  (compile-dependencies ''())
+                  (image? #f)
+                  (binary? #f)
+                  (test-only-systems ''())
+                  (lisp lisp-implementation)
+                  (phases '(@ (guix build asdf-build-system)
+                              %standard-phases))
+                  (search-paths '())
+                  (system (%current-system))
+                  (guile #f)
+                  (imported-modules %asdf-build-system-modules)
+                  (modules %asdf-build-modules))
+
+    (define builder
+      `(begin
+         (use-modules ,@modules)
+         (asdf-build #:name ,name
+                     #:source ,(match (assoc-ref inputs "source")
+                                 (((? derivation? source))
+                                  (derivation->output-path source))
+                                 ((source) source)
+                                 (source source))
+                     #:lisp ,lisp
+                     #:special-dependencies ,special-dependencies
+                     #:entry-program ,entry-program
+                     #:image-dependencies ,image-dependencies
+                     #:compile-dependencies ,compile-dependencies
+                     #:image? ,image?
+                     #:binary? ,binary?
+                     #:test-only-systems ,test-only-systems
+                     #:system ,system
+                     #:tests? ,tests?
+                     #:phases ,phases
+                     #:outputs %outputs
+                     #:search-paths ',(map search-path-specification->sexp
+                                           search-paths)
+                     #:inputs %build-inputs)))
+
+    (define guile-for-build
+      (match guile
+        ((? package?)
+         (package-derivation store guile system #:graft? #f))
+        (#f
+         (let* ((distro (resolve-interface '(gnu packages commencement)))
+                (guile (module-ref distro 'guile-final)))
+           (package-derivation store guile system #:graft? #f)))))
+
+    (build-expression->derivation store name builder
+                                  #:inputs inputs
+                                  #:system system
+                                  #:modules imported-modules
+                                  #:outputs outputs
+                                  #:guile-for-build guile-for-build)))
+
+(define asdf-build-system/sbcl
+  (build-system
+    (name 'asdf/sbcl)
+    (description "The build system for asdf binary packages using sbcl")
+    (lower (lower "sbcl"))))
+
+(define asdf-build-system/ecl
+  (build-system
+    (name 'asdf/ecl)
+    (description "The build system for asdf binary packages using ecl")
+    (lower (lower "ecl"))))
+
+(define asdf-build-system/source
+  (build-system
+    (name 'asdf/source)
+    (description "The build system for asdf source packages")
+    (lower lower/source)))
+
+(define source-package->sbcl-package
+  (let* ((property 'sbcl-variant)
+         (transformer
+          (package-with-build-system asdf-build-system/source
+                                     asdf-build-system/sbcl
+                                     "cl-"
+                                     "sbcl-"
+                                     #:variant-property property
+                                     #:phases-transformer
+                                     'source-phases->sbcl-phases)))
+    (lambda (pkg)
+      (transformer
+       (strip-variant-as-necessary property pkg)))))
+
+(define sbcl-package->cl-source-package
+  (let* ((property 'cl-source-variant)
+         (transformer
+          (package-with-build-system asdf-build-system/sbcl
+                                     asdf-build-system/source
+                                     "sbcl-"
+                                     "cl-"
+                                     #:variant-property property
+                                     #:phases-transformer
+                                     '(const %standard-phases/source))))
+    (lambda (pkg)
+      (transformer
+       (strip-variant-as-necessary property pkg)))))
+
+(define sbcl-package->ecl-package
+  (let* ((property 'ecl-variant)
+         (transformer
+          (package-with-build-system asdf-build-system/sbcl
+                                     asdf-build-system/ecl
+                                     "sbcl-"
+                                     "ecl-"
+                                     #:variant-property property
+                                     #:phases-transformer
+                                     'identity)))
+    (lambda (pkg)
+      (transformer
+       (strip-variant-as-necessary property pkg)))))
+
+;;; asdf.scm ends here
diff --git a/guix/build/asdf-build-system.scm b/guix/build/asdf-build-system.scm
new file mode 100644
index 0000000..7554b54
--- /dev/null
+++ b/guix/build/asdf-build-system.scm
@@ -0,0 +1,400 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build asdf-build-system)
+  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+  #:use-module (guix build utils)
+  #:use-module (guix build lisp-utils)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 receive)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 format)
+  #:export (%standard-phases
+            %standard-phases/source
+            asdf-build
+            asdf-build/source))
+
+;; Commentary:
+;;
+;; System for building ASDF packages; creating executable programs and images
+;; from them.
+;;
+;; Code:
+
+(define %object-prefix "/lib")
+
+(define (source-install-prefix lisp)
+  (string-append %install-prefix "/" lisp "-source"))
+
+(define %system-install-prefix
+  (string-append %install-prefix "/systems"))
+
+(define (output-path->package-name path)
+  (package-name->name+version (strip-store-file-name path)))
+
+(define (outputs->name outputs)
+  (output-path->package-name
+   (assoc-ref outputs "out")))
+
+(define (wrap-source-registry registry)
+  `(:source-registry
+    ,@registry
+    :inherit-configuration))
+
+(define (wrap-output-translations translations)
+  `(:output-translations
+    ,@translations
+    :inherit-configuration))
+
+(define (lisp-source-directory output lisp name)
+  (string-append output (source-install-prefix lisp) "/" name))
+
+(define (source-directory output name)
+  (string-append output %install-prefix "/source/" name))
+
+(define (library-directory output lisp)
+  (string-append output %object-prefix
+                 "/" lisp))
+
+(define (output-translation source-path
+                            object-output
+                            lisp)
+  "Return a translation for the system's source path
+to it's binary output."
+  `((,source-path
+     :**/ :*.*.*)
+    (,(library-directory object-output lisp)
+     :**/ :*.*.*)))
+
+(define (source-registry source-path)
+  `(:tree ,source-path))
+
+(define (lisp-dependency-names lisp inputs)
+  (map first (lisp-dependencies lisp inputs)))
+
+(define (copy-files-to-output outputs output name)
+  "Copy all files from OUTPUT to \"out\". Create an extra link to any
+system-defining files in the source to a convenient location. This is done
+before any compiling so that the compiled source locations will be valid."
+  (let* ((out (assoc-ref outputs output))
+         (source (getcwd))
+         (target (source-directory out name))
+         (system-path (string-append out %system-install-prefix)))
+    (copy-recursively source target)
+    (mkdir-p system-path)
+    (for-each
+     (lambda (file)
+       (symlink file
+                (string-append system-path "/" (basename file))))
+     (find-files target "\\.asd$"))
+    #t))
+
+(define* (install #:key outputs #:allow-other-keys)
+  "Copy and symlink all the source files."
+  (copy-files-to-output outputs "out" (outputs->name outputs)))
+
+(define* (copy-source #:key outputs lisp
+                      image? binary?
+                      #:allow-other-keys)
+  "Copy the source to \"out\"."
+  (unless (or binary? image?)
+    (let* ((out (assoc-ref outputs "out"))
+           (name (remove-lisp-from-name (output-path->package-name out) lisp))
+           (install-path (string-append out %install-prefix)))
+      (copy-files-to-output outputs "out" name)
+      ;; Hide the files from asdf
+      (with-directory-excursion install-path
+        (rename-file "source" (string-append lisp "-source"))
+        (delete-file-recursively "systems"))))
+  #t)
+
+(define* (build #:key outputs inputs lisp
+                compile-dependencies
+                image?
+                binary?
+                #:allow-other-keys)
+  "Compile the system."
+
+  (unless (or binary? image?)
+    (let* ((out (assoc-ref outputs "out"))
+           (name (remove-lisp-from-name (output-path->package-name out) lisp))
+           (source-path (lisp-source-directory out lisp name))
+           (translations (wrap-output-translations
+                          `(,(output-translation source-path
+                                                 out
+                                                 lisp)))))
+
+      (setenv "ASDF_OUTPUT_TRANSLATIONS"
+              (replace-escaped-macros (format #f "~S" translations)))
+      (setenv "CL_SOURCE_REGISTRY"
+              (replace-escaped-macros
+               (format #f "~S" (wrap-source-registry
+                                `(,(source-registry source-path))))))
+
+      (setenv "HOME" out) ; ecl's asdf sometimes wants to create $HOME/.cache
+
+      (parameterize ((%lisp (string-append
+                             (assoc-ref inputs lisp) "/bin/" lisp)))
+        (compile-system name lisp compile-dependencies))
+
+      ;; As above, ecl will sometimes create this even though it doesn't use it
+
+      (let ((cache-directory (string-append out "/.cache")))
+        (when (directory-exists? cache-directory)
+          (delete-file-recursively cache-directory)))))
+  #t)
+
+(define* (check #:key lisp tests? outputs inputs
+                compile-dependencies
+                image?
+                binary?
+                #:allow-other-keys)
+  "Test the system."
+
+  (if (and tests? (not image?) (not binary?))
+      (parameterize ((%lisp (string-append
+                             (assoc-ref inputs lisp) "/bin/" lisp)))
+        (test-system
+         (remove-lisp-from-name (outputs->name outputs) lisp)
+         lisp
+         compile-dependencies))
+      (format #t "test suite not run~%"))
+  #t)
+
+(define* (patch-asd-files #:key outputs
+                          inputs
+                          lisp
+                          special-dependencies
+                          image?
+                          binary?
+                          test-only-systems
+                          #:allow-other-keys)
+  "Patch any asd files created by the compilation process so that they
+can find their dependencies. Exclude any TEST-ONLY-SYSTEMS which were only
+included to run tests. Add any SPECIAL-DEPENDENCIES which the LISP
+implementation itself provides."
+  (unless (or image? binary?)
+    (let* ((out (assoc-ref outputs "out"))
+           (name (remove-lisp-from-name (output-path->package-name out) lisp))
+           (registry (lset-difference
+                      (lambda (input system)
+                        (match input
+                          ((name . path) (string=? name system))))
+                      (lisp-dependencies lisp inputs)
+                      test-only-systems))
+           (lisp-systems (map first registry)))
+
+      (for-each
+       (lambda (asd-file)
+         (patch-asd-file asd-file registry lisp
+                         (append lisp-systems special-dependencies)))
+       (find-files out "\\.asd$"))))
+  #t)
+
+(define* (symlink-asd-files #:key outputs lisp
+                            image? binary?
+                            #:allow-other-keys)
+  "Create an extra reference to the system in a convenient location."
+  (unless (or image? binary?)
+    (let* ((out (assoc-ref outputs "out")))
+      (for-each
+       (lambda (asd-file)
+         (receive (new-asd-file asd-file-directory)
+             (bundle-asd-file out asd-file lisp)
+           (mkdir-p asd-file-directory)
+           (symlink asd-file new-asd-file)))
+
+       (find-files (string-append out %object-prefix) "\\.asd$"))))
+  #t)
+
+(define* (generate-binary #:key outputs
+                          inputs
+                          image-dependencies
+                          entry-program
+                          lisp
+                          binary?
+                          #:allow-other-keys)
+  "Generate a binary program for the system, either in \"bin\" if the package
+also contains a library system, or in \"out\" otherwise."
+  (define output (if binary? "out" "bin"))
+  (generate-executable #:outputs outputs
+                       #:inputs inputs
+                       #:image-dependencies image-dependencies
+                       #:entry-program entry-program
+                       #:lisp lisp
+                       #:output output
+                       #:needs-own-system? (not binary?)
+                       #:type "program")
+  (and=>
+   (assoc-ref outputs output)
+   (lambda (bin)
+     (let* ((full-name (outputs->name outputs))
+            (name (if binary? full-name
+                      (remove-lisp-from-name full-name lisp)))
+            (bin-directory (string-append bin "/bin")))
+       (with-directory-excursion bin-directory
+         (rename-file (string-append name "-exec")
+                      name)))))
+  #t)
+
+(define* (generate-image #:key outputs
+                         inputs
+                         image-dependencies
+                         lisp
+                         image?
+                         #:allow-other-keys)
+  "Generate an image for the system, possibly standalone, either in \"image\"
+if the package also contains a library system, or in \"out\" otherwise."
+  (define output (if image? "out" "image"))
+  (generate-executable #:outputs outputs
+                       #:inputs inputs
+                       #:image-dependencies image-dependencies
+                       #:entry-program '(nil)
+                       #:lisp lisp
+                       #:output output
+                       #:needs-own-system? (not image?)
+                       #:type "image")
+  (and=>
+   (assoc-ref outputs output)
+   (lambda (image)
+     (let* ((full-name (outputs->name outputs))
+            (name (if image? full-name
+                      (remove-lisp-from-name full-name lisp)))
+            (bin-directory (string-append image "/bin")))
+       (with-directory-excursion bin-directory
+         (rename-file (string-append name "-exec--all-systems.image")
+                      (string-append name ".image"))))))
+  #t)
+
+(define* (generate-executable #:key outputs
+                              image-dependencies
+                              entry-program
+                              lisp
+                              output
+                              inputs
+                              type
+                              needs-own-system?
+                              #:allow-other-keys)
+  "Generate an executable by using asdf's TYPE-op, containing whithin the
+image all IMAGE-DEPNDENCIES, and running ENTRY-PROGRAM in the case of an
+executable."
+  (and=>
+   (assoc-ref outputs output)
+   (lambda (out)
+     (let* ((bin-directory (string-append out "/bin"))
+            (full-name (outputs->name outputs))
+            (name (if needs-own-system?
+                      (remove-lisp-from-name full-name lisp)
+                      full-name)))
+       (mkdir-p out)
+       (with-directory-excursion out
+         (generate-executable-wrapper-system name
+                                             image-dependencies
+                                             needs-own-system?)
+         (generate-executable-entry-point name entry-program))
+
+       (setenv "CL_SOURCE_REGISTRY"
+               (replace-escaped-macros
+                (format
+                 #f "~S"
+                 (wrap-source-registry
+                  `(,(source-registry (assoc-ref outputs "out"))
+                    ,(source-registry out))))))
+
+       (setenv "ASDF_OUTPUT_TRANSLATIONS"
+               (replace-escaped-macros
+                (format
+                 #f "~S"
+                 (wrap-output-translations
+                  `(((,out :**/ :*.*.*)
+                     (,bin-directory :**/ :*.*.*)))))))
+
+       (parameterize ((%lisp (string-append
+                              (assoc-ref inputs lisp) "/bin/" lisp)))
+         (generate-executable-for-system type name lisp))
+
+       (delete-file (string-append out "/" name "-exec.asd"))
+       (delete-file (string-append out "/" name "-exec.lisp"))))))
+
+(define* (cleanup-files #:key outputs binary? image? lisp
+                             #:allow-other-keys)
+  "Remove any compiled files which are not a part of the final bundle."
+  (unless (or binary? image?)
+    (let ((out (assoc-ref outputs "out")))
+      (match lisp
+        ("sbcl"
+         (for-each
+          (lambda (file)
+            (unless (string-suffix? "--system.fasl" file)
+              (delete-file file)))
+          (find-files out "\\.fasl$")))
+        ("ecl"
+         (for-each delete-file
+                   (append (find-files out "\\.fas$")
+                           (find-files out "\\.o$")))))))
+  #t)
+
+(define* (strip #:key lisp #:allow-other-keys #:rest args)
+  ;; stripping sbcl binaries removes their entry program and extra systems
+  (unless (string=? lisp "sbcl")
+    (apply (assoc-ref gnu:%standard-phases 'strip) args))
+  #t)
+
+(define %standard-phases/source
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'check)
+    (delete 'build)
+    (replace 'install install)))
+
+(define %standard-phases
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'install)
+    (replace 'build build)
+    (add-before 'build 'copy-source copy-source)
+    (replace 'check check)
+    (replace 'strip strip)
+    (add-after 'check 'link-dependencies patch-asd-files)
+    (add-after 'link-dependencies 'create-symlinks symlink-asd-files)
+    (add-after 'create-symlinks 'cleanup cleanup-files)
+    (add-after 'cleanup 'generate-binary generate-binary)
+    (add-after 'generate-binary 'generate-image generate-image)))
+
+(define* (asdf-build #:key inputs
+                     (phases %standard-phases)
+                     #:allow-other-keys
+                     #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+(define* (asdf-build/source #:key inputs
+                            (phases %standard-phases/source)
+                            #:allow-other-keys
+                            #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+;;; asdf-build-system.scm ends here
diff --git a/guix/build/lisp-utils.scm b/guix/build/lisp-utils.scm
new file mode 100644
index 0000000..f67e38b
--- /dev/null
+++ b/guix/build/lisp-utils.scm
@@ -0,0 +1,240 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build lisp-utils)
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (%lisp
+            %install-prefix
+            lisp-eval-program
+            compile-system
+            test-system
+            replace-escaped-macros
+            generate-executable-wrapper-system
+            generate-executable-entry-point
+            generate-executable-for-system
+            patch-asd-file
+            bundle-install-prefix
+            lisp-dependencies
+            bundle-asd-file
+            remove-lisp-from-name))
+
+;;; Commentary:
+;;;
+;;; Tools to evaluate lisp programs within a lisp session, generate wrapper
+;;; systems for executables. Compile, test, and produce images for systems and
+;;; programs, and link them with their dependencies.
+;;;
+;;; Code:
+
+(define %lisp
+  (make-parameter "lisp"))
+
+(define %install-prefix "/share/common-lisp")
+
+(define (bundle-install-prefix lisp)
+  (string-append %install-prefix "/" lisp "-bundle-systems"))
+
+(define (remove-lisp-from-name name lisp)
+  (string-drop name (1+ (string-length lisp))))
+
+(define (lisp-eval-program lisp program)
+  "Evaluate PROGRAM with a given LISP implementation."
+  (unless (zero? (apply system*
+                        (lisp-invoke lisp (format #f "~S" program))))
+    (error "lisp-eval-program failed!" lisp program)))
+
+(define (lisp-invoke lisp program)
+  "Return a list of arguments for system* determining how to invoke LISP
+with PROGRAM."
+  (match lisp
+    ("sbcl" `(,(%lisp) "--non-interactive" "--eval" ,program))
+    ("ecl" `(,(%lisp) "-eval" ,program "-eval" "(quit)"))))
+
+(define (asdf-load-all systems)
+  (map (lambda (system)
+         `(funcall
+           (find-symbol
+            (symbol-name :load-system)
+            (symbol-name :asdf))
+           ,system))
+       systems))
+
+(define (compile-system system lisp other-required-systems)
+  "Use a lisp implementation to compile SYSTEM using asdf. Loads
+OTHER-REQUIRED-SYSTEMS before beginning compilation."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       ,@(asdf-load-all other-required-systems)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :compile-bundle-op)
+                                 (symbol-name :asdf))
+                                ,system)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :deliver-asd-op)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (test-system system lisp other-required-systems)
+  "Use a lisp implementation to test SYSTEM using asdf. Loads
+OTHER-REQUIRED-SYSTEMS before beginning to test."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       ,@(asdf-load-all other-required-systems)
+                       (funcall (find-symbol
+                                 (symbol-name :test-system)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (string->lisp-keyword . strings)
+  "Return a lisp keyword for the concatenation of STRINGS."
+  (string->symbol (apply string-append ":" strings)))
+
+(define (generate-executable-for-system type system lisp)
+  "Use LISP to generate an executable, whose TYPE can be \"image\"
+or \"program\". The latter will always be standalone. Depends on having
+created a \"SYSTEM-exec\" system which contains the entry program."
+  (lisp-eval-program
+   lisp
+   `(progn
+     (require :asdf)
+     (funcall (find-symbol
+               (symbol-name :operate)
+               (symbol-name :asdf))
+              (find-symbol
+               (symbol-name ,(string->lisp-keyword type "-op"))
+               (symbol-name :asdf))
+              ,(string-append system "-exec")))))
+
+(define (generate-executable-wrapper-system system
+                                            dependencies
+                                            needs-system?)
+  "Generates a system which can be used by asdf to produce an image or program
+inside the current directory. The image or program will contain SYSTEM and all
+other DEPENDENCIES, which may not be depended on by the SYSTEM itself. SYSTEM
+will be excluded unless NEEDS-SYSTEM? is #t."
+  (with-output-to-file (string-append system "-exec.asd")
+    (lambda _
+      (format #t "~y~%"
+              `(defsystem ,(string->lisp-keyword system "-exec")
+                 :entry-point ,(string-append system "-exec:main")
+                 :depends-on (:uiop
+                              ,@(if needs-system?
+                                    `(,(string->lisp-keyword system))
+                                    '())
+                              ,@(map string->lisp-keyword
+                                     dependencies))
+                 :components ((:file ,(string-append system "-exec"))))))))
+
+(define (generate-executable-entry-point system entry-program)
+  "Generates an entry point program from the list of lisp statements
+ENTRY-PROGRAM for SYSTEM within the current directory."
+  (with-output-to-file (string-append system "-exec.lisp")
+    (lambda _
+      (let ((system (string->lisp-keyword system "-exec")))
+        (format #t "~{~y~%~%~}"
+                `((defpackage ,system
+                    (:use :cl)
+                    (:export :main))
+
+                  (in-package ,system)
+
+                  (defun main ()
+                    (let ((arguments uiop:*command-line-arguments*))
+                      (declare (ignorable arguments))
+                      ,@entry-program))))))))
+
+(define (wrap-perform-method lisp registry dependencies file-name)
+  "Creates a wrapper method which allows the system to locate its dependent
+systems from REGISTRY, an alist of the same form as %outputs, which contains
+lisp systems which the systems is dependent on. All DEPENDENCIES which
+the system depends on will the be loaded before this system."
+  (let* ((system (string-drop-right (basename file-name) 4))
+         (system-symbol (string->lisp-keyword system)))
+
+    `(defmethod asdf:perform :before
+       (op (c (eql (asdf:find-system ,system-symbol))))
+       (asdf/source-registry:ensure-source-registry)
+       ,@(map (match-lambda
+                ((name . path)
+                 (let ((asd-file (string-append path
+                                                (bundle-install-prefix lisp)
+                                                "/" name ".asd")))
+                   `(setf
+                     (gethash ,name
+                              asdf/source-registry:*source-registry*)
+                     ,(string->symbol "#p")
+                     ,(bundle-asd-file path asd-file lisp)))))
+              registry)
+       ,@(map (lambda (system)
+                `(asdf:load-system ,(string->lisp-keyword system)))
+              dependencies))))
+
+(define (patch-asd-file asd-file registry lisp dependencies)
+  "Patches ASD-FILE with a perform method as described in WRAP-PERFORM-METHOD."
+  (chmod asd-file #o644)
+  (let ((port (open-file asd-file "a")))
+    (dynamic-wind
+      (lambda _ #t)
+      (lambda _
+        (display
+         (replace-escaped-macros
+          (format #f "~%~y~%"
+                  (wrap-perform-method lisp registry
+                                       dependencies asd-file)))
+         port))
+      (lambda _ (close-port port))))
+  (chmod asd-file #o444))
+
+(define (lisp-dependencies lisp inputs)
+  "Determine which inputs are lisp system dependencies, by using the convention
+that a lisp system dependency will resemble \"system-LISP\"."
+  (filter-map (match-lambda
+                ((name . value)
+                 (and (string-prefix? lisp name)
+                      (string<> lisp name)
+                      `(,(remove-lisp-from-name name lisp)
+                        . ,value))))
+              inputs))
+
+(define (bundle-asd-file output-path original-asd-file lisp)
+  "Find the symlinked bundle file for ORIGINAL-ASD-FILE by looking
+in OUTPUT-PATH/lib/LISP/<system>.asd. Returns two values: the asd
+file itself and the directory in which it resides."
+  (let ((bundle-asd-path (string-append output-path
+                                        (bundle-install-prefix lisp))))
+    (values (string-append bundle-asd-path "/" (basename original-asd-file))
+            bundle-asd-path)))
+
+(define (replace-escaped-macros string)
+  "Replace simple lisp forms that the guile writer escapes, for
+example by replacing #{#p}# with #p. Should only be used to replace
+truly simple forms which are not nested."
+  (regexp-substitute/global #f "(#\\{)(\\S*)(\\}#)" string
+                            'pre 2 'post))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 02/13] gnu: sbcl: Honour XDG_DATA_DIRS.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 01/13] build-system: " Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 03/13] gnu: ecl: " Andy Patterson
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (asdf-substitutions): New variable.
(sbcl) [source]: Add snippet.
[native-search-paths]: Add XDG_DATA_DIRS.
---
 gnu/packages/lisp.scm | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 439433a..1311a7d 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -47,6 +47,15 @@
   #:use-module (ice-9 match)
   #:use-module (srfi srfi-1))
 
+(define (asdf-substitutions lisp)
+  `((("\\(,dir \"systems/\"\\)\\)")
+     (format #f
+             "(,dir \"~a-bundle-systems\")))
+
+      ,@(loop :for dir :in (xdg-data-dirs \"common-lisp/\")
+              :collect `(:directory (,dir \"systems\"))"
+             ,lisp))))
+
 (define-public gcl
   (package
     (name "gcl")
@@ -226,7 +235,12 @@ an interpreter, a compiler, a debugger, and much more.")
        (uri (string-append "mirror://sourceforge/sbcl/sbcl/" version "/sbcl-"
                            version "-source.tar.bz2"))
        (sha256
-        (base32 "0fjdqnb2rsm2vi9794ywp27jr239ddvzc4xfr0dk49jd4v7p2kc5"))))
+        (base32 "0fjdqnb2rsm2vi9794ywp27jr239ddvzc4xfr0dk49jd4v7p2kc5"))
+       (modules '((guix build utils)))
+       (snippet
+        ;; Add sbcl-bundle-systems to the asdf registry
+        `(substitute* "contrib/asdf/asdf.lisp"
+           ,@(asdf-substitutions name)))))
     (build-system gnu-build-system)
     (outputs '("out" "doc"))
     ;; Bootstrap with CLISP.
@@ -315,6 +329,10 @@ an interpreter, a compiler, a debugger, and much more.")
                #t))))
          ;; No 'check' target, though "make.sh" (build phase) runs tests.
          #:tests? #f))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "XDG_DATA_DIRS")
+            (files '("share")))))
     (home-page "http://www.sbcl.org/")
     (synopsis "Common Lisp implementation")
     (description "Steel Bank Common Lisp (SBCL) is a high performance Common
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 03/13] gnu: ecl: Honour XDG_DATA_DIRS.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 01/13] build-system: " Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 02/13] gnu: sbcl: Honour XDG_DATA_DIRS Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 04/13] gnu: Add cl-alexandria Andy Patterson
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (ecl)[source]: Add snippet.
[native-search-paths]: Add XDG_DATA_DIRS.
---
 gnu/packages/lisp.scm | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 1311a7d..59086e6 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -121,7 +121,12 @@ interface to the Tk widget system.")
              "https://common-lisp.net/project/ecl/static/files/release/"
              name "-" version ".tgz"))
        (sha256
-        (base32 "16ab8qs3awvdxy8xs8jy82v8r04x4wr70l9l2j45vgag18d2nj1d"))))
+        (base32 "16ab8qs3awvdxy8xs8jy82v8r04x4wr70l9l2j45vgag18d2nj1d"))
+       (modules '((guix build utils)))
+       (snippet
+        ;; Add ecl-bundle-systems to the asdf registry
+        `(substitute* "contrib/asdf/asdf.lisp"
+           ,@(asdf-substitutions name)))))
     (build-system gnu-build-system)
     ;; src/configure uses 'which' to confirm the existence of 'gzip'.
     (native-inputs `(("which" ,which)))
@@ -162,6 +167,10 @@ interface to the Tk widget system.")
                  `("LIBRARY_PATH" suffix ,library-directories)
                  `("LD_LIBRARY_PATH" suffix ,library-directories)))))
          (add-after 'wrap 'check (assoc-ref %standard-phases 'check)))))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "XDG_DATA_DIRS")
+            (files '("share")))))
     (home-page "http://ecls.sourceforge.net/")
     (synopsis "Embeddable Common Lisp")
     (description "ECL is an implementation of the Common Lisp language as
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 04/13] gnu: Add cl-alexandria.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (2 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 03/13] gnu: ecl: " Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 05/13] gnu: Add cl-fiveam Andy Patterson
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-alexandria, sbcl-alexandria)
  (ecl-alexandria): New variables.
---
 gnu/packages/lisp.scm | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 59086e6..dd17bce 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -33,6 +33,7 @@
   #:use-module (guix git-download)
   #:use-module (guix utils)
   #:use-module (guix build-system gnu)
+  #:use-module (guix build-system asdf)
   #:use-module (gnu packages base)
   #:use-module (gnu packages multiprecision)
   #:use-module (gnu packages bdw-gc)
@@ -563,3 +564,32 @@ simple, elegant Scheme dialect.  It is a lisp-1 with lexical scope.
 The core is 12 builtin special forms and 33 builtin functions.")
       (home-page "https://github.com/JeffBezanson/femtolisp")
       (license license:bsd-3))))
+
+(define-public sbcl-alexandria
+  (let ((revision "1")
+        (commit "926a066611b7b11cb71e26c827a271e500888c30"))
+    (package
+      (name "sbcl-alexandria")
+      (version (string-append "0.0.0-" revision "." (string-take commit 7)))
+      (source (origin
+                (method git-fetch)
+                (uri
+                 (git-reference
+                  (url "https://gitlab.common-lisp.net/alexandria/alexandria.git")
+                  (commit commit)))
+                (sha256
+                 (base32 "18yncicdkh294j05rhgm23gzi36y9qy6vrfba8vg69jrxjp1hx8l"))
+                (file-name (string-append "alexandria-" version "-checkout"))))
+      (build-system asdf-build-system/sbcl)
+      (synopsis "Collection of portable utilities for Common Lisp")
+      (description "Alexandria is a collection of portable utilities.  It does
+not contain conceptual extensions to Common Lisp.  It is conservative in
+scope, and portable between implementations.")
+      (home-page "https://common-lisp.net/project/alexandria/")
+      (license license:public-domain))))
+
+(define-public cl-alexandria
+  (sbcl-package->cl-source-package sbcl-alexandria))
+
+(define-public ecl-alexandria
+  (sbcl-package->ecl-package sbcl-alexandria))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 05/13] gnu: Add cl-fiveam.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (3 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 04/13] gnu: Add cl-alexandria Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 06/13] gnu: Add cl-bordeaux-threads Andy Patterson
                     ` (9 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-fiveam, sbcl-fiveam, ecl-fiveam): New
  variables.
---
 gnu/packages/lisp.scm | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index dd17bce..513034c 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -593,3 +593,31 @@ scope, and portable between implementations.")
 
 (define-public ecl-alexandria
   (sbcl-package->ecl-package sbcl-alexandria))
+
+(define-public sbcl-fiveam
+  (package
+    (name "sbcl-fiveam")
+    (version "1.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/sionescu/fiveam/archive/v"
+             version ".tar.gz"))
+       (sha256
+        (base32 "0f48pcbhqs3wwwzjl5nk57d4hcbib4l9xblxc66b8c2fhvhmhxnv"))
+       (file-name (string-append "fiveam-" version ".tar.gz"))))
+    (inputs `(("sbcl-alexandria" ,sbcl-alexandria)))
+    (build-system asdf-build-system/sbcl)
+    (synopsis "Common Lisp testing framework")
+    (description "FiveAM is a simple (as far as writing and running tests
+goes) regression testing framework.  It has been designed with Common Lisp's
+interactive development model in mind.")
+    (home-page "https://common-lisp.net/project/fiveam/")
+    (license license:bsd-3)))
+
+(define-public cl-fiveam
+  (sbcl-package->cl-source-package sbcl-fiveam))
+
+(define-public ecl-fiveam
+  (sbcl-package->ecl-package sbcl-fiveam))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 06/13] gnu: Add cl-bordeaux-threads.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (4 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 05/13] gnu: Add cl-fiveam Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 07/13] gnu: Add cl-trivial-gray-streams Andy Patterson
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-bordeaux-threads, sbcl-bordeaux-threads)
  (ecl-bordeaux-threads): New variables.
---
 gnu/packages/lisp.scm | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 513034c..5d2a03b 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -621,3 +621,32 @@ interactive development model in mind.")
 
 (define-public ecl-fiveam
   (sbcl-package->ecl-package sbcl-fiveam))
+
+(define-public sbcl-bordeaux-threads
+  (package
+    (name "sbcl-bordeaux-threads")
+    (version "0.8.5")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/sionescu/bordeaux-threads/archive/v"
+                    version ".tar.gz"))
+              (sha256
+               (base32 "10ryrcx832fwqdawb6jmknymi7wpdzhi30qzx7cbrk0cpnka71w2"))
+              (file-name
+               (string-append "bordeaux-threads-" version ".tar.gz"))))
+    (inputs `(("sbcl-alexandria" ,sbcl-alexandria)))
+    (native-inputs `(("tests:cl-fiveam" ,sbcl-fiveam)))
+    (build-system asdf-build-system/sbcl)
+    (synopsis "Portable shared-state concurrency library for Common Lisp")
+    (description "BORDEAUX-THREADS is a proposed standard for a minimal
+MP/Threading interface.  It is similar to the CLIM-SYS threading and lock
+support.")
+    (home-page "https://common-lisp.net/project/bordeaux-threads/")
+    (license license:x11)))
+
+(define-public cl-bordeaux-threads
+  (sbcl-package->cl-source-package sbcl-bordeaux-threads))
+
+(define-public ecl-bordeaux-threads
+  (sbcl-package->ecl-package sbcl-bordeaux-threads))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 07/13] gnu: Add cl-trivial-gray-streams.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (5 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 06/13] gnu: Add cl-bordeaux-threads Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 08/13] gnu: Add cl-flexi-streams Andy Patterson
                     ` (7 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-trivial-gray-streams)
  (sbcl-trivial-gray-streams, ecl-trivial-gray-streams): New variables.
---
 gnu/packages/lisp.scm | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 5d2a03b..712075a 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -650,3 +650,35 @@ support.")
 
 (define-public ecl-bordeaux-threads
   (sbcl-package->ecl-package sbcl-bordeaux-threads))
+
+(define-public sbcl-trivial-gray-streams
+  (let ((revision "1")
+        (commit "0483ade330508b4b2edeabdb47d16ec9437ee1cb"))
+    (package
+      (name "sbcl-trivial-gray-streams")
+      (version (string-append "0.0.0-" revision "." (string-take commit 7)))
+      (source
+       (origin
+         (method git-fetch)
+         (uri
+          (git-reference
+           (url "https://github.com/trivial-gray-streams/trivial-gray-streams.git")
+           (commit commit)))
+         (sha256
+          (base32 "0m3rpf2x0zmdk3nf1qfa01j6a55vj7gkwhyw78qslcgbjlgh8p4d"))
+         (file-name
+          (string-append "trivial-gray-streams-" version "-checkout"))))
+      (build-system asdf-build-system/sbcl)
+      (synopsis "Compatibility layer for Gray streams implementations")
+      (description "Gray streams is an interface proposed for inclusion with
+ANSI CL by David N. Gray.  The proposal did not make it into ANSI CL, but most
+popular CL implementations implement it.  This package provides an extremely
+thin compatibility layer for gray streams.")
+      (home-page "http://www.cliki.net/trivial-gray-streams")
+      (license license:x11))))
+
+(define-public cl-trivial-gray-streams
+  (sbcl-package->cl-source-package sbcl-trivial-gray-streams))
+
+(define-public ecl-trivial-gray-streams
+  (sbcl-package->ecl-package sbcl-trivial-gray-streams))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 08/13] gnu: Add cl-flexi-streams.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (6 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 07/13] gnu: Add cl-trivial-gray-streams Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 09/13] gnu: Add cl-ppcre Andy Patterson
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-flexi-streams, sbcl-flexi-streams)
  (ecl-flexi-streams): New variables.
---
 gnu/packages/lisp.scm | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 712075a..b83e63f 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -682,3 +682,33 @@ thin compatibility layer for gray streams.")
 
 (define-public ecl-trivial-gray-streams
   (sbcl-package->ecl-package sbcl-trivial-gray-streams))
+
+(define-public sbcl-flexi-streams
+  (package
+    (name "sbcl-flexi-streams")
+    (version "1.0.12")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/edicl/flexi-streams/archive/v"
+             version ".tar.gz"))
+       (sha256
+        (base32 "16grnxvs7vqm5s6myf8a5s7vwblzq1kgwj8i7ahz8vwvihm9gzfi"))
+       (file-name (string-append "flexi-streams-" version ".tar.gz"))))
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("sbcl-trivial-gray-streams" ,sbcl-trivial-gray-streams)))
+    (synopsis "Implementation of virtual bivalent streams for Common Lisp")
+    (description "Flexi-streams is an implementation of \"virtual\" bivalent
+streams that can be layered atop real binary or bivalent streams and that can
+be used to read and write character data in various single- or multi-octet
+encodings which can be changed on the fly.  It also supplies in-memory binary
+streams which are similar to string streams.")
+    (home-page "http://weitz.de/flexi-streams/")
+    (license license:bsd-3)))
+
+(define-public cl-flexi-streams
+  (sbcl-package->cl-source-package sbcl-flexi-streams))
+
+(define-public ecl-flexi-streams
+  (sbcl-package->ecl-package sbcl-flexi-streams))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 09/13] gnu: Add cl-ppcre.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (7 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 08/13] gnu: Add cl-flexi-streams Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 10/13] gnu: Add cl-clx Andy Patterson
                     ` (5 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-ppcre, sbcl-cl-pprcre, ecl-cl-pprcre): New
  variables.
---
 gnu/packages/lisp.scm | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index b83e63f..84457eb 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -712,3 +712,31 @@ streams which are similar to string streams.")
 
 (define-public ecl-flexi-streams
   (sbcl-package->ecl-package sbcl-flexi-streams))
+
+(define-public sbcl-cl-ppcre
+  (package
+    (name "sbcl-cl-ppcre")
+    (version "2.0.11")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/edicl/cl-ppcre/archive/v"
+             version ".tar.gz"))
+       (sha256
+        (base32 "1i7daxf0wnydb0pgwiym7qh2wy70n14lxd6dyv28sy0naa8p31gd"))
+       (file-name (string-append "cl-ppcre-" version ".tar.gz"))))
+    (build-system asdf-build-system/sbcl)
+    (native-inputs `(("tests:cl-flexi-streams" ,sbcl-flexi-streams)))
+    (synopsis "Portable regular expression library for Common Lisp")
+    (description "CL-PPCRE is a portable regular expression library for Common
+Lisp, which is compatible with perl.  It is pretty fast, thread-safe, and
+compatible with ANSI-compliant Common Lisp implementations.")
+    (home-page "http://weitz.de/cl-ppcre/")
+    (license license:bsd-2)))
+
+(define-public cl-ppcre
+  (sbcl-package->cl-source-package sbcl-cl-ppcre))
+
+(define-public ecl-cl-ppcre
+  (sbcl-package->ecl-package sbcl-cl-ppcre))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 10/13] gnu: Add cl-clx.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (8 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 09/13] gnu: Add cl-ppcre Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 11/13] gnu: Add cl-stumpwm Andy Patterson
                     ` (4 subsequent siblings)
  14 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-clx, sbcl-clx, ecl-clx): New variables.
* gnu/packages/patches/clx-remove-demo.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                               |  1 +
 gnu/packages/lisp.scm                      | 45 ++++++++++++++++++++++++++++++
 gnu/packages/patches/clx-remove-demo.patch | 27 ++++++++++++++++++
 3 files changed, 73 insertions(+)
 create mode 100644 gnu/packages/patches/clx-remove-demo.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 4260a92..10a2bac 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -473,6 +473,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/clang-libc-search-path.patch		\
   %D%/packages/patches/clang-3.8-libc-search-path.patch		\
   %D%/packages/patches/clucene-pkgconfig.patch			\
+  %D%/packages/patches/clx-remove-demo.patch			\
   %D%/packages/patches/cmake-fix-tests.patch			\
   %D%/packages/patches/cpio-gets-undeclared.patch		\
   %D%/packages/patches/cpio-CVE-2016-2037.patch			\
diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 84457eb..fa7f727 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -740,3 +740,48 @@ compatible with ANSI-compliant Common Lisp implementations.")
 
 (define-public ecl-cl-ppcre
   (sbcl-package->ecl-package sbcl-cl-ppcre))
+
+(define-public sbcl-clx
+  (let ((revision "1")
+        (commit "1c62774b03c1cf3fe6e5cb532df8b14b44c96b95"))
+    (package
+      (name "sbcl-clx")
+      (version (string-append "0.0.0-" revision "." (string-take commit 7)))
+      (source
+       (origin
+         (method git-fetch)
+         (uri
+          (git-reference
+           (url "https://github.com/sharplispers/clx.git")
+           (commit commit)))
+         (sha256
+          (base32 "0qffag03ns52kwq9xjns2qg1yr0bf3ba507iwq5cmx5xz0b0rmjm"))
+         (file-name (string-append "clx-" version "-checkout"))
+         (patches
+          (list
+           (search-patch "clx-remove-demo.patch")))
+         (modules '((guix build utils)))
+         (snippet
+          '(begin
+             ;; These removed files cause the compiled system to crash when
+             ;; loading.
+             (delete-file-recursively "demo")
+             (delete-file "test/trapezoid.lisp")
+             (substitute* "clx.asd"
+               (("\\(:file \"trapezoid\"\\)") ""))))))
+      (build-system asdf-build-system/sbcl)
+      (arguments
+       '(#:special-dependencies '("sb-bsd-sockets")))
+      (home-page "http://www.cliki.net/portable-clx")
+      (synopsis "X11 client library for Common Lisp")
+      (description "CLX is an X11 client library for Common Lisp.  The code was
+originally taken from a CMUCL distribution, was modified somewhat in order to
+make it compile and run under SBCL, then a selection of patches were added
+from other CLXes around the net.")
+      (license license:x11))))
+
+(define-public cl-clx
+  (sbcl-package->cl-source-package sbcl-clx))
+
+(define-public ecl-clx
+  (sbcl-package->ecl-package sbcl-clx))
diff --git a/gnu/packages/patches/clx-remove-demo.patch b/gnu/packages/patches/clx-remove-demo.patch
new file mode 100644
index 0000000..c5fffea
--- /dev/null
+++ b/gnu/packages/patches/clx-remove-demo.patch
@@ -0,0 +1,27 @@
+--- a/clx.asd	2016-02-16 00:06:48.161596976 -0500
++++ b/clx.asd	2016-02-16 00:06:54.793774658 -0500
+@@ -79,24 +79,6 @@
+                (:file "xtest")
+                (:file "screensaver")
+                (:file "xinerama")))
+-     (:module demo
+-	      :default-component-class example-source-file
+-	      :components
+-	      ((:file "bezier")
+-	       ;; KLUDGE: this requires "bezier" for proper operation,
+-	       ;; but we don't declare that dependency here, because
+-	       ;; asdf doesn't load example files anyway.
+-	       (:file "beziertest")
+-	       (:file "clclock")
+-               (:file "clipboard")
+-	       (:file "clx-demos")
+-	       (:file "gl-test")
+-	       ;; FIXME: compiling this generates 30-odd spurious code
+-	       ;; deletion notes.  Find out why, and either fix or
+-	       ;; workaround the problem.
+-	       (:file "mandel")
+-	       (:file "menu")
+-	       (:file "zoid")))
+      (:module test
+ 	      :default-component-class example-source-file
+ 	      :components
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 11/13] gnu: Add cl-stumpwm.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (9 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 10/13] gnu: Add cl-clx Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-07  8:07     ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 12/13] gnu: Add cl-slynk Andy Patterson
                     ` (3 subsequent siblings)
  14 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-stumpwm, sbcl-stumpwm, ecl-stumpwm): New
  variables.
---
 gnu/packages/lisp.scm | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index fa7f727..3a59c86 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -785,3 +785,67 @@ from other CLXes around the net.")
 
 (define-public ecl-clx
   (sbcl-package->ecl-package sbcl-clx))
+
+(define-public sbcl-stumpwm
+  (package
+    (name "sbcl-stumpwm")
+    (version "0.9.9")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/stumpwm/stumpwm/archive/"
+                    version ".tar.gz"))
+              (sha256
+               (base32 "1fqabij4zcsqg1ywgdv2irp1ys23dwc8ms9ai55lb2i47hgv7z3x"))
+              (file-name (string-append "stumpwm-" version ".tar.gz"))))
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("sbcl-cl-ppcre" ,sbcl-cl-ppcre)
+              ("sbcl-clx" ,sbcl-clx)))
+    (outputs '("out" "bin"))
+    (arguments
+     '(#:special-dependencies '("sb-posix")
+       #:entry-program
+       '((stumpwm:stumpwm)
+         0)
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'generate-binary 'create-desktop-file
+           (lambda* (#:key outputs lisp binary? #:allow-other-keys)
+             (let ((output (assoc-ref outputs (if binary? "out" "bin")))
+                   (xsessions "/share/xsessions")
+                   (name (package-name->name+version
+                          (strip-store-file-name (assoc-ref outputs "out")))))
+               (mkdir-p (string-append output xsessions))
+               (with-output-to-file
+                   (string-append output xsessions
+                                  "/stumpwm.desktop")
+                 (lambda _
+                   (format #t
+                    "[Desktop Entry]~@
+                     Name=stumpwm~@
+                     Comment=The Stump Window Manager~@
+                     Exec=~a/bin/~a~@
+                     TryExec=~@*~a/bin/~a~@
+                     Icon=~@
+                     Type=Application~%"
+                    output
+                    (if binary? name (remove-lisp-from-name name lisp)))))
+               #t))))))
+    (synopsis "Window manager written in Common Lisp")
+    (description "Stumpwm is a window manager written entirely in Common Lisp.
+It attempts to be highly customizable while relying entirely on the keyboard
+for input.  These design decisions reflect the growing popularity of
+productive, customizable lisp based systems.")
+    (home-page "http://github.com/stumpwm/stumpwm")
+    (license license:gpl2+)
+    (properties `((ecl-variant . ,(delay ecl-stumpwm))))))
+
+(define-public cl-stumpwm
+  (sbcl-package->cl-source-package sbcl-stumpwm))
+
+(define-public ecl-stumpwm
+  (let ((base (sbcl-package->ecl-package sbcl-stumpwm)))
+    (package
+      (inherit base)
+      (outputs '("out"))
+      (arguments '()))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 12/13] gnu: Add cl-slynk.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (10 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 11/13] gnu: Add cl-stumpwm Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-07  8:07     ` Andy Patterson
  2016-10-03  2:41   ` [PATCH v2 13/13] gnu: Add sbcl-stumpwm-with-slynk Andy Patterson
                     ` (2 subsequent siblings)
  14 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (cl-slynk, sbcl-slynk, ecl-slynk): New
  variables.
---
 gnu/packages/lisp.scm | 283 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 283 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 3a59c86..05c3101 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -849,3 +849,286 @@ productive, customizable lisp based systems.")
       (inherit base)
       (outputs '("out"))
       (arguments '()))))
+
+(define slynk-change-directory
+  '(lambda _
+     (chdir "slynk")
+     #t))
+
+(define sbcl-slynk-boot0
+  (package
+    (name "sbcl-slynk")
+    (version "1.0.0-beta")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "https://github.com/capitaomorte/sly/archive/"
+                           version ".tar.gz"))
+       (sha256
+        (base32 "0mc3w6afgx97y2bh3pjv29dndidm016adpd11zn86kp7zq6xf8sv"))
+       (file-name (string-append "slynk-" version ".tar.gz"))
+       (modules '((guix build utils)))
+       (snippet
+        '(begin
+           ;; Move the contribs into the main source directory for easier
+           ;; access
+           (substitute* "slynk/slynk.asd"
+             (("\\.\\./contrib")
+              "contrib"))
+           (substitute* "contrib/slynk-trace-dialog.lisp"
+             (("\\(slynk::reset-inspector\\)") ; Causes problems on load
+              "nil"))
+           (mkdir-p "slynk/contrib")
+           (copy-recursively "contrib" "slynk/contrib")))))
+    (build-system asdf-build-system/sbcl)
+    (arguments
+     `(#:tests? #f ; No test suite
+       #:phases
+       (modify-phases %standard-phases
+         (add-before 'copy-source 'change-directory
+           ,slynk-change-directory)
+         (delete 'cleanup))))
+    (synopsis "Common Lisp IDE for Emacs")
+    (description "SLY is a fork of SLIME.  It also featrues a completely
+redesigned REPL based on Emacs's own full-featured comint.el, live code
+annotations, and a consistent interactive button interface.  Everything can be
+copied to the REPL.  One can create multiple inspectors with independent
+history.")
+    (home-page "https://github.com/capitaomorte/sly")
+    (license license:public-domain)
+    (properties `((cl-source-variant . ,(delay cl-slynk))))))
+
+(define-public cl-slynk
+  (let ((base (sbcl-package->cl-source-package sbcl-slynk-boot0)))
+    (package
+      (inherit base)
+      (arguments
+       `(#:phases
+         (modify-phases %standard-phases/source
+           (add-before 'install 'change-directory
+             ,slynk-change-directory)))))))
+
+(define ecl-slynk-boot0
+  (sbcl-package->ecl-package sbcl-slynk-boot0))
+
+(define sbcl-slynk-arglists
+  (package
+    (inherit sbcl-slynk-boot0)
+    (name "sbcl-slynk-arglists")
+    (inputs `(("sbcl-slynk" ,sbcl-slynk-boot0)))
+    (arguments
+     (substitute-keyword-arguments
+         `(#:compile-dependencies '("slynk")
+           #:modules ((ice-9 match)
+                      ,@%asdf-build-modules)
+           ,@(package-arguments sbcl-slynk-boot0))
+       ((#:phases phases)
+        `(modify-phases %standard-phases
+           (add-before 'copy-source 'change-directory
+             (assoc-ref ,phases 'change-directory))
+           (add-before 'build 'copy-output
+             ;; Copy in slynk's output, so it doesn't have to be re-compiled
+             ;; in each contrib package.
+             (lambda* (#:key outputs inputs lisp #:allow-other-keys)
+               (let ((out (assoc-ref outputs "out"))
+                     (slynk (assoc-ref inputs
+                                       (string-append lisp "-slynk"))))
+                 (copy-recursively slynk out)
+                 ;; Hide all asd files providing slynk other than the source
+                 (for-each delete-file
+                           (append (find-files
+                                    (string-append out "/lib/") "\\.asd$")
+                                   (find-files
+                                    (string-append out
+                                                   "/share/common-lisp/"
+                                                   lisp "-bundle-systems/"))))
+                 (unsetenv "XDG_DATA_DIRS")
+                 #t)))
+           (add-after 'copy-output 'delete-bundle
+             ;; Ensure only one system is provided
+             (lambda* (#:key outputs lisp #:allow-other-keys)
+               (let ((out (assoc-ref outputs "out")))
+                 (match lisp
+                   ("sbcl"
+                    (delete-file
+                     (string-append out "/lib/" lisp "/slynk--system.fasl")))
+                   ("ecl"
+                    (begin
+                      (delete-file
+                       (string-append out "/lib/" lisp "/slynk.fasb"))
+                      (delete-file
+                       (string-append out "/lib/" lisp "/slynk.a")))))
+                 #t)))))))))
+
+(define ecl-slynk-arglists
+  (sbcl-package->ecl-package sbcl-slynk-arglists))
+
+(define sbcl-slynk-util
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-util")))
+
+(define ecl-slynk-util
+  (sbcl-package->ecl-package sbcl-slynk-util))
+
+(define sbcl-slynk-fuzzy
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-fuzzy")
+    (inputs `(("sbcl-slynk-util" ,sbcl-slynk-util)
+              ,@(package-inputs sbcl-slynk-arglists)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments sbcl-slynk-arglists)
+       ((#:compile-dependencies _)
+        ''("slynk" "slynk-util"))))))
+
+(define ecl-slynk-fuzzy
+  (sbcl-package->ecl-package sbcl-slynk-fuzzy))
+
+(define sbcl-slynk-c-p-c
+  (package
+    (inherit sbcl-slynk-fuzzy)
+    (name "sbcl-slynk-c-p-c")))
+
+(define ecl-slynk-c-p-c
+  (sbcl-package->ecl-package sbcl-slynk-c-p-c))
+
+(define sbcl-slynk-fancy-inspector
+  (package
+    (inherit sbcl-slynk-fuzzy)
+    (name "sbcl-slynk-fancy-inspector")))
+
+(define ecl-slynk-fancy-inspector
+  (sbcl-package->ecl-package sbcl-slynk-fancy-inspector))
+
+(define sbcl-slynk-package-fu
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-package-fu")))
+
+(define ecl-slynk-package-fu
+  (sbcl-package->ecl-package sbcl-slynk-package-fu))
+
+(define sbcl-slynk-mrepl
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-mrepl")))
+
+(define ecl-slynk-mrepl
+  (sbcl-package->ecl-package sbcl-slynk-mrepl))
+
+(define sbcl-slynk-trace-dialog
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-trace-dialog")))
+
+(define ecl-slynk-trace-dialog
+  (sbcl-package->ecl-package sbcl-slynk-trace-dialog))
+
+(define sbcl-slynk-profiler
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-profiler")))
+
+(define ecl-slynk-profiler
+  (sbcl-package->ecl-package sbcl-slynk-profiler))
+
+(define sbcl-slynk-stickers
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-stickers")))
+
+(define ecl-slynk-stickers
+  (sbcl-package->ecl-package sbcl-slynk-stickers))
+
+(define sbcl-slynk-indentation
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-indentation")))
+
+(define ecl-slynk-indentation
+  (sbcl-package->ecl-package sbcl-slynk-indentation))
+
+(define sbcl-slynk-retro
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-retro")))
+
+(define ecl-slynk-retro
+  (sbcl-package->ecl-package sbcl-slynk-retro))
+
+(define-public sbcl-slynk
+  (let ((dependencies
+         '("slynk-util"
+           "slynk-arglists"
+           "slynk-c-p-c"
+           "slynk-fuzzy"
+           "slynk-fancy-inspector"
+           "slynk-package-fu"
+           "slynk-mrepl"
+           "slynk-profiler"
+           "slynk-trace-dialog"
+           "slynk-stickers"
+           "slynk-indentation"
+           "slynk-retro")))
+    (package
+      (inherit sbcl-slynk-boot0)
+      (name "sbcl-slynk")
+      (inputs `(("slynk" ,sbcl-slynk-boot0)
+                ("slynk-util" ,sbcl-slynk-util)
+                ("slynk-arglists" ,sbcl-slynk-arglists)
+                ("slynk-c-p-c" ,sbcl-slynk-c-p-c)
+                ("slynk-fuzzy" ,sbcl-slynk-fuzzy)
+                ("slynk-fancy-inspector" ,sbcl-slynk-fancy-inspector)
+                ("slynk-package-fu" ,sbcl-slynk-package-fu)
+                ("slynk-mrepl" ,sbcl-slynk-mrepl)
+                ("slynk-profiler" ,sbcl-slynk-profiler)
+                ("slynk-trace-dialog" ,sbcl-slynk-trace-dialog)
+                ("slynk-stickers" ,sbcl-slynk-stickers)
+                ("slynk-indentation" ,sbcl-slynk-indentation)
+                ("slynk-retro" ,sbcl-slynk-retro)))
+      (outputs '("out" "image"))
+      (arguments
+       (substitute-keyword-arguments
+           `(#:image-dependencies ',dependencies
+             ,@(package-arguments sbcl-slynk-boot0))
+         ((#:phases _)
+          `(modify-phases %standard-phases
+             (add-before 'build 'copy-slynk
+               (lambda* (#:key outputs inputs #:allow-other-keys)
+                 (let ((out (assoc-ref outputs "out"))
+                       (slynk (assoc-ref inputs "slynk")))
+                   (copy-recursively slynk out))))
+             (add-after 'generate-image 'link-contribs
+               (lambda* (#:key outputs inputs lisp #:allow-other-keys)
+                 (let* ((out (assoc-ref outputs "out"))
+                        (asd-file (string-append out "/lib/" lisp "/slynk.asd"))
+                        (link-file (string-append
+                                    out "/share/common-lisp/" lisp
+                                    "-bundle-systems/slynk.asd")))
+                   ;; Patch the asd file for slynk so that it can find
+                   ;; contribs, but doesn't load them. Avoids circular
+                   ;; loading.
+                   (patch-asd-file
+                    asd-file
+                    (map
+                     (lambda (dependency)
+                       `(,dependency
+                         . ,(string-append
+                             (assoc-ref inputs dependency))))
+                     ',dependencies)
+                    lisp
+                    '())
+                   (delete-file link-file)
+                   (symlink asd-file link-file))))
+             (delete 'copy-source)
+             (delete 'build)
+             (delete 'check)
+             (delete 'link-dependencies)
+             (delete 'create-symlinks)))))
+      (properties `((ecl-variant . ,(delay ecl-slynk)))))))
+
+(define-public ecl-slynk
+  (package
+    (inherit (sbcl-package->ecl-package sbcl-slynk))
+    (outputs '("out"))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v2 13/13] gnu: Add sbcl-stumpwm-with-slynk.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (11 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 12/13] gnu: Add cl-slynk Andy Patterson
@ 2016-10-03  2:41   ` Andy Patterson
  2016-10-07  8:07     ` Andy Patterson
  2016-10-06 21:04   ` [PATCH v2 00/13]: Add asdf-build-system Ludovic Courtès
  2016-10-08 13:30   ` 宋文武
  14 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-10-03  2:41 UTC (permalink / raw)
  To: guix-devel

* gnu/packages/lisp.scm (sbcl-stumpwm+slynk): New variable.
---
 gnu/packages/lisp.scm | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 05c3101..52903d1 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -1132,3 +1132,27 @@ history.")
   (package
     (inherit (sbcl-package->ecl-package sbcl-slynk))
     (outputs '("out"))))
+
+(define-public sbcl-stumpwm+slynk
+  (package
+    (inherit sbcl-slynk)
+    (name "sbcl-stumpwm-with-slynk")
+    (native-inputs `(("stumpwm" ,sbcl-stumpwm)
+                     ("slynk" ,sbcl-slynk)
+                     ,@(package-inputs sbcl-slynk)))
+    (outputs '("out"))
+    (arguments
+     (substitute-keyword-arguments
+         `(#:binary? #t
+           #:entry-program
+           '((stumpwm:stumpwm)
+             0)
+           ,@(package-arguments sbcl-slynk))
+       ((#:image-dependencies dependencies)
+         ``("stumpwm"
+            "slynk"
+            ,@,dependencies))
+       ((#:phases _)
+        (match (memq #:phases (package-arguments sbcl-stumpwm))
+          ((#:phases phases . _)
+           phases)))))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-03  2:41   ` [PATCH v2 01/13] build-system: " Andy Patterson
@ 2016-10-05  4:55     ` 宋文武
  2016-10-05 20:59       ` Andy Patterson
  2016-10-07  8:07     ` Andy Patterson
  1 sibling, 1 reply; 51+ messages in thread
From: 宋文武 @ 2016-10-05  4:55 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel


Hi!  I have spent more time wondering on this patch and ASDF, so here
are some questions, opinions and ideas (roughly).

Andy Patterson <ajpatter@uwaterloo.ca> writes:

> * guix/build-system/asdf.scm: New file.
> * guix/build/asdf-build-system.scm: New file.
> * guix/build/lisp-utils.scm: New file.
> * Makefile.am: Add them.

Should be: Makefile.am (MODULES): Add them.

> * doc/guix.texi: Add section on 'asdf-build-system/source'.

Well, it dosen't create a new info section, I think this can be:

* doc/guix.texi (Build Systems): Document 'asdf-build-system'.

> ---
>  Makefile.am                      |   3 +
>  doc/guix.texi                    |  60 ++++++
>  guix/build-system/asdf.scm       | 385 +++++++++++++++++++++++++++++++++++++
>  guix/build/asdf-build-system.scm | 400 +++++++++++++++++++++++++++++++++++++++
>  guix/build/lisp-utils.scm        | 240 +++++++++++++++++++++++
>  5 files changed, 1088 insertions(+)
>  create mode 100644 guix/build-system/asdf.scm
>  create mode 100644 guix/build/asdf-build-system.scm
>  create mode 100644 guix/build/lisp-utils.scm
>
> diff --git a/Makefile.am b/Makefile.am
> index 43a33c8..a23e5fd 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -63,6 +63,7 @@ MODULES =					\
>    guix/build-system/ant.scm			\
>    guix/build-system/cmake.scm			\
>    guix/build-system/emacs.scm			\
> +  guix/build-system/asdf.scm			\
>    guix/build-system/glib-or-gtk.scm		\
>    guix/build-system/gnu.scm			\
>    guix/build-system/haskell.scm			\
> @@ -84,6 +85,7 @@ MODULES =					\
>    guix/build/download.scm			\
>    guix/build/cmake-build-system.scm		\
>    guix/build/emacs-build-system.scm		\
> +  guix/build/asdf-build-system.scm		\
>    guix/build/git.scm				\
>    guix/build/hg.scm				\
>    guix/build/glib-or-gtk-build-system.scm	\
> @@ -106,6 +108,7 @@ MODULES =					\
>    guix/build/syscalls.scm                       \
>    guix/build/gremlin.scm			\
>    guix/build/emacs-utils.scm			\
> +  guix/build/lisp-utils.scm			\
>    guix/build/graft.scm				\
>    guix/build/bournish.scm			\
>    guix/build/qt-utils.scm			\
> diff --git a/doc/guix.texi b/doc/guix.texi
> index f5bbb92..53db367 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -2965,6 +2965,66 @@ that should be run during the @code{build} phase.  By default the
>
>  @end defvr
>
> +@defvr {Scheme Variable} asdf-build-system/source
> +@defvrx {Scheme Variable} asdf-build-system/sbcl
> +@defvrx {Scheme Variable} asdf-build-system/ecl
> +
> +These variables, exported by @code{(guix build-system sbcl)}, implement

Typo, sbcl -> asdf.

> +build procedures for Common Lisp packages using the
> +@url{https://common-lisp.net/project/asdf/, ``ASDF''} system.

How about expand it a bit to: @url{..., ``ASDF''}, a system definition
facility for Common Lisp programs and libraries.

> +
> +The @code{asdf-build-system/source} system installs the packages in
> +source form, and can be loaded using any common lisp implementation, via
> +ASDF.  The others, such as @code{asdf-build-system/sbcl}, install binary
> +systems in the format which a particular implementation understands.
> +These build systems can also be used to produce executable programs, or
> +lisp images which contain a set of packages pre-loaded.
> +
> +The build system uses conventions to determine the roles of inputs in
> +the build system.

… uses naming conventions …  What’s the “roles of inputs” for?

> For binary packages, the package itself as well as
> +its dependencies should begin their name with the lisp implementation,
> +such as @code{sbcl-} for @code{asdf-build-system/sbcl}.  If dependencies
> +are used only for tests, it is convenient to use a different prefix in
> +order to avoid having a run-time dependency on such systems.

> + For example,
> +
> +@example
> +(define-public sbcl-bordeaux-threads
> +  (package
> +    ...
> +    (native-inputs `(("tests:cl-fiveam" ,sbcl-fiveam)))
> +    ...))
> +@end example

This is a bit confusing, so every input starts with ‘sbcl-’ will be
propagated?  I wonder why not just use ‘propgated-inputs’ for that.

> +
> +Additionally, the corresponding source package should be labelled using
> +the same convention as python packages (see @ref{Python Modules}), using
> +the @code{cl-} prefix.
> +
> +One package should be defined for each ASDF system.

This is for binary packages right?  (It’s obviously not convenient for
source packages which usually have an extra system for test only.)
++ I seems wrong here, new ideas below ‘package-with-build-system’. ++

For binary packages, this will be perfect if they’re 1-to-1 mapped to
a CL system, but then their names are inconsistent with the ’cl-’
ones, whose names are from projects instead of the systems they
contain.

Consider the ‘cl-autowrap’ (https://github.com/rpav/cl-autowrap)
project.  It has 3 systems: ‘cl-autowrap’, ‘cl-autowrap-test’ and
‘cl-plus-c’.  IIUC, follow this one package per system way, we will
package it as:

- cl-autowrap, contains the 3 systems in source form.
- sbcl-autowrap (or maybe sbcl-cl-autowrap?).
- sbcl-plus-c (or ‘sbcl-cl-plus-c?).
- sbcl-autowrap-test (for testing).

It’s hard to know that ‘cl-autowrap’ has ‘cl-plus-c’ in it…

> +
> +The package outputs control whether or not executable programs and
> +images are built alongside the package's usual output, using the
> +@code{bin} and @code{image} outputs, respectively.
> +
> +Packages can also be built which combine other packages into an
> +executable program or image only, without building another system.
> +Specifying one of the @code{#:binary?} or @code{#:image?} parameters
> +will produce this behaviour.
> +
> +When building an executable program, the @code{#:entry-program}
> +parameter, which should be a list of Common Lisp expressions, must be
> +used to specify what program should be run.  In this program,
> +@code{arguments} will be bound to the command-line arguments passed.
> +
> +The @code{#:image-dependencies} parameter can be used to add packages to
> +the pre-loaded systems included in the executable program or image.
> +@code{#:compile-dependencies} specifies a list of additional systems
> +which should be loaded before a system is compiled.  If the package
> +depends on special systems exported by the implementation itself, the
> +@code{#:special-dependencies} parameter should be used to specify them.

I’d like to make the build action of ‘program’ or ‘image’ more
explicit instead of coding them in the build system.  eg:

--8<---------------cut here---------------start------------->8---
(define-public sbcl-stumpwm
  (package
    …
    (arguments
     '(#:phases
       (modify-phases %standard-phases
         (add-after 'install 'install-program
           (lambda* (#:key outputs #:allow-other-keys)
             ((let* ((bin  (assoc-ref outputs "bin"))
                     (prog (string-append bin "/bin/stumpwm")))
                (asdf:build-program prog
                  #:entry-program '((stumpwm:stumpwm))
                  #:special-dependencies '("sb-posix")))))))
        …))))
--8<---------------cut here---------------end--------------->8---

I think this way show what #:entry-program and other parameters are used
for more clearly, as they have nothing to do with other phases (compile
the system and install a bundle asd file).  Most CL packages are
libraries, so I feel that having phases (generate-binary and
generate-image) which do nothing most times is overkill :-)

What’s the ‘compile-dependencies’ used for?  I think when compile a
system, ASDF will load all its depends (from the :depends-on) first.
Sometimes we need load extra systems manually?

> […]
> diff --git a/guix/build-system/asdf.scm b/guix/build-system/asdf.scm
> new file mode 100644
> index 0000000..eb8b7d9
> --- /dev/null
> +++ b/guix/build-system/asdf.scm
> @@ -0,0 +1,385 @@
> […]
> +
> +(define* (package-with-build-system from-build-system to-build-system
> +                                    from-prefix to-prefix
> +                                    #:key variant-property
> +                                    phases-transformer)
> +  "Return a precedure which takes a package PKG which uses FROM-BUILD-SYSTEM,
> +and returns one using TO-BUILD-SYSTEM. If PKG was prefixed by FROM-PREFIX, the
> +resulting package will be prefixed by TO-PREFIX. Inputs of PKG are recursively
> +transformed using the same rule.

Oops, so we should use one package per system for source packages too,
otherwise there is no obvious way to transform between them (I’d like it
be one way, just ‘cl-package->sbcl-package’) and binary packages.  If
that’s true, for the ‘cl-autowrap’ project, its source packages should
be ‘cl-autowrap’, ’cl-plus-c’, and ‘cl-autowrap-test’.  And I don’t
think we should copy the whole project source for each of them.  So, how
about:

- For a CL project, define a (non-public) project package, which just
  unpacks the source to its ‘$out’.

- For each system the project contains, define a ‘cl-SYSTEM-NAME-W/O-CL’
  package, which takes the project package as ‘source’ and symlink the
  system’s asd file to its ‘$out/share/common-lisp/systems’.

- Then for each ‘cl-’ package, we can transform it to a binary package,
  which should compile and install a bundle asd file for one system.

> +The result's #:phases argument will be
> +modified by PHASES-TRANSFORMER, a list which evaluates on the build side to a
> +procedure of one argument.

A symbol?

> +
> +VARIANT-PROPERTY can be added to a package's properties to indicate that the
> +corresponding package promise should be used as the result of this
> +transformation. This allows the result to differ from what the transformation
> +would otherwise produce.
> +
> +If TO-BUILD-SYSTEM is asdf-build-system/source, the resulting package will be
> +set up using CL source package conventions."
> +  (define target-is-source? (eq? 'asdf/source
> +                                 (build-system-name to-build-system)))
> +
> +  (define (transform-package-name name)
> +    (if (string-prefix? from-prefix name)
> +        (let ((new-name (string-drop name (string-length from-prefix))))
> +          (if (string-prefix? to-prefix new-name)
> +              new-name
> +              (string-append to-prefix new-name)))
> +        name))
> +
> +  (define (has-from-build-system? pkg)
> +    (eq? (build-system-name from-build-system)
> +         (build-system-name (package-build-system pkg))))
> +
> +  (define transform
> +    (memoize
> +     (lambda (pkg)
> +       (define rewrite
> +         (match-lambda
> +           ((name content . rest)
> +            (let* ((is-package? (package? content))
> +                   (new-content (if is-package? (transform content) content))
> +                   (new-name (if (and is-package?
> +                                      (string-prefix? from-prefix name))
> +                                 (package-name new-content)
> +                                 name)))
> +              `(,new-name ,new-content ,@rest)))))
> +
> +       ;; Special considerations for source packages: CL inputs become
> +       ;; propagated, and un-handled arguments are removed. Native inputs are
> +       ;; removed as are extraneous outputs.
> +       (define new-propagated-inputs
> +         (if target-is-source?
> +             (map rewrite
> +                  (filter (match-lambda
> +                            ((_ input . _)
> +                             (has-from-build-system? input)))
> +                          (package-inputs pkg)))
> +             '()))
> +
> +       (define new-inputs
> +         (if target-is-source?
> +             (map rewrite
> +                  (filter (match-lambda
> +                            ((_ input . _)
> +                             (not (has-from-build-system? input))))
> +                          (package-inputs pkg)))
> +             (map rewrite (package-inputs pkg))))

To make a binary package from a source package, my plan looks like:

- remove all inputs not start with ‘cl-’.  Ideally, we can do all the
  things (eg: patch the file names of ffi libraries to absolute paths)
  in source packages to make them ready to use for CLs.  All a binary
  package needs are CL systems and an CL compiler.
  
- rewrite ‘cl-’ inputs to ‘sbcl-’ inputs recursively.

- source package becomes the ‘source’ of the binary package, if in-tree
  build is needed (I hope not very often), we can follow the asd file
  link to copy its real source.

> +
> +       (define base-arguments
> +         (if target-is-source?
> +             (strip-keyword-arguments
> +              '(#:tests? #:special-dependencies #:entry-program
> +                #:image-dependencies #:compile-dependencies #:image?
> +                #:binary? #:test-only-systems #:lisp)
> +              (package-arguments pkg))
> +             (package-arguments pkg)))

If we don’t allow ‘sbcl-package->cl-package’, arguments don’t need to be
stripped.

> +
> +       (cond
> +        ((and variant-property
> +              (assoc-ref (package-properties pkg) variant-property))
> +         => force)
> +
> +        ((has-from-build-system? pkg)
> +         (package
> +           (inherit pkg)
> +           (location (package-location pkg))
> +           (name (transform-package-name (package-name pkg)))
> +           (build-system to-build-system)
> +           (arguments
> +            (substitute-keyword-arguments base-arguments
> +              ((#:phases phases) (list phases-transformer phases))))
> +           (inputs new-inputs)
> +           (propagated-inputs new-propagated-inputs)
> +           (native-inputs (if target-is-source?
> +                              '()
> +                              (map rewrite (package-native-inputs pkg))))
> +           (outputs (if target-is-source?
> +                        '("out")
> +                        (package-outputs pkg)))))
> +        (else pkg)))))
> +
> +  transform)
> +
> +(define (strip-variant-as-necessary variant pkg)
> +  (define properties (package-properties pkg))
> +  (if (assoc variant properties)
> +      (package
> +        (inherit pkg)
> +        (properties (alist-delete variant properties)))
> +      pkg))
> +
> +(define (lower lisp-implementation)
> +  (lambda* (name
> +            #:key source inputs outputs native-inputs system target
> +            (lisp (default-lisp (string->symbol lisp-implementation)))
> +            #:allow-other-keys
> +            #:rest arguments)
> +    "Return a bag for NAME"
> +    (define private-keywords
> +      '(#:target #:inputs #:native-inputs #:lisp))
> +
> +    (and (not target)
> +         (bag
> +           (name name)
> +           (system system)
> +           (host-inputs `(,@(if source
> +                                `(("source" ,source))
> +                                '())
> +                          ,@inputs
> +                          ,@(standard-packages)))
> +           (build-inputs `((,lisp-implementation ,lisp)
> +                           ,@native-inputs))
> +           (outputs outputs)
> +           (build (asdf-build lisp-implementation))
> +           (arguments (strip-keyword-arguments private-keywords arguments))))))
> +
> +(define (asdf-build lisp-implementation)
> +  (lambda* (store name inputs
> +                  #:key source outputs
> +                  (tests? #t)
> +                  (special-dependencies ''())
> +                  (entry-program #f)
> +                  (image-dependencies ''())
> +                  (compile-dependencies ''())
> +                  (image? #f)
> +                  (binary? #f)
> +                  (test-only-systems ''())
> +                  (lisp lisp-implementation)
> +                  (phases '(@ (guix build asdf-build-system)
> +                              %standard-phases))
> +                  (search-paths '())
> +                  (system (%current-system))
> +                  (guile #f)
> +                  (imported-modules %asdf-build-system-modules)
> +                  (modules %asdf-build-modules))
> +
> +    (define builder
> +      `(begin
> +         (use-modules ,@modules)
> +         (asdf-build #:name ,name
> +                     #:source ,(match (assoc-ref inputs "source")
> +                                 (((? derivation? source))
> +                                  (derivation->output-path source))
> +                                 ((source) source)
> +                                 (source source))
> +                     #:lisp ,lisp
> +                     #:special-dependencies ,special-dependencies
> +                     #:compile-dependencies ,compile-dependencies
> +                     #:test-only-systems ,test-only-systems

++ quetions below ‘patch-asd-files’. ++

> +                     #:entry-program ,entry-program
> +                     #:image-dependencies ,image-dependencies
> +                     #:image? ,image?
> +                     #:binary? ,binary?


Those will be removed if we build ‘program’ or ’image’ explicitly.  In
that case, IIUC, we should add variant properties to the source package
if we add phases (by inherit) to the binary package and want the
transform get the same (not get the same one is fine too, which only
lacks the optional programs or binaries) package.


> +                     #:system ,system
> +                     #:tests? ,tests?
> +                     #:phases ,phases
> +                     #:outputs %outputs
> +                     #:search-paths ',(map search-path-specification->sexp
> +                                           search-paths)
> +                     #:inputs %build-inputs)))
> +
> +    (define guile-for-build
> +      (match guile
> +        ((? package?)
> +         (package-derivation store guile system #:graft? #f))
> +        (#f
> +         (let* ((distro (resolve-interface '(gnu packages commencement)))
> +                (guile (module-ref distro 'guile-final)))
> +           (package-derivation store guile system #:graft? #f)))))
> +
> +    (build-expression->derivation store name builder
> +                                  #:inputs inputs
> +                                  #:system system
> +                                  #:modules imported-modules
> +                                  #:outputs outputs
> +                                  #:guile-for-build guile-for-build)))
> +
> +(define asdf-build-system/sbcl
> +  (build-system
> +    (name 'asdf/sbcl)
> +    (description "The build system for asdf binary packages using sbcl")
> +    (lower (lower "sbcl"))))
> +
> +(define asdf-build-system/ecl
> +  (build-system
> +    (name 'asdf/ecl)
> +    (description "The build system for asdf binary packages using ecl")
> +    (lower (lower "ecl"))))
> +
> +(define asdf-build-system/source
> +  (build-system
> +    (name 'asdf/source)
> +    (description "The build system for asdf source packages")
> +    (lower lower/source)))
> +
> +(define source-package->sbcl-package
> +  (let* ((property 'sbcl-variant)
> +         (transformer
> +          (package-with-build-system asdf-build-system/source
> +                                     asdf-build-system/sbcl
> +                                     "cl-"
> +                                     "sbcl-"
> +                                     #:variant-property property
> +                                     #:phases-transformer
> +                                     'source-phases->sbcl-phases)))

The ‘source-phases->sbcl-phases’ proceduce seems missing, is it ‘(const
%standard-phases)’?

> +    (lambda (pkg)
> +      (transformer
> +       (strip-variant-as-necessary property pkg)))))
> +
> +(define sbcl-package->cl-source-package
> +  (let* ((property 'cl-source-variant)
> +         (transformer
> +          (package-with-build-system asdf-build-system/sbcl
> +                                     asdf-build-system/source
> +                                     "sbcl-"
> +                                     "cl-"
> +                                     #:variant-property property
> +                                     #:phases-transformer
> +                                     '(const %standard-phases/source))))
> +    (lambda (pkg)
> +      (transformer
> +       (strip-variant-as-necessary property pkg)))))
> +
> +(define sbcl-package->ecl-package
> +  (let* ((property 'ecl-variant)
> +         (transformer
> +          (package-with-build-system asdf-build-system/sbcl
> +                                     asdf-build-system/ecl
> +                                     "sbcl-"
> +                                     "ecl-"
> +                                     #:variant-property property
> +                                     #:phases-transformer
> +                                     'identity)))
> +    (lambda (pkg)
> +      (transformer
> +       (strip-variant-as-necessary property pkg)))))
> +
> +;;; asdf.scm ends here


> […]
> +(define* (patch-asd-files #:key outputs
> +                          inputs
> +                          lisp
> +                          special-dependencies
> +                          image?
> +                          binary?
> +                          test-only-systems
> +                          #:allow-other-keys)
> +  "Patch any asd files created by the compilation process so that they
> +can find their dependencies. Exclude any TEST-ONLY-SYSTEMS which were only
> +included to run tests. Add any SPECIAL-DEPENDENCIES which the LISP
> +implementation itself provides."
> +  (unless (or image? binary?)
> +    (let* ((out (assoc-ref outputs "out"))
> +           (name (remove-lisp-from-name (output-path->package-name out) lisp))
> +           (registry (lset-difference
> +                      (lambda (input system)
> +                        (match input
> +                          ((name . path) (string=? name system))))
> +                      (lisp-dependencies lisp inputs)
> +                      test-only-systems))
> +           (lisp-systems (map first registry)))
> +
> +      (for-each
> +       (lambda (asd-file)
> +         (patch-asd-file asd-file registry lisp
> +                         (append lisp-systems special-dependencies)))
> +       (find-files out "\\.asd$"))))
> +  #t)

Doesn’t ‘special-dependencies’ always available, do we need load them
explicitly?

I think it’s strange that ‘deliver-asd-op’ make a asd file without all
its original depends, if the original are valid, maybe we can copy them
back?

> […]
> +(define* (generate-binary #:key outputs
> +                          inputs
> +                          image-dependencies
> +                          entry-program
> +                          lisp
> +                          binary?
> +                          #:allow-other-keys)
> +  "Generate a binary program for the system, either in \"bin\" if the package
> +also contains a library system, or in \"out\" otherwise."
> +  (define output (if binary? "out" "bin"))
> +  (generate-executable #:outputs outputs
> +                       #:inputs inputs
> +                       #:image-dependencies image-dependencies
> +                       #:entry-program entry-program
> +                       #:lisp lisp
> +                       #:output output
> +                       #:needs-own-system? (not binary?)
> +                       #:type "program")
> +  (and=>
> +   (assoc-ref outputs output)
> +   (lambda (bin)
> +     (let* ((full-name (outputs->name outputs))
> +            (name (if binary? full-name
> +                      (remove-lisp-from-name full-name lisp)))
> +            (bin-directory (string-append bin "/bin")))
> +       (with-directory-excursion bin-directory
> +         (rename-file (string-append name "-exec")
> +                      name)))))
> +  #t)
> +
> +(define* (generate-image #:key outputs
> +                         inputs
> +                         image-dependencies
> +                         lisp
> +                         image?
> +                         #:allow-other-keys)
> +  "Generate an image for the system, possibly standalone, either in \"image\"
> +if the package also contains a library system, or in \"out\" otherwise."
> +  (define output (if image? "out" "image"))
> +  (generate-executable #:outputs outputs
> +                       #:inputs inputs
> +                       #:image-dependencies image-dependencies
> +                       #:entry-program '(nil)
> +                       #:lisp lisp
> +                       #:output output
> +                       #:needs-own-system? (not image?)
> +                       #:type "image")
> +  (and=>
> +   (assoc-ref outputs output)
> +   (lambda (image)
> +     (let* ((full-name (outputs->name outputs))
> +            (name (if image? full-name
> +                      (remove-lisp-from-name full-name lisp)))
> +            (bin-directory (string-append image "/bin")))
> +       (with-directory-excursion bin-directory
> +         (rename-file (string-append name "-exec--all-systems.image")
> +                      (string-append name ".image"))))))
> +  #t)
> +
> +(define* (generate-executable #:key outputs
> +                              image-dependencies
> +                              entry-program
> +                              lisp
> +                              output
> +                              inputs
> +                              type
> +                              needs-own-system?
> +                              #:allow-other-keys)
> +  "Generate an executable by using asdf's TYPE-op, containing whithin the
> +image all IMAGE-DEPNDENCIES, and running ENTRY-PROGRAM in the case of an
> +executable."
> +  (and=>
> +   (assoc-ref outputs output)
> +   (lambda (out)
> +     (let* ((bin-directory (string-append out "/bin"))
> +            (full-name (outputs->name outputs))
> +            (name (if needs-own-system?
> +                      (remove-lisp-from-name full-name lisp)
> +                      full-name)))
> +       (mkdir-p out)
> +       (with-directory-excursion out
> +         (generate-executable-wrapper-system name
> +                                             image-dependencies
> +                                             needs-own-system?)
> +         (generate-executable-entry-point name entry-program))
> +
> +       (setenv "CL_SOURCE_REGISTRY"
> +               (replace-escaped-macros
> +                (format
> +                 #f "~S"
> +                 (wrap-source-registry
> +                  `(,(source-registry (assoc-ref outputs "out"))
> +                    ,(source-registry out))))))
> +
> +       (setenv "ASDF_OUTPUT_TRANSLATIONS"
> +               (replace-escaped-macros
> +                (format
> +                 #f "~S"
> +                 (wrap-output-translations
> +                  `(((,out :**/ :*.*.*)
> +                     (,bin-directory :**/ :*.*.*)))))))
> +
> +       (parameterize ((%lisp (string-append
> +                              (assoc-ref inputs lisp) "/bin/" lisp)))
> +         (generate-executable-for-system type name lisp))
> +
> +       (delete-file (string-append out "/" name "-exec.asd"))
> +       (delete-file (string-append out "/" name "-exec.lisp"))))))
> +

Yeah, I’d like to merge those into lisp-utils.scm, and become something
like ‘wrap-program’.


Also, the output-translations way sometime produces unnecessary
files, eg: in ecl-fiveam:

--8<---------------cut here---------------start------------->8---
/gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib
/gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl
/gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src
/gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src/fiveam.fasb
/gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src/fiveam.asd
/gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src/fiveam.a
/gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/t
--8<---------------cut here---------------end--------------->8---

I think we only want ’lib/ecl/fiveam.*’.

I have tried ‘asdf/action:output-files’, hoping that will allow install
only the files we want, but it doesn’t seem give all the output files.

Run this with ECL:

--8<---------------cut here---------------start------------->8---
(require :asdf)

(let* ((asdf/output-translations:*output-translations*
	'(((t #P"/tmp/build/**/*.*"))))
       (files
	(asdf/action:output-files
	 'asdf:compile-bundle-op (asdf:find-system :cl-json))))
  (asdf:operate 'asdf:compile-bundle-op :cl-json)
  (format t "~S" files))

(quit)
--8<---------------cut here---------------end--------------->8---

The ‘fasb’ file is returned, but the ‘a’ file is missing.
What the ECL lib (‘a’) files used for?


Despite my opinions and ideas, please let me know if this patch is
considered ready, so we can merge it and improve later.

Thanks!

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-05  4:55     ` 宋文武
@ 2016-10-05 20:59       ` Andy Patterson
  2016-10-07  8:07         ` Andy Patterson
  0 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-10-05 20:59 UTC (permalink / raw)
  To: 宋文武; +Cc: guix-devel

On Wed, 05 Oct 2016 12:55:51 +0800
iyzsong@member.fsf.org (宋文武) wrote:

> Hi!  I have spent more time wondering on this patch and ASDF, so here
> are some questions, opinions and ideas (roughly).
> 

Hi. Thanks again for your comments.

> > * Makefile.am: Add them.  
> 
> Should be: Makefile.am (MODULES): Add them.
> 

Ok.

> > * doc/guix.texi: Add section on 'asdf-build-system/source'.  
> 
> Well, it dosen't create a new info section, I think this can be:
> 
> * doc/guix.texi (Build Systems): Document 'asdf-build-system'.
>

Ok.

> > +These variables, exported by @code{(guix build-system sbcl)},
> > implement  
> 
> Typo, sbcl -> asdf.
> 

Right.

> > +build procedures for Common Lisp packages using the
> > +@url{https://common-lisp.net/project/asdf/, ``ASDF''} system.  
> 
> How about expand it a bit to: @url{..., ``ASDF''}, a system definition
> facility for Common Lisp programs and libraries.
>

Sure.

> > +The build system uses conventions to determine the roles of inputs
> > in +the build system.  
> 
> … uses naming conventions …  What’s the “roles of inputs” for?
> 

I'll explain what is meant a bit further.

> > + For example,
> > +
> > +@example
> > +(define-public sbcl-bordeaux-threads
> > +  (package
> > +    ...
> > +    (native-inputs `(("tests:cl-fiveam" ,sbcl-fiveam)))
> > +    ...))
> > +@end example  
> 
> This is a bit confusing, so every input starts with ‘sbcl-’ will be
> propagated?  I wonder why not just use ‘propgated-inputs’ for that.
>

Packages aren't propagated in the binary systems. The naming
convention is what tells 'patch-asd-file' which systems to wrap the
library with (so that it can find its dependencies). Changing the
prefix will cause that phase to ignore that library, so doing so has
the same effect as '#:test-only-systems' used to have. I'll explain
that in the doc.

> > +
> > +Additionally, the corresponding source package should be labelled
> > using +the same convention as python packages (see @ref{Python
> > Modules}), using +the @code{cl-} prefix.
> > +
> > +One package should be defined for each ASDF system.  
> 
> This is for binary packages right?  (It’s obviously not convenient for
> source packages which usually have an extra system for test only.)
> ++ I seems wrong here, new ideas below ‘package-with-build-system’. ++
>

This is correct, actually. This is essentially what I did for slynk,
which contains quite a few systems.
 
> For binary packages, this will be perfect if they’re 1-to-1 mapped to
> a CL system, but then their names are inconsistent with the ’cl-’
> ones, whose names are from projects instead of the systems they
> contain.
> 
> Consider the ‘cl-autowrap’ (https://github.com/rpav/cl-autowrap)
> project.  It has 3 systems: ‘cl-autowrap’, ‘cl-autowrap-test’ and
> ‘cl-plus-c’.  IIUC, follow this one package per system way, we will
> package it as:
> 
> - cl-autowrap, contains the 3 systems in source form.
> - sbcl-autowrap (or maybe sbcl-cl-autowrap?).
> - sbcl-plus-c (or ‘sbcl-cl-plus-c?).
> - sbcl-autowrap-test (for testing).
> 

That's right (and it would be sbcl-cl-autowrap).

> It’s hard to know that ‘cl-autowrap’ has ‘cl-plus-c’ in it…
> 

In that case, we could add the extra systems to the description of the
source package. Does that sound reasonable?

> > +
> > +The package outputs control whether or not executable programs and
> > +images are built alongside the package's usual output, using the
> > +@code{bin} and @code{image} outputs, respectively.
> > +
> > +Packages can also be built which combine other packages into an
> > +executable program or image only, without building another system.
> > +Specifying one of the @code{#:binary?} or @code{#:image?}
> > parameters +will produce this behaviour.
> > +
> > +When building an executable program, the @code{#:entry-program}
> > +parameter, which should be a list of Common Lisp expressions, must
> > be +used to specify what program should be run.  In this program,
> > +@code{arguments} will be bound to the command-line arguments
> > passed. +
> > +The @code{#:image-dependencies} parameter can be used to add
> > packages to +the pre-loaded systems included in the executable
> > program or image. +@code{#:compile-dependencies} specifies a list
> > of additional systems +which should be loaded before a system is
> > compiled.  If the package +depends on special systems exported by
> > the implementation itself, the +@code{#:special-dependencies}
> > parameter should be used to specify them.  
> 
> I’d like to make the build action of ‘program’ or ‘image’ more
> explicit instead of coding them in the build system.  eg:
> 
> --8<---------------cut here---------------start------------->8---
> (define-public sbcl-stumpwm
>   (package
>     …
>     (arguments
>      '(#:phases
>        (modify-phases %standard-phases
>          (add-after 'install 'install-program
>            (lambda* (#:key outputs #:allow-other-keys)
>              ((let* ((bin  (assoc-ref outputs "bin"))
>                      (prog (string-append bin "/bin/stumpwm")))
>                 (asdf:build-program prog
>                   #:entry-program '((stumpwm:stumpwm))
>                   #:special-dependencies '("sb-posix")))))))
>         …))))
> --8<---------------cut here---------------end--------------->8---
> 
> I think this way show what #:entry-program and other parameters are
> used for more clearly, as they have nothing to do with other phases
> (compile the system and install a bundle asd file).  Most CL packages
> are libraries, so I feel that having phases (generate-binary and
> generate-image) which do nothing most times is overkill :-)
> 

That sounds good.

> What’s the ‘compile-dependencies’ used for?  I think when compile a
> system, ASDF will load all its depends (from the :depends-on) first.
> Sometimes we need load extra systems manually?
> 

It's for packages like slynk, where many systems are defined within the
same file. When telling asdf to find a system, it will only search for
a file with the same name unless it already knows about that system.
Therefore, in these cases the system which contains the definitions is
loaded first. This mechanism is a bit clunky so suggestions are
welcome. For now I'll document the reason it's done that way.

> > […]
> > diff --git a/guix/build-system/asdf.scm b/guix/build-system/asdf.scm
> > new file mode 100644
> > index 0000000..eb8b7d9
> > --- /dev/null
> > +++ b/guix/build-system/asdf.scm
> > @@ -0,0 +1,385 @@
> > […]
> > +
> > +(define* (package-with-build-system from-build-system
> > to-build-system
> > +                                    from-prefix to-prefix
> > +                                    #:key variant-property
> > +                                    phases-transformer)
> > +  "Return a precedure which takes a package PKG which uses
> > FROM-BUILD-SYSTEM, +and returns one using TO-BUILD-SYSTEM. If PKG
> > was prefixed by FROM-PREFIX, the +resulting package will be
> > prefixed by TO-PREFIX. Inputs of PKG are recursively +transformed
> > using the same rule.  
> 
> Oops, so we should use one package per system for source packages too,
> otherwise there is no obvious way to transform between them (I’d like
> it be one way, just ‘cl-package->sbcl-package’) and binary packages.

There doesn't need to be a translation for each package; in the case of
slynk one translation is done for sbcl->cl-source, and then the other
systems provided have binary packages created just using the usual
inherit mechanism, and a translation is made for sbcl->ecl.

I decided to use the sbcl package a the source for all translations,
because it is likely that a binary package will contain more
information (in the form of customizations to the arguments field),
than for source packages, which simplifies the translation process.

> If that’s true, for the ‘cl-autowrap’ project, its source packages
> should be ‘cl-autowrap’, ’cl-plus-c’, and ‘cl-autowrap-test’.  And I
> don’t think we should copy the whole project source for each of
> them.  So, how about:
> 

I agree, that seems unnecessary.

> - For a CL project, define a (non-public) project package, which just
>   unpacks the source to its ‘$out’.
> 
> - For each system the project contains, define a
> ‘cl-SYSTEM-NAME-W/O-CL’ package, which takes the project package as
> ‘source’ and symlink the system’s asd file to its
> ‘$out/share/common-lisp/systems’.
>

The source package already copies all asd files to that directory, so
I think it makes sense to have just one source package (I'll fix the
documentation for that). So for the case of cl-autowrap, that
directory would contain cl-{autowrap-test,autowrap,plus-c}.asd. 

In the guix source, you'd have a sbcl-cl-autowrap package, an
automatically translated cl-autowrap package containing all of the
above, and a manually inherited sbcl-cl-plus-c package. There wouldn't
be a -test package. You'd then also have automatically translated ecl-
packages.

> - Then for each ‘cl-’ package, we can transform it to a binary
> package, which should compile and install a bundle asd file for one
> system.
> 

As described earlier, I think it's easier to go binary->source and
binary->binary.

> > +The result's #:phases argument will be
> > +modified by PHASES-TRANSFORMER, a list which evaluates on the
> > build side to a +procedure of one argument.  
> 
> A symbol?
> 

Right, it could be any quoted sexp. I'll fix that.

> To make a binary package from a source package, my plan looks like:
> 
> - remove all inputs not start with ‘cl-’.  Ideally, we can do all the
>   things (eg: patch the file names of ffi libraries to absolute paths)
>   in source packages to make them ready to use for CLs.  All a binary
>   package needs are CL systems and an CL compiler.
>

Correct; that's currently exactly what CL systems depend on. I'm hoping
that patching ffi files could be done in a mostly automated way once
that's required, so that copying build phases would be unnecessary.
 
> - rewrite ‘cl-’ inputs to ‘sbcl-’ inputs recursively.
> 
> - source package becomes the ‘source’ of the binary package, if
> in-tree build is needed (I hope not very often), we can follow the
> asd file link to copy its real source.
> 

I think it's more flexible to just always build in tree (the system
worked as you describe it here in the first version of the series).
It's not too outlandish to think that systems might want to create
files during the test phase, which is exactly what one package was
doing.

> > +
> > +       (define base-arguments
> > +         (if target-is-source?
> > +             (strip-keyword-arguments
> > +              '(#:tests? #:special-dependencies #:entry-program
> > +                #:image-dependencies #:compile-dependencies
> > #:image?
> > +                #:binary? #:test-only-systems #:lisp)
> > +              (package-arguments pkg))
> > +             (package-arguments pkg)))  
> 
> If we don’t allow ‘sbcl-package->cl-package’, arguments don’t need to
> be stripped.
> 

That's true, but it's easier to strip arguments than to add them.

> ++ quetions below ‘patch-asd-files’. ++
> 
> > +                     #:entry-program ,entry-program
> > +                     #:image-dependencies ,image-dependencies
> > +                     #:image? ,image?
> > +                     #:binary? ,binary?  
> 
> 
> Those will be removed if we build ‘program’ or ’image’ explicitly.  In
> that case, IIUC, we should add variant properties to the source
> package if we add phases (by inherit) to the binary package and want
> the transform get the same (not get the same one is fine too, which
> only lacks the optional programs or binaries) package.
> 
> 

That's correct.

> > +(define source-package->sbcl-package
> > +  (let* ((property 'sbcl-variant)
> > +         (transformer
> > +          (package-with-build-system asdf-build-system/source
> > +                                     asdf-build-system/sbcl
> > +                                     "cl-"
> > +                                     "sbcl-"
> > +                                     #:variant-property property
> > +                                     #:phases-transformer
> > +
> > 'source-phases->sbcl-phases)))  
> 
> The ‘source-phases->sbcl-phases’ proceduce seems missing, is it
> ‘(const %standard-phases)’?
> 

I meant to delete that procedure.

> Doesn’t ‘special-dependencies’ always available, do we need load them
> explicitly?
> 

The problem is that the asd file produced by 'deliver-asd-op' doesn't
add anything to :depends-on, as you mention.

> I think it’s strange that ‘deliver-asd-op’ make a asd file without all
> its original depends, if the original are valid, maybe we can copy
> them back?
> 

That's basically what's being done in a slightly roundabout way. The
key thing is that we let asdf know where the dependencies need to be
found first, so that we can avoid propagation. Copying the :depends-on
field could be difficult since it can contain reader expressions. We'd
need some logic to do that, or have a lisp implementation help us out.
I don't think specifying #:special-dependencies is too onerous; the
package creator is required to specify dependencies anyway.

> > […]
> > +(define* (generate-binary #:key outputs
> > +                          inputs
> > +                          image-dependencies
> > +                          entry-program
> > +                          lisp
> > +                          binary?
> > +                          #:allow-other-keys)
> > +  "Generate a binary program for the system, either in \"bin\" if
> > the package +also contains a library system, or in \"out\"
> > otherwise."
> > +  (define output (if binary? "out" "bin"))
> > +  (generate-executable #:outputs outputs
> > +                       #:inputs inputs
> > +                       #:image-dependencies image-dependencies
> > +                       #:entry-program entry-program
> > +                       #:lisp lisp
> > +                       #:output output
> > +                       #:needs-own-system? (not binary?)
> > +                       #:type "program")
> > +  (and=>
> > +   (assoc-ref outputs output)
> > +   (lambda (bin)
> > +     (let* ((full-name (outputs->name outputs))
> > +            (name (if binary? full-name
> > +                      (remove-lisp-from-name full-name lisp)))
> > +            (bin-directory (string-append bin "/bin")))
> > +       (with-directory-excursion bin-directory
> > +         (rename-file (string-append name "-exec")
> > +                      name)))))
> > +  #t)
> > +
> > +(define* (generate-image #:key outputs
> > +                         inputs
> > +                         image-dependencies
> > +                         lisp
> > +                         image?
> > +                         #:allow-other-keys)
> > +  "Generate an image for the system, possibly standalone, either
> > in \"image\" +if the package also contains a library system, or in
> > \"out\" otherwise."
> > +  (define output (if image? "out" "image"))
> > +  (generate-executable #:outputs outputs
> > +                       #:inputs inputs
> > +                       #:image-dependencies image-dependencies
> > +                       #:entry-program '(nil)
> > +                       #:lisp lisp
> > +                       #:output output
> > +                       #:needs-own-system? (not image?)
> > +                       #:type "image")
> > +  (and=>
> > +   (assoc-ref outputs output)
> > +   (lambda (image)
> > +     (let* ((full-name (outputs->name outputs))
> > +            (name (if image? full-name
> > +                      (remove-lisp-from-name full-name lisp)))
> > +            (bin-directory (string-append image "/bin")))
> > +       (with-directory-excursion bin-directory
> > +         (rename-file (string-append name
> > "-exec--all-systems.image")
> > +                      (string-append name ".image"))))))
> > +  #t)
> > +
> > +(define* (generate-executable #:key outputs
> > +                              image-dependencies
> > +                              entry-program
> > +                              lisp
> > +                              output
> > +                              inputs
> > +                              type
> > +                              needs-own-system?
> > +                              #:allow-other-keys)
> > +  "Generate an executable by using asdf's TYPE-op, containing
> > whithin the +image all IMAGE-DEPNDENCIES, and running ENTRY-PROGRAM
> > in the case of an +executable."
> > +  (and=>
> > +   (assoc-ref outputs output)
> > +   (lambda (out)
> > +     (let* ((bin-directory (string-append out "/bin"))
> > +            (full-name (outputs->name outputs))
> > +            (name (if needs-own-system?
> > +                      (remove-lisp-from-name full-name lisp)
> > +                      full-name)))
> > +       (mkdir-p out)
> > +       (with-directory-excursion out
> > +         (generate-executable-wrapper-system name
> > +                                             image-dependencies
> > +                                             needs-own-system?)
> > +         (generate-executable-entry-point name entry-program))
> > +
> > +       (setenv "CL_SOURCE_REGISTRY"
> > +               (replace-escaped-macros
> > +                (format
> > +                 #f "~S"
> > +                 (wrap-source-registry
> > +                  `(,(source-registry (assoc-ref outputs "out"))
> > +                    ,(source-registry out))))))
> > +
> > +       (setenv "ASDF_OUTPUT_TRANSLATIONS"
> > +               (replace-escaped-macros
> > +                (format
> > +                 #f "~S"
> > +                 (wrap-output-translations
> > +                  `(((,out :**/ :*.*.*)
> > +                     (,bin-directory :**/ :*.*.*)))))))
> > +
> > +       (parameterize ((%lisp (string-append
> > +                              (assoc-ref inputs lisp) "/bin/"
> > lisp)))
> > +         (generate-executable-for-system type name lisp))
> > +
> > +       (delete-file (string-append out "/" name "-exec.asd"))
> > +       (delete-file (string-append out "/" name "-exec.lisp"))))))
> > +  
> 
> Yeah, I’d like to merge those into lisp-utils.scm, and become
> something like ‘wrap-program’.
> 

Ok, sounds good.

> 
> Also, the output-translations way sometime produces unnecessary
> files, eg: in ecl-fiveam:
> 
> --8<---------------cut here---------------start------------->8---
> /gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib
> /gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl
> /gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src
> /gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src/fiveam.fasb
> /gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src/fiveam.asd
> /gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/src/fiveam.a
> /gnu/store/jy5525lyx0lk20h02g6ik5q4qfkjcnz6-ecl-fiveam-1.2/lib/ecl/t
> --8<---------------cut here---------------end--------------->8---
> 
> I think we only want ’lib/ecl/fiveam.*’.
> 

Right, I didn't notice that.

> I have tried ‘asdf/action:output-files’, hoping that will allow
> install only the files we want, but it doesn’t seem give all the
> output files.
> 
> Run this with ECL:
> 
> --8<---------------cut here---------------start------------->8---
> (require :asdf)
> 
> (let* ((asdf/output-translations:*output-translations*
> 	'(((t #P"/tmp/build/**/*.*"))))
>        (files
> 	(asdf/action:output-files
> 	 'asdf:compile-bundle-op (asdf:find-system :cl-json))))
>   (asdf:operate 'asdf:compile-bundle-op :cl-json)
>   (format t "~S" files))
> 
> (quit)
> --8<---------------cut here---------------end--------------->8---
> 
> The ‘fasb’ file is returned, but the ‘a’ file is missing.
> What the ECL lib (‘a’) files used for?
> 

It gets created by the 'compile-bundle-op', so I assumed it was
necessary, but it turns out it's perfectly possible to load systems
without it. My guess is that it's just a convenience for C developpers,
and we don't really need it. It could be useful if we ever find a C
program that depends on ECL libraries, but I'm willing to remove it.

> 
> Despite my opinions and ideas, please let me know if this patch is
> considered ready, so we can merge it and improve later.

The patch is in a working state, but I have no problem implementing
your suggestions and continuing discussion. It shouldn't take too long.

> 
> Thanks!

Thank you.

--
Andy

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 00/13]: Add asdf-build-system.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (12 preceding siblings ...)
  2016-10-03  2:41   ` [PATCH v2 13/13] gnu: Add sbcl-stumpwm-with-slynk Andy Patterson
@ 2016-10-06 21:04   ` Ludovic Courtès
  2016-10-07  0:59     ` 宋文武
  2016-10-08 13:30   ` 宋文武
  14 siblings, 1 reply; 51+ messages in thread
From: Ludovic Courtès @ 2016-10-06 21:04 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

Hi!

Andy Patterson <ajpatter@uwaterloo.ca> skribis:

> Here's the next round of the series. In addition to the changes proposed by
> 宋文武, I homogenized the phases of the compiled packages, in order to
> simplify transformations. I also added a package transformer system similar to
> package-with-python2. Finally, I decided to have all packages bundle a copy of
> their source, and use it while building, rather than using the source packages
> as a build input, which had some complications.
>
> Further comments are appreciated.

宋文武, I take it that you’ll be looking at this patch series, right?
If you’d like others to chime in, please let us know.  :-)

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 00/13]: Add asdf-build-system.
  2016-10-06 21:04   ` [PATCH v2 00/13]: Add asdf-build-system Ludovic Courtès
@ 2016-10-07  0:59     ` 宋文武
  0 siblings, 0 replies; 51+ messages in thread
From: 宋文武 @ 2016-10-07  0:59 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

ludo@gnu.org (Ludovic Courtès) writes:

> Hi!
>
> Andy Patterson <ajpatter@uwaterloo.ca> skribis:
>
>> Here's the next round of the series. In addition to the changes proposed by
>> 宋文武, I homogenized the phases of the compiled packages, in order to
>> simplify transformations. I also added a package transformer system similar to
>> package-with-python2. Finally, I decided to have all packages bundle a copy of
>> their source, and use it while building, rather than using the source packages
>> as a build input, which had some complications.
>>
>> Further comments are appreciated.
>
> 宋文武, I take it that you’ll be looking at this patch series, right?
> If you’d like others to chime in, please let us know.  :-)
>

Yes, at this point Andy Patterson had addressed most my questions in his
latest reply, so I plan to merge them once a new 'asdf-build-system'
patch is out (fix typo, add more document, etc.) and if no new concerns
appear.  It will be great if others review and comment on them too, in
case I overlooked something :-)

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-05 20:59       ` Andy Patterson
@ 2016-10-07  8:07         ` Andy Patterson
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-07  8:07 UTC (permalink / raw)
  To: 宋文武; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 1195 bytes --]

Hi again,

Things took a little longer than expected as I ran into a bug with ECL
(fix attached). I'll try to upstream it later. It can be re-ordered
somewhere nearer the beginning of the series.

On Wed, 5 Oct 2016 16:59:07 -0400
Andy Patterson <ajpatter@uwaterloo.ca> wrote:

> > What’s the ‘compile-dependencies’ used for?  I think when compile a
> > system, ASDF will load all its depends (from the :depends-on) first.
> > Sometimes we need load extra systems manually?
> >   
> 
> It's for packages like slynk, where many systems are defined within
> the same file. When telling asdf to find a system, it will only
> search for a file with the same name unless it already knows about
> that system. Therefore, in these cases the system which contains the
> definitions is loaded first. This mechanism is a bit clunky so
> suggestions are welcome. For now I'll document the reason it's done
> that way.
> 

I found a better way to solve this.

I hope I've managed to cover everything you've suggested. The slynk
packages look quite a bit nicer now. I'll attach the updates as replies
to the corresponding v2 patches. Let me know what you think.

--
Andy

[-- Attachment #2: v3-0012-gnu-ecl-Fix-truename-on-long-target-files.patch --]
[-- Type: text/x-patch, Size: 3152 bytes --]

From 7646691c77c9a01e620e5f0c4695db8abb276863 Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Fri, 7 Oct 2016 03:19:26 -0400
Subject: [PATCH v3 12/12] gnu: ecl: Fix `truename' on long target files.

When the target of a symbolic link exceeded 128 characters, `truename'
would unexpectedly fail.

* gnu/packages/patches/ecl-fix-si-readlink.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                                   |  1 +
 gnu/packages/lisp.scm                          |  4 +++-
 gnu/packages/patches/ecl-fix-si-readlink.patch | 20 ++++++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/ecl-fix-si-readlink.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 206b794..d057d20 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -497,6 +497,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/doxygen-test.patch			\
   %D%/packages/patches/duplicity-piped-password.patch		\
   %D%/packages/patches/duplicity-test_selection-tmp.patch	\
+  %D%/packages/patches/ecl-fix-si-readlink.patch		\
   %D%/packages/patches/elfutils-tests-ptrace.patch		\
   %D%/packages/patches/elixir-disable-failing-tests.patch	\
   %D%/packages/patches/einstein-build.patch			\
diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 458862c..7068800 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -130,7 +130,9 @@ interface to the Tk widget system.")
        (snippet
         ;; Add ecl-bundle-systems to 'default-system-source-registry'.
         `(substitute* "contrib/asdf/asdf.lisp"
-           ,@(asdf-substitutions name)))))
+           ,@(asdf-substitutions name)))
+       (patches
+        (search-patches "ecl-fix-si-readlink.patch"))))
     (build-system gnu-build-system)
     ;; src/configure uses 'which' to confirm the existence of 'gzip'.
     (native-inputs `(("which" ,which)))
diff --git a/gnu/packages/patches/ecl-fix-si-readlink.patch b/gnu/packages/patches/ecl-fix-si-readlink.patch
new file mode 100644
index 0000000..5cd0efc
--- /dev/null
+++ b/gnu/packages/patches/ecl-fix-si-readlink.patch
@@ -0,0 +1,20 @@
+--- a/src/c/unixfsys.d	2016-02-25 02:06:19.000000000 -0500
++++ b/src/c/unixfsys.d	2016-10-07 00:50:20.172282246 -0400
+@@ -236,15 +236,15 @@ static cl_object
+ si_readlink(cl_object filename) {
+         /* Given a filename which is a symlink, this routine returns
+          * the value of this link in the form of a pathname. */
+-        cl_index size = 128, written;
++        cl_index size = 0, written;
+         cl_object output, kind;
+         do {
++                size += 128;
+                 output = ecl_alloc_adjustable_base_string(size);
+                 ecl_disable_interrupts();
+                 written = readlink((char*)filename->base_string.self,
+                                    (char*)output->base_string.self, size);
+                 ecl_enable_interrupts();
+-                size += 256;
+         } while (written == size);
+         output->base_string.self[written] = '\0';
+         kind = file_kind((char*)output->base_string.self, FALSE);
-- 
2.10.0


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-03  2:41   ` [PATCH v2 01/13] build-system: " Andy Patterson
  2016-10-05  4:55     ` 宋文武
@ 2016-10-07  8:07     ` Andy Patterson
  2016-10-07 12:44       ` Ludovic Courtès
  1 sibling, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-10-07  8:07 UTC (permalink / raw)
  To: guix-devel

From 31dea60d8f4d876c24352b3279c8bef7d5a1ffc4 Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Mon, 26 Sep 2016 20:11:54 -0400
Subject: [PATCH v3 01/12] build-system: Add asdf-build-system.

* guix/build-system/asdf.scm: New file.
* guix/build/asdf-build-system.scm: New file.
* guix/build/lisp-utils.scm: New file.
* Makefile.am (MODULES): Add them.
* doc/guix.texi (Build Systems): Document 'asdf-build-system'.
---
 Makefile.am                      |   3 +
 doc/guix.texi                    |  57 ++++++
 guix/build-system/asdf.scm       | 362 +++++++++++++++++++++++++++++++++++++++
 guix/build/asdf-build-system.scm | 283 ++++++++++++++++++++++++++++++
 guix/build/lisp-utils.scm        | 325 +++++++++++++++++++++++++++++++++++
 5 files changed, 1030 insertions(+)
 create mode 100644 guix/build-system/asdf.scm
 create mode 100644 guix/build/asdf-build-system.scm
 create mode 100644 guix/build/lisp-utils.scm

diff --git a/Makefile.am b/Makefile.am
index 1690a94..7f2281c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -63,6 +63,7 @@ MODULES =					\
   guix/build-system/ant.scm			\
   guix/build-system/cmake.scm			\
   guix/build-system/emacs.scm			\
+  guix/build-system/asdf.scm			\
   guix/build-system/glib-or-gtk.scm		\
   guix/build-system/gnu.scm			\
   guix/build-system/haskell.scm			\
@@ -84,6 +85,7 @@ MODULES =					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
   guix/build/emacs-build-system.scm		\
+  guix/build/asdf-build-system.scm		\
   guix/build/git.scm				\
   guix/build/hg.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
@@ -106,6 +108,7 @@ MODULES =					\
   guix/build/syscalls.scm                       \
   guix/build/gremlin.scm			\
   guix/build/emacs-utils.scm			\
+  guix/build/lisp-utils.scm			\
   guix/build/graft.scm				\
   guix/build/bournish.scm			\
   guix/build/qt-utils.scm			\
diff --git a/doc/guix.texi b/doc/guix.texi
index 9bd8b43..2be589e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2967,6 +2967,63 @@ that should be run during the @code{build} phase.  By default the
 
 @end defvr
 
+@defvr {Scheme Variable} asdf-build-system/source
+@defvrx {Scheme Variable} asdf-build-system/sbcl
+@defvrx {Scheme Variable} asdf-build-system/ecl
+
+These variables, exported by @code{(guix build-system asdf)}, implement
+build procedures for Common Lisp packages using
+@url{https://common-lisp.net/project/asdf/, ``ASDF''}. ASDF is a system
+definition facility for Common Lisp programs and libraries.
+
+The @code{asdf-build-system/source} system installs the packages in
+source form, and can be loaded using any common lisp implementation, via
+ASDF.  The others, such as @code{asdf-build-system/sbcl}, install binary
+systems in the format which a particular implementation understands.
+These build systems can also be used to produce executable programs, or
+lisp images which contain a set of packages pre-loaded.
+
+The build system uses naming conventions.  For binary packages, the
+package itself as well as its run-time dependencies should begin their
+name with the lisp implementation, such as @code{sbcl-} for
+@code{asdf-build-system/sbcl}.  Beginning the input name with this
+prefix will allow the build system to encode its location into the
+resulting library, so that the input can be found at run-time.
+
+If dependencies are used only for tests, it is convenient to use a
+different prefix in order to avoid having a run-time dependency on such
+systems.  For example,
+
+@example
+(define-public sbcl-bordeaux-threads
+  (package
+    ...
+    (native-inputs `(("tests:cl-fiveam" ,sbcl-fiveam)))
+    ...))
+@end example
+
+Additionally, the corresponding source package should be labeled using
+the same convention as python packages (see @ref{Python Modules}), using
+the @code{cl-} prefix.
+
+For binary packages, each system should be defined as a Guix package.
+If one package @code{origin} contains several systems, package variants
+can be created in order to build all the systems.  Source packages,
+which use @code{asdf-build-system/source}, may contain several systems.
+
+In order to create executable programs and images, the build-side
+procedures @code{build-program} and @code{build-image} can be used.
+They should be called in a build phase after the @code{create-symlinks}
+phase, so that the system which was just built can be used within the
+resulting image.  @code{build-program} requires a list of Common Lisp
+expressions to be passed as the @code{#:entry-program} argument.
+
+If the system is not defined within its own @code{.asd} file of the same
+name, then the @code{#:asd-file} parameter should be used to specify
+which file the system is defined in.
+
+@end defvr
+
 @defvr {Scheme Variable} cmake-build-system
 This variable is exported by @code{(guix build-system cmake)}.  It
 implements the build procedure for packages using the
diff --git a/guix/build-system/asdf.scm b/guix/build-system/asdf.scm
new file mode 100644
index 0000000..5bc932f
--- /dev/null
+++ b/guix/build-system/asdf.scm
@@ -0,0 +1,362 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build-system asdf)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix packages)
+  #:use-module (guix derivations)
+  #:use-module (guix search-paths)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system gnu)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (%asdf-build-system-modules
+            %asdf-build-modules
+            asdf-build
+            asdf-build-system/sbcl
+            asdf-build-system/ecl
+            asdf-build-system/source
+            sbcl-package->cl-source-package
+            sbcl-package->ecl-package))
+
+;; Commentary:
+;;
+;; Standard build procedure for asdf packages.  This is implemented as an
+;; extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define %asdf-build-system-modules
+  ;; Imported build-side modules
+  `((guix build asdf-build-system)
+    (guix build lisp-utils)
+    ,@%gnu-build-system-modules))
+
+(define %asdf-build-modules
+  ;; Used (visible) build-side modules
+  '((guix build asdf-build-system)
+    (guix build utils)
+    (guix build lisp-utils)))
+
+(define (default-lisp implementation)
+  "Return the default package for the lisp IMPLEMENTATION."
+  ;; Lazily resolve the binding to avoid a circular dependancy.
+  (let ((lisp-module (resolve-interface '(gnu packages lisp))))
+    (module-ref lisp-module implementation)))
+
+(define* (lower/source name
+                       #:key source inputs outputs native-inputs system target
+                       #:allow-other-keys
+                       #:rest arguments)
+  "Return a bag for NAME"
+  (define private-keywords
+    '(#:target #:inputs #:native-inputs))
+
+  (and (not target)
+       (bag
+         (name name)
+         (system system)
+         (host-inputs `(,@(if source
+                              `(("source" ,source))
+                              '())
+                        ,@inputs
+                        ,@(standard-packages)))
+         (build-inputs native-inputs)
+         (outputs outputs)
+         (build asdf-build/source)
+         (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define* (asdf-build/source store name inputs
+                            #:key source outputs
+                            (phases '(@ (guix build asdf-build-system)
+                                        %standard-phases/source))
+                            (search-paths '())
+                            (system (%current-system))
+                            (guile #f)
+                            (imported-modules %asdf-build-system-modules)
+                            (modules %asdf-build-modules))
+  (define builder
+    `(begin
+       (use-modules ,@modules)
+       (asdf-build/source #:name ,name
+                          #:source ,(match (assoc-ref inputs "source")
+                                      (((? derivation? source))
+                                       (derivation->output-path source))
+                                      ((source) source)
+                                      (source source))
+                          #:system ,system
+                          #:phases ,phases
+                          #:outputs %outputs
+                          #:search-paths ',(map search-path-specification->sexp
+                                                search-paths)
+                          #:inputs %build-inputs)))
+
+  (define guile-for-build
+    (match guile
+      ((? package?)
+       (package-derivation store guile system #:graft? #f))
+      (#f
+       (let* ((distro (resolve-interface '(gnu packages commencement)))
+              (guile (module-ref distro 'guile-final)))
+         (package-derivation store guile system #:graft? #f)))))
+
+  (build-expression->derivation store name builder
+                                #:inputs inputs
+                                #:system system
+                                #:modules imported-modules
+                                #:outputs outputs
+                                #:guile-for-build guile-for-build))
+
+(define* (package-with-build-system from-build-system to-build-system
+                                    from-prefix to-prefix
+                                    #:key variant-property
+                                    phases-transformer)
+  "Return a precedure which takes a package PKG which uses FROM-BUILD-SYSTEM,
+and returns one using TO-BUILD-SYSTEM. If PKG was prefixed by FROM-PREFIX, the
+resulting package will be prefixed by TO-PREFIX. Inputs of PKG are recursively
+transformed using the same rule. The result's #:phases argument will be
+modified by PHASES-TRANSFORMER, an S-expression which evaluates on the build
+side to a procedure of one argument.
+
+VARIANT-PROPERTY can be added to a package's properties to indicate that the
+corresponding package promise should be used as the result of this
+transformation. This allows the result to differ from what the transformation
+would otherwise produce.
+
+If TO-BUILD-SYSTEM is asdf-build-system/source, the resulting package will be
+set up using CL source package conventions."
+  (define target-is-source? (eq? 'asdf/source
+                                 (build-system-name to-build-system)))
+
+  (define (transform-package-name name)
+    (if (string-prefix? from-prefix name)
+        (let ((new-name (string-drop name (string-length from-prefix))))
+          (if (string-prefix? to-prefix new-name)
+              new-name
+              (string-append to-prefix new-name)))
+        name))
+
+  (define (has-from-build-system? pkg)
+    (eq? (build-system-name from-build-system)
+         (build-system-name (package-build-system pkg))))
+
+  (define transform
+    (memoize
+     (lambda (pkg)
+       (define rewrite
+         (match-lambda
+           ((name content . rest)
+            (let* ((is-package? (package? content))
+                   (new-content (if is-package? (transform content) content))
+                   (new-name (if (and is-package?
+                                      (string-prefix? from-prefix name))
+                                 (package-name new-content)
+                                 name)))
+              `(,new-name ,new-content ,@rest)))))
+
+       ;; Special considerations for source packages: CL inputs become
+       ;; propagated, and un-handled arguments are removed. Native inputs are
+       ;; removed as are extraneous outputs.
+       (define new-propagated-inputs
+         (if target-is-source?
+             (map rewrite
+                  (filter (match-lambda
+                            ((_ input . _)
+                             (has-from-build-system? input)))
+                          (package-inputs pkg)))
+             '()))
+
+       (define new-inputs
+         (if target-is-source?
+             (map rewrite
+                  (filter (match-lambda
+                            ((_ input . _)
+                             (not (has-from-build-system? input))))
+                          (package-inputs pkg)))
+             (map rewrite (package-inputs pkg))))
+
+       (define base-arguments
+         (if target-is-source?
+             (strip-keyword-arguments
+              '(#:tests? #:special-dependencies #:asd-file
+                #:test-only-systems #:lisp)
+              (package-arguments pkg))
+             (package-arguments pkg)))
+
+       (cond
+        ((and variant-property
+              (assoc-ref (package-properties pkg) variant-property))
+         => force)
+
+        ((has-from-build-system? pkg)
+         (package
+           (inherit pkg)
+           (location (package-location pkg))
+           (name (transform-package-name (package-name pkg)))
+           (build-system to-build-system)
+           (arguments
+            (substitute-keyword-arguments base-arguments
+              ((#:phases phases) (list phases-transformer phases))))
+           (inputs new-inputs)
+           (propagated-inputs new-propagated-inputs)
+           (native-inputs (if target-is-source?
+                              '()
+                              (map rewrite (package-native-inputs pkg))))
+           (outputs (if target-is-source?
+                        '("out")
+                        (package-outputs pkg)))))
+        (else pkg)))))
+
+  transform)
+
+(define (strip-variant-as-necessary variant pkg)
+  (define properties (package-properties pkg))
+  (if (assoc variant properties)
+      (package
+        (inherit pkg)
+        (properties (alist-delete variant properties)))
+      pkg))
+
+(define (lower lisp-implementation)
+  (lambda* (name
+            #:key source inputs outputs native-inputs system target
+            (lisp (default-lisp (string->symbol lisp-implementation)))
+            #:allow-other-keys
+            #:rest arguments)
+    "Return a bag for NAME"
+    (define private-keywords
+      '(#:target #:inputs #:native-inputs #:lisp))
+
+    (and (not target)
+         (bag
+           (name name)
+           (system system)
+           (host-inputs `(,@(if source
+                                `(("source" ,source))
+                                '())
+                          ,@inputs
+                          ,@(standard-packages)))
+           (build-inputs `((,lisp-implementation ,lisp)
+                           ,@native-inputs))
+           (outputs outputs)
+           (build (asdf-build lisp-implementation))
+           (arguments (strip-keyword-arguments private-keywords arguments))))))
+
+(define (asdf-build lisp-implementation)
+  (lambda* (store name inputs
+                  #:key source outputs
+                  (tests? #t)
+                  (special-dependencies ''())
+                  (asd-file #f)
+                  (test-only-systems ''())
+                  (lisp lisp-implementation)
+                  (phases '(@ (guix build asdf-build-system)
+                              %standard-phases))
+                  (search-paths '())
+                  (system (%current-system))
+                  (guile #f)
+                  (imported-modules %asdf-build-system-modules)
+                  (modules %asdf-build-modules))
+
+    (define builder
+      `(begin
+         (use-modules ,@modules)
+         (asdf-build #:name ,name
+                     #:source ,(match (assoc-ref inputs "source")
+                                 (((? derivation? source))
+                                  (derivation->output-path source))
+                                 ((source) source)
+                                 (source source))
+                     #:lisp ,lisp
+                     #:special-dependencies ,special-dependencies
+                     #:asd-file ,asd-file
+                     #:test-only-systems ,test-only-systems
+                     #:system ,system
+                     #:tests? ,tests?
+                     #:phases ,phases
+                     #:outputs %outputs
+                     #:search-paths ',(map search-path-specification->sexp
+                                           search-paths)
+                     #:inputs %build-inputs)))
+
+    (define guile-for-build
+      (match guile
+        ((? package?)
+         (package-derivation store guile system #:graft? #f))
+        (#f
+         (let* ((distro (resolve-interface '(gnu packages commencement)))
+                (guile (module-ref distro 'guile-final)))
+           (package-derivation store guile system #:graft? #f)))))
+
+    (build-expression->derivation store name builder
+                                  #:inputs inputs
+                                  #:system system
+                                  #:modules imported-modules
+                                  #:outputs outputs
+                                  #:guile-for-build guile-for-build)))
+
+(define asdf-build-system/sbcl
+  (build-system
+    (name 'asdf/sbcl)
+    (description "The build system for asdf binary packages using sbcl")
+    (lower (lower "sbcl"))))
+
+(define asdf-build-system/ecl
+  (build-system
+    (name 'asdf/ecl)
+    (description "The build system for asdf binary packages using ecl")
+    (lower (lower "ecl"))))
+
+(define asdf-build-system/source
+  (build-system
+    (name 'asdf/source)
+    (description "The build system for asdf source packages")
+    (lower lower/source)))
+
+(define sbcl-package->cl-source-package
+  (let* ((property 'cl-source-variant)
+         (transformer
+          (package-with-build-system asdf-build-system/sbcl
+                                     asdf-build-system/source
+                                     "sbcl-"
+                                     "cl-"
+                                     #:variant-property property
+                                     #:phases-transformer
+                                     '(const %standard-phases/source))))
+    (lambda (pkg)
+      (transformer
+       (strip-variant-as-necessary property pkg)))))
+
+(define sbcl-package->ecl-package
+  (let* ((property 'ecl-variant)
+         (transformer
+          (package-with-build-system asdf-build-system/sbcl
+                                     asdf-build-system/ecl
+                                     "sbcl-"
+                                     "ecl-"
+                                     #:variant-property property
+                                     #:phases-transformer
+                                     'identity)))
+    (lambda (pkg)
+      (transformer
+       (strip-variant-as-necessary property pkg)))))
+
+;;; asdf.scm ends here
diff --git a/guix/build/asdf-build-system.scm b/guix/build/asdf-build-system.scm
new file mode 100644
index 0000000..fcd5b65
--- /dev/null
+++ b/guix/build/asdf-build-system.scm
@@ -0,0 +1,283 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build asdf-build-system)
+  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+  #:use-module (guix build utils)
+  #:use-module (guix build lisp-utils)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 receive)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 ftw)
+  #:export (%standard-phases
+            %standard-phases/source
+            asdf-build
+            asdf-build/source))
+
+;; Commentary:
+;;
+;; System for building ASDF packages; creating executable programs and images
+;; from them.
+;;
+;; Code:
+
+(define %object-prefix "/lib")
+
+(define (source-install-prefix lisp)
+  (string-append %install-prefix "/" lisp "-source"))
+
+(define %system-install-prefix
+  (string-append %install-prefix "/systems"))
+
+(define (output-path->package-name path)
+  (package-name->name+version (strip-store-file-name path)))
+
+(define (outputs->name outputs)
+  (output-path->package-name
+   (assoc-ref outputs "out")))
+
+(define (lisp-source-directory output lisp name)
+  (string-append output (source-install-prefix lisp) "/" name))
+
+(define (source-directory output name)
+  (string-append output %install-prefix "/source/" name))
+
+(define (library-directory output lisp)
+  (string-append output %object-prefix
+                 "/" lisp))
+
+(define (output-translation source-path
+                            object-output
+                            lisp)
+  "Return a translation for the system's source path
+to it's binary output."
+  `((,source-path
+     :**/ :*.*.*)
+    (,(library-directory object-output lisp)
+     :**/ :*.*.*)))
+
+(define (source-asd-file output lisp name asd-file)
+  (string-append (lisp-source-directory output lisp name) "/" asd-file))
+
+(define (copy-files-to-output outputs output name)
+  "Copy all files from OUTPUT to \"out\". Create an extra link to any
+system-defining files in the source to a convenient location. This is done
+before any compiling so that the compiled source locations will be valid."
+  (let* ((out (assoc-ref outputs output))
+         (source (getcwd))
+         (target (source-directory out name))
+         (system-path (string-append out %system-install-prefix)))
+    (copy-recursively source target)
+    (mkdir-p system-path)
+    (for-each
+     (lambda (file)
+       (symlink file
+                (string-append system-path "/" (basename file))))
+     (find-files target "\\.asd$"))
+    #t))
+
+(define* (install #:key outputs #:allow-other-keys)
+  "Copy and symlink all the source files."
+  (copy-files-to-output outputs "out" (outputs->name outputs)))
+
+(define* (copy-source #:key outputs lisp #:allow-other-keys)
+  "Copy the source to \"out\"."
+  (let* ((out (assoc-ref outputs "out"))
+         (name (remove-lisp-from-name (output-path->package-name out) lisp))
+         (install-path (string-append out %install-prefix)))
+    (copy-files-to-output outputs "out" name)
+    ;; Hide the files from asdf
+    (with-directory-excursion install-path
+      (rename-file "source" (string-append lisp "-source"))
+      (delete-file-recursively "systems")))
+  #t)
+
+(define* (build #:key outputs inputs lisp asd-file
+                #:allow-other-keys)
+  "Compile the system."
+  (let* ((out (assoc-ref outputs "out"))
+         (name (remove-lisp-from-name (output-path->package-name out) lisp))
+         (source-path (lisp-source-directory out lisp name))
+         (translations (wrap-output-translations
+                        `(,(output-translation source-path
+                                               out
+                                               lisp))))
+         (asd-file (and=> asd-file (cut source-asd-file out lisp name <>))))
+
+    (setenv "ASDF_OUTPUT_TRANSLATIONS"
+            (replace-escaped-macros (format #f "~S" translations)))
+
+    ;; We don't need this if we have the asd file, and it can mess with the
+    ;; load ordering we're trying to enforce
+    (unless asd-file
+      (prepend-to-source-registry (string-append source-path "//")))
+
+    (setenv "HOME" out) ; ecl's asdf sometimes wants to create $HOME/.cache
+
+    (parameterize ((%lisp (string-append
+                           (assoc-ref inputs lisp) "/bin/" lisp)))
+      (compile-system name lisp asd-file))
+
+    ;; As above, ecl will sometimes create this even though it doesn't use it
+
+    (let ((cache-directory (string-append out "/.cache")))
+      (when (directory-exists? cache-directory)
+        (delete-file-recursively cache-directory))))
+  #t)
+
+(define* (check #:key lisp tests? outputs inputs asd-file
+                #:allow-other-keys)
+  "Test the system."
+  (let* ((name (remove-lisp-from-name (outputs->name outputs) lisp))
+         (out (assoc-ref outputs "out"))
+         (asd-file (and=> asd-file (cut source-asd-file out lisp name <>))))
+    (if tests?
+        (parameterize ((%lisp (string-append
+                               (assoc-ref inputs lisp) "/bin/" lisp)))
+          (test-system name lisp asd-file))
+        (format #t "test suite not run~%")))
+  #t)
+
+(define* (patch-asd-files #:key outputs
+                          inputs
+                          lisp
+                          special-dependencies
+                          test-only-systems
+                          #:allow-other-keys)
+  "Patch any asd files created by the compilation process so that they
+can find their dependencies. Exclude any TEST-ONLY-SYSTEMS which were only
+included to run tests. Add any SPECIAL-DEPENDENCIES which the LISP
+implementation itself provides."
+  (let* ((out (assoc-ref outputs "out"))
+         (name (remove-lisp-from-name (output-path->package-name out) lisp))
+         (registry (lset-difference
+                    (lambda (input system)
+                      (match input
+                        ((name . path) (string=? name system))))
+                    (lisp-dependencies lisp inputs)
+                    test-only-systems))
+         (lisp-systems (map first registry)))
+
+    (for-each
+     (lambda (asd-file)
+       (patch-asd-file asd-file registry lisp
+                       (append lisp-systems special-dependencies)))
+     (find-files out "\\.asd$")))
+  #t)
+
+(define* (symlink-asd-files #:key outputs lisp #:allow-other-keys)
+  "Create an extra reference to the system in a convenient location."
+  (let* ((out (assoc-ref outputs "out")))
+    (for-each
+     (lambda (asd-file)
+       (substitute* asd-file
+         ((";;; Built for.*") "") ; remove potential non-determinism
+         (("^\\(DEFSYSTEM(.*)$" all end) (string-append "(asdf:defsystem" end)))
+       (receive (new-asd-file asd-file-directory)
+           (bundle-asd-file out asd-file lisp)
+         (mkdir-p asd-file-directory)
+         (symlink asd-file new-asd-file)
+         ;; Update the source registry for future phases which might want to
+         ;; use the newly compiled system.
+         (prepend-to-source-registry
+          (string-append asd-file-directory "/"))))
+
+     (find-files (string-append out %object-prefix) "\\.asd$"))
+)
+  #t)
+
+(define* (cleanup-files #:key outputs lisp
+                             #:allow-other-keys)
+  "Remove any compiled files which are not a part of the final bundle."
+  (let ((out (assoc-ref outputs "out")))
+    (match lisp
+      ("sbcl"
+       (for-each
+        (lambda (file)
+          (unless (string-suffix? "--system.fasl" file)
+            (delete-file file)))
+        (find-files out "\\.fasl$")))
+      ("ecl"
+       (for-each delete-file
+                 (append (find-files out "\\.fas$")
+                         (find-files out "\\.o$")
+                         (find-files out "\\.a$")))))
+
+    (with-directory-excursion (library-directory out lisp)
+      (for-each
+       (lambda (file)
+         (rename-file file
+                      (string-append "./" (basename file))))
+       (find-files "."))
+      (for-each delete-file-recursively
+                (scandir "."
+                         (lambda (file)
+                           (and
+                            (directory-exists? file)
+                            (string<> "." file)
+                            (string<> ".." file)))))))
+  #t)
+
+(define* (strip #:key lisp #:allow-other-keys #:rest args)
+  ;; stripping sbcl binaries removes their entry program and extra systems
+  (unless (string=? lisp "sbcl")
+    (apply (assoc-ref gnu:%standard-phases 'strip) args))
+  #t)
+
+(define %standard-phases/source
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'check)
+    (delete 'build)
+    (replace 'install install)))
+
+(define %standard-phases
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'install)
+    (replace 'build build)
+    (add-before 'build 'copy-source copy-source)
+    (replace 'check check)
+    (replace 'strip strip)
+    (add-after 'check 'link-dependencies patch-asd-files)
+    (add-after 'link-dependencies 'cleanup cleanup-files)
+    (add-after 'cleanup 'create-symlinks symlink-asd-files)))
+
+(define* (asdf-build #:key inputs
+                     (phases %standard-phases)
+                     #:allow-other-keys
+                     #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+(define* (asdf-build/source #:key inputs
+                            (phases %standard-phases/source)
+                            #:allow-other-keys
+                            #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+;;; asdf-build-system.scm ends here
diff --git a/guix/build/lisp-utils.scm b/guix/build/lisp-utils.scm
new file mode 100644
index 0000000..0e3fcfe
--- /dev/null
+++ b/guix/build/lisp-utils.scm
@@ -0,0 +1,325 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build lisp-utils)
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (guix build utils)
+  #:export (%lisp
+            %install-prefix
+            lisp-eval-program
+            compile-system
+            test-system
+            replace-escaped-macros
+            generate-executable-wrapper-system
+            generate-executable-entry-point
+            generate-executable-for-system
+            patch-asd-file
+            bundle-install-prefix
+            lisp-dependencies
+            bundle-asd-file
+            remove-lisp-from-name
+            wrap-output-translations
+            prepend-to-source-registry
+            build-program
+            build-image))
+
+;;; Commentary:
+;;;
+;;; Tools to evaluate lisp programs within a lisp session, generate wrapper
+;;; systems for executables. Compile, test, and produce images for systems and
+;;; programs, and link them with their dependencies.
+;;;
+;;; Code:
+
+(define %lisp
+  (make-parameter "lisp"))
+
+(define %install-prefix "/share/common-lisp")
+
+(define (bundle-install-prefix lisp)
+  (string-append %install-prefix "/" lisp "-bundle-systems"))
+
+(define (remove-lisp-from-name name lisp)
+  (string-drop name (1+ (string-length lisp))))
+
+(define (wrap-output-translations translations)
+  `(:output-translations
+    ,@translations
+    :inherit-configuration))
+
+(define (lisp-eval-program lisp program)
+  "Evaluate PROGRAM with a given LISP implementation."
+  (unless (zero? (apply system*
+                        (lisp-invoke lisp (format #f "~S" program))))
+    (error "lisp-eval-program failed!" lisp program)))
+
+(define (lisp-invoke lisp program)
+  "Return a list of arguments for system* determining how to invoke LISP
+with PROGRAM."
+  (match lisp
+    ("sbcl" `(,(%lisp) "--non-interactive" "--eval" ,program))
+    ("ecl" `(,(%lisp) "-eval" ,program "-eval" "(quit)"))))
+
+(define (asdf-load-all systems)
+  (map (lambda (system)
+         `(funcall
+           (find-symbol
+            (symbol-name :load-system)
+            (symbol-name :asdf))
+           ,system))
+       systems))
+
+(define (compile-system system lisp asd-file)
+  "Use a lisp implementation to compile SYSTEM using asdf. Loads
+OTHER-REQUIRED-SYSTEMS before beginning compilation."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       (in-package :asdf)
+                       ,@(if asd-file
+                             `((load ,asd-file))
+                             '())
+                       (in-package :cl-user)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :compile-bundle-op)
+                                 (symbol-name :asdf))
+                                ,system)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :deliver-asd-op)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (test-system system lisp asd-file)
+  "Use a lisp implementation to test SYSTEM using asdf. Loads
+OTHER-REQUIRED-SYSTEMS before beginning to test."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       (in-package :asdf)
+                       ,@(if asd-file
+                             `((load ,asd-file))
+                             '())
+                       (in-package :cl-user)
+                       (funcall (find-symbol
+                                 (symbol-name :test-system)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (string->lisp-keyword . strings)
+  "Return a lisp keyword for the concatenation of STRINGS."
+  (string->symbol (apply string-append ":" strings)))
+
+(define (generate-executable-for-system type system lisp)
+  "Use LISP to generate an executable, whose TYPE can be \"image\"
+or \"program\". The latter will always be standalone. Depends on having
+created a \"SYSTEM-exec\" system which contains the entry program."
+  (lisp-eval-program
+   lisp
+   `(progn
+     (require :asdf)
+     (funcall (find-symbol
+               (symbol-name :operate)
+               (symbol-name :asdf))
+              (find-symbol
+               (symbol-name ,(string->lisp-keyword type "-op"))
+               (symbol-name :asdf))
+              ,(string-append system "-exec")))))
+
+(define (generate-executable-wrapper-system system dependencies)
+  "Generates a system which can be used by asdf to produce an image or program
+inside the current directory. The image or program will contain DEPENDENCIES."
+  (with-output-to-file (string-append system "-exec.asd")
+    (lambda _
+      (format #t "~y~%"
+              `(defsystem ,(string->lisp-keyword system "-exec")
+                 :entry-point ,(string-append system "-exec:main")
+                 :depends-on (:uiop
+                              ,@(map string->lisp-keyword
+                                     dependencies))
+                 :components ((:file ,(string-append system "-exec"))))))))
+
+(define (generate-executable-entry-point system entry-program)
+  "Generates an entry point program from the list of lisp statements
+ENTRY-PROGRAM for SYSTEM within the current directory."
+  (with-output-to-file (string-append system "-exec.lisp")
+    (lambda _
+      (let ((system (string->lisp-keyword system "-exec")))
+        (format #t "~{~y~%~%~}"
+                `((defpackage ,system
+                    (:use :cl)
+                    (:export :main))
+
+                  (in-package ,system)
+
+                  (defun main ()
+                    (let ((arguments uiop:*command-line-arguments*))
+                      (declare (ignorable arguments))
+                      ,@entry-program))))))))
+
+(define (wrap-perform-method lisp registry dependencies file-name)
+  "Creates a wrapper method which allows the system to locate its dependent
+systems from REGISTRY, an alist of the same form as %outputs, which contains
+lisp systems which the systems is dependent on. All DEPENDENCIES which
+the system depends on will the be loaded before this system."
+  (let* ((system (string-drop-right (basename file-name) 4))
+         (system-symbol (string->lisp-keyword system)))
+
+    `(defmethod asdf:perform :before
+       (op (c (eql (asdf:find-system ,system-symbol))))
+       (asdf/source-registry:ensure-source-registry)
+       ,@(map (match-lambda
+                ((name . path)
+                 (let ((asd-file (string-append path
+                                                (bundle-install-prefix lisp)
+                                                "/" name ".asd")))
+                   `(setf
+                     (gethash ,name
+                              asdf/source-registry:*source-registry*)
+                     ,(string->symbol "#p")
+                     ,(bundle-asd-file path asd-file lisp)))))
+              registry)
+       ,@(map (lambda (system)
+                `(asdf:load-system ,(string->lisp-keyword system)))
+              dependencies))))
+
+(define (patch-asd-file asd-file registry lisp dependencies)
+  "Patches ASD-FILE with a perform method as described in WRAP-PERFORM-METHOD."
+  (chmod asd-file #o644)
+  (let ((port (open-file asd-file "a")))
+    (dynamic-wind
+      (lambda _ #t)
+      (lambda _
+        (display
+         (replace-escaped-macros
+          (format #f "~%~y~%"
+                  (wrap-perform-method lisp registry
+                                       dependencies asd-file)))
+         port))
+      (lambda _ (close-port port))))
+  (chmod asd-file #o444))
+
+(define (lisp-dependencies lisp inputs)
+  "Determine which inputs are lisp system dependencies, by using the convention
+that a lisp system dependency will resemble \"system-LISP\"."
+  (filter-map (match-lambda
+                ((name . value)
+                 (and (string-prefix? lisp name)
+                      (string<> lisp name)
+                      `(,(remove-lisp-from-name name lisp)
+                        . ,value))))
+              inputs))
+
+(define (bundle-asd-file output-path original-asd-file lisp)
+  "Find the symlinked bundle file for ORIGINAL-ASD-FILE by looking in
+OUTPUT-PATH/share/common-lisp/LISP-bundle-systems/<system>.asd. Returns two
+values: the asd file itself and the directory in which it resides."
+  (let ((bundle-asd-path (string-append output-path
+                                        (bundle-install-prefix lisp))))
+    (values (string-append bundle-asd-path "/" (basename original-asd-file))
+            bundle-asd-path)))
+
+(define (replace-escaped-macros string)
+  "Replace simple lisp forms that the guile writer escapes, for
+example by replacing #{#p}# with #p. Should only be used to replace
+truly simple forms which are not nested."
+  (regexp-substitute/global #f "(#\\{)(\\S*)(\\}#)" string
+                            'pre 2 'post))
+
+(define (prepend-to-source-registry path)
+  (setenv "CL_SOURCE_REGISTRY"
+          (string-append path ":" (or (getenv "CL_SOURCE_REGISTRY") ""))))
+
+(define* (build-program lisp program #:key inputs
+                        (dependencies (list (basename program)))
+                        entry-program
+                        #:allow-other-keys)
+  "Generate an executable program containing all DEPENDENCIES, and which will
+execute ENTRY-PROGRAM. The result is placed in PROGRAM. When executed, it will
+run ENTRY-PROGRAM, a list of Common Lisp expressions in which `arguments' has
+been bound to the command-line arguments which were passed."
+  (generate-executable lisp program
+                       #:inputs inputs
+                       #:dependencies dependencies
+                       #:entry-program entry-program
+                       #:type "program")
+  (let* ((name (basename program))
+         (bin-directory (dirname program)))
+    (with-directory-excursion bin-directory
+      (rename-file (string-append name "-exec")
+                   name)))
+  #t)
+
+(define* (build-image lisp image #:key inputs
+                      (dependencies (list (basename image)))
+                      #:allow-other-keys)
+  "Generate an image, possibly standalone, which contains all DEPENDENCIES,
+placing the result in IMAGE.image."
+  (generate-executable lisp image
+                       #:inputs inputs
+                       #:dependencies dependencies
+                       #:entry-program '(nil)
+                       #:type "image")
+  (let* ((name (basename image))
+         (bin-directory (dirname image)))
+    (with-directory-excursion bin-directory
+      (rename-file (string-append name "-exec--all-systems.image")
+                   (string-append name ".image"))))
+  #t)
+
+(define* (generate-executable lisp out-file #:key inputs
+                              dependencies
+                              entry-program
+                              type
+                              #:allow-other-keys)
+  "Generate an executable by using asdf's TYPE-op, containing whithin the
+image all DEPENDENCIES, and running ENTRY-PROGRAM in the case of an
+executable."
+  (let* ((bin-directory (dirname out-file))
+         (name (basename out-file)))
+    (mkdir-p bin-directory)
+    (with-directory-excursion bin-directory
+      (generate-executable-wrapper-system name dependencies)
+      (generate-executable-entry-point name entry-program))
+
+    (prepend-to-source-registry
+     (string-append bin-directory "/"))
+
+    (setenv "ASDF_OUTPUT_TRANSLATIONS"
+            (replace-escaped-macros
+             (format
+              #f "~S"
+              (wrap-output-translations
+               `(((,bin-directory :**/ :*.*.*)
+                  (,bin-directory :**/ :*.*.*)))))))
+
+    (parameterize ((%lisp (string-append
+                           (assoc-ref inputs lisp) "/bin/" lisp)))
+      (generate-executable-for-system type name lisp))
+
+    (delete-file (string-append bin-directory "/" name "-exec.asd"))
+    (delete-file (string-append bin-directory "/" name "-exec.lisp"))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 11/13] gnu: Add cl-stumpwm.
  2016-10-03  2:41   ` [PATCH v2 11/13] gnu: Add cl-stumpwm Andy Patterson
@ 2016-10-07  8:07     ` Andy Patterson
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-07  8:07 UTC (permalink / raw)
  To: guix-devel

From e4810fc2d9a38b8cf4f4132db040cb6059e14fc3 Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Sat, 1 Oct 2016 00:32:44 -0400
Subject: [PATCH v3 09/12] gnu: Add cl-stumpwm.

* gnu/packages/lisp.scm (cl-stumpwm, sbcl-stumpwm, ecl-stumpwm): New
  variables.
---
 gnu/packages/lisp.scm | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index ff329bd..06a4337 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -743,3 +743,69 @@ from other CLXes around the net.")
 
 (define-public ecl-clx
   (sbcl-package->ecl-package sbcl-clx))
+
+(define-public sbcl-stumpwm
+  (package
+    (name "sbcl-stumpwm")
+    (version "0.9.9")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/stumpwm/stumpwm/archive/"
+                    version ".tar.gz"))
+              (sha256
+               (base32 "1fqabij4zcsqg1ywgdv2irp1ys23dwc8ms9ai55lb2i47hgv7z3x"))
+              (file-name (string-append "stumpwm-" version ".tar.gz"))))
+    (build-system asdf-build-system/sbcl)
+    (inputs `(("sbcl-cl-ppcre" ,sbcl-cl-ppcre)
+              ("sbcl-clx" ,sbcl-clx)))
+    (outputs '("out" "bin"))
+    (arguments
+     '(#:special-dependencies '("sb-posix")
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'create-symlinks 'build-program
+           (lambda* (#:key lisp outputs inputs #:allow-other-keys)
+             (build-program
+              lisp
+              (string-append (assoc-ref outputs "bin") "/bin/stumpwm")
+              #:inputs inputs
+              #:entry-program '((stumpwm:stumpwm) 0))))
+         (add-after 'build-program 'create-desktop-file
+           (lambda* (#:key outputs lisp binary? #:allow-other-keys)
+             (let ((output (or (assoc-ref outputs "bin")
+                               (assoc-ref outputs "out")))
+                   (xsessions "/share/xsessions"))
+               (mkdir-p (string-append output xsessions))
+               (with-output-to-file
+                   (string-append output xsessions
+                                  "/stumpwm.desktop")
+                 (lambda _
+                   (format #t
+                    "[Desktop Entry]~@
+                     Name=stumpwm~@
+                     Comment=The Stump Window Manager~@
+                     Exec=~a/bin/stumpwm~@
+                     TryExec=~@*~a/bin/stumpwm~@
+                     Icon=~@
+                     Type=Application~%"
+                    output)))
+               #t))))))
+    (synopsis "Window manager written in Common Lisp")
+    (description "Stumpwm is a window manager written entirely in Common Lisp.
+It attempts to be highly customizable while relying entirely on the keyboard
+for input.  These design decisions reflect the growing popularity of
+productive, customizable lisp based systems.")
+    (home-page "http://github.com/stumpwm/stumpwm")
+    (license license:gpl2+)
+    (properties `((ecl-variant . ,(delay ecl-stumpwm))))))
+
+(define-public cl-stumpwm
+  (sbcl-package->cl-source-package sbcl-stumpwm))
+
+(define-public ecl-stumpwm
+  (let ((base (sbcl-package->ecl-package sbcl-stumpwm)))
+    (package
+      (inherit base)
+      (outputs '("out"))
+      (arguments '()))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 12/13] gnu: Add cl-slynk.
  2016-10-03  2:41   ` [PATCH v2 12/13] gnu: Add cl-slynk Andy Patterson
@ 2016-10-07  8:07     ` Andy Patterson
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-07  8:07 UTC (permalink / raw)
  To: guix-devel

From c2ced364d1442c4a0f05a19518eaa88e4e602744 Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Sat, 1 Oct 2016 12:16:25 -0400
Subject: [PATCH v3 10/12] gnu: Add cl-slynk.

* gnu/packages/lisp.scm (cl-slynk, sbcl-slynk, ecl-slynk): New
  variables.
---
 gnu/packages/lisp.scm | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 230 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 06a4337..60c7673 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -34,6 +34,7 @@
   #:use-module (guix utils)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system asdf)
+  #:use-module (guix build-system trivial)
   #:use-module (gnu packages base)
   #:use-module (gnu packages multiprecision)
   #:use-module (gnu packages bdw-gc)
@@ -809,3 +810,232 @@ productive, customizable lisp based systems.")
       (inherit base)
       (outputs '("out"))
       (arguments '()))))
+
+(define sbcl-slynk-boot0
+  (let ((revision "1")
+        (commit "5706cd45d484a4f25795abe8e643509d31968aa2"))
+    (package
+      (name "sbcl-slynk")
+      (version (string-append "1.0.0-beta-" revision "." (string-take commit 7)))
+      (source
+       (origin
+         (method git-fetch)
+         (uri
+          (git-reference
+           (url "https://github.com/joaotavora/sly.git")
+           (commit commit)))
+         (sha256
+          (base32 "0h4gg3sndl2bf6jdnx9nrf14p9hhi43hagrl0f4v4l11hczl8w81"))
+         (file-name (string-append "slynk-" version "-checkout"))
+         (modules '((guix build utils)
+                    (ice-9 ftw)))
+         (snippet
+          '(begin
+             ;; Move the contribs into the main source directory for easier
+             ;; access
+             (substitute* "slynk/slynk.asd"
+               (("\\.\\./contrib")
+                "contrib")
+               (("\\(defsystem :slynk-util")
+                "(defsystem :slynk-util :depends-on (:slynk)"))
+             (substitute* "contrib/slynk-trace-dialog.lisp"
+               (("\\(slynk::reset-inspector\\)") ; Causes problems on load
+                "nil"))
+             (substitute* "contrib/slynk-profiler.lisp"
+               (("slynk:to-line")
+                "slynk-pprint-to-line"))
+             (rename-file "contrib" "slynk/contrib")
+             ;; Move slynk's contents into the base directory for easier
+             ;; access
+             (for-each
+              (lambda (file)
+                (unless (string-prefix? "." file)
+                  (rename-file (string-append "slynk/" file)
+                               (string-append "./" (basename file)))))
+              (scandir "slynk"))))))
+      (build-system asdf-build-system/sbcl)
+      (arguments
+       `(#:tests? #f)) ; No test suite
+      (synopsis "Common Lisp IDE for Emacs")
+      (description "SLY is a fork of SLIME.  It also features a completely
+redesigned REPL based on Emacs's own full-featured comint.el, live code
+annotations, and a consistent interactive button interface.  Everything can be
+copied to the REPL.  One can create multiple inspectors with independent
+history.")
+      (home-page "https://github.com/joaotavora/sly")
+      (license license:public-domain)
+      (properties `((cl-source-variant . ,(delay cl-slynk)))))))
+
+(define-public cl-slynk
+  (sbcl-package->cl-source-package sbcl-slynk-boot0))
+
+(define ecl-slynk-boot0
+  (sbcl-package->ecl-package sbcl-slynk-boot0))
+
+(define sbcl-slynk-arglists
+  (package
+    (inherit sbcl-slynk-boot0)
+    (name "sbcl-slynk-arglists")
+    (inputs `(("sbcl-slynk" ,sbcl-slynk-boot0)))
+    (arguments
+     `(#:asd-file "slynk.asd"
+       ,@(package-arguments sbcl-slynk-boot0)))))
+
+(define ecl-slynk-arglists
+  (sbcl-package->ecl-package sbcl-slynk-arglists))
+
+(define sbcl-slynk-util
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-util")))
+
+(define ecl-slynk-util
+  (sbcl-package->ecl-package sbcl-slynk-util))
+
+(define sbcl-slynk-fancy-inspector
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-fancy-inspector")
+    (inputs `(("sbcl-slynk-util" ,sbcl-slynk-util)
+              ,@(package-inputs sbcl-slynk-arglists)))))
+
+(define ecl-slynk-fancy-inspector
+  (sbcl-package->ecl-package sbcl-slynk-fancy-inspector))
+
+(define sbcl-slynk-package-fu
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-package-fu")))
+
+(define ecl-slynk-package-fu
+  (sbcl-package->ecl-package sbcl-slynk-package-fu))
+
+(define sbcl-slynk-mrepl
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-mrepl")))
+
+(define ecl-slynk-mrepl
+  (sbcl-package->ecl-package sbcl-slynk-mrepl))
+
+(define sbcl-slynk-trace-dialog
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-trace-dialog")))
+
+(define ecl-slynk-trace-dialog
+  (sbcl-package->ecl-package sbcl-slynk-trace-dialog))
+
+(define sbcl-slynk-profiler
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-profiler")))
+
+(define ecl-slynk-profiler
+  (sbcl-package->ecl-package sbcl-slynk-profiler))
+
+(define sbcl-slynk-stickers
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-stickers")))
+
+(define ecl-slynk-stickers
+  (sbcl-package->ecl-package sbcl-slynk-stickers))
+
+(define sbcl-slynk-indentation
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-indentation")))
+
+(define ecl-slynk-indentation
+  (sbcl-package->ecl-package sbcl-slynk-indentation))
+
+(define sbcl-slynk-retro
+  (package
+    (inherit sbcl-slynk-arglists)
+    (name "sbcl-slynk-retro")))
+
+(define ecl-slynk-retro
+  (sbcl-package->ecl-package sbcl-slynk-retro))
+
+(define slynk-systems
+  '("slynk"
+    "slynk-util"
+    "slynk-arglists"
+    "slynk-fancy-inspector"
+    "slynk-package-fu"
+    "slynk-mrepl"
+    "slynk-profiler"
+    "slynk-trace-dialog"
+    "slynk-stickers"
+    "slynk-indentation"
+    "slynk-retro"))
+
+(define-public sbcl-slynk
+  (package
+    (inherit sbcl-slynk-boot0)
+    (inputs
+     `(("slynk" ,sbcl-slynk-boot0)
+       ("slynk-util" ,sbcl-slynk-util)
+       ("slynk-arglists" ,sbcl-slynk-arglists)
+       ("slynk-fancy-inspector" ,sbcl-slynk-fancy-inspector)
+       ("slynk-package-fu" ,sbcl-slynk-package-fu)
+       ("slynk-mrepl" ,sbcl-slynk-mrepl)
+       ("slynk-profiler" ,sbcl-slynk-profiler)
+       ("slynk-trace-dialog" ,sbcl-slynk-trace-dialog)
+       ("slynk-stickers" ,sbcl-slynk-stickers)
+       ("slynk-indentation" ,sbcl-slynk-indentation)
+       ("slynk-retro" ,sbcl-slynk-retro)))
+    (native-inputs `(("sbcl" ,sbcl)))
+    (build-system trivial-build-system)
+    (source #f)
+    (outputs '("out" "image"))
+    (arguments
+     `(#:modules ((guix build union)
+                  (guix build utils)
+                  (guix build lisp-utils))
+       #:builder
+       (begin
+         (use-modules (ice-9 match)
+                      (srfi srfi-1)
+                      (guix build union)
+                      (guix build lisp-utils))
+
+         (union-build
+          (assoc-ref %outputs "out")
+          (filter-map
+           (match-lambda
+             ((name . path)
+              (if (string-prefix? "slynk" name) path #f)))
+           %build-inputs))
+
+         (prepend-to-source-registry
+          (string-append (assoc-ref %outputs "out") "//"))
+         (build-image "sbcl"
+                      (string-append
+                       (assoc-ref %outputs "image")
+                       "/bin/slynk")
+                      #:inputs %build-inputs
+                      #:dependencies ',slynk-systems))))))
+
+(define-public ecl-slynk
+  (package
+    (inherit sbcl-slynk)
+    (name "ecl-slynk")
+    (inputs
+     (map (match-lambda
+            ((name pkg . _)
+             (list name (sbcl-package->ecl-package pkg))))
+          (package-inputs sbcl-slynk)))
+    (native-inputs '())
+    (outputs '("out"))
+    (arguments
+     '(#:modules ((guix build union))
+       #:builder
+       (begin
+         (use-modules (ice-9 match)
+                      (guix build union))
+         (match %build-inputs
+           (((names . paths) ...)
+            (union-build (assoc-ref %outputs "out")
+                         paths))))))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 13/13] gnu: Add sbcl-stumpwm-with-slynk.
  2016-10-03  2:41   ` [PATCH v2 13/13] gnu: Add sbcl-stumpwm-with-slynk Andy Patterson
@ 2016-10-07  8:07     ` Andy Patterson
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-07  8:07 UTC (permalink / raw)
  To: guix-devel

From 18ed767219311a348fe58f4a7e7f8bdb3dbfde9a Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Fri, 7 Oct 2016 03:37:02 -0400
Subject: [PATCH v3 11/12] gnu: Add sbcl-stumpwm-with-slynk.

* gnu/packages/lisp.scm (sbcl-stumpwm+slynk): New variable.
---
 gnu/packages/lisp.scm | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/gnu/packages/lisp.scm b/gnu/packages/lisp.scm
index 60c7673..458862c 100644
--- a/gnu/packages/lisp.scm
+++ b/gnu/packages/lisp.scm
@@ -1039,3 +1039,32 @@ history.")
            (((names . paths) ...)
             (union-build (assoc-ref %outputs "out")
                          paths))))))))
+
+(define-public sbcl-stumpwm+slynk
+  (package
+    (inherit sbcl-stumpwm)
+    (name "sbcl-stumpwm-with-slynk")
+    (outputs '("out"))
+    (native-inputs
+     `(("stumpwm" ,sbcl-stumpwm)
+       ("slynk" ,sbcl-slynk)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments sbcl-stumpwm)
+       ((#:phases phases)
+        `(modify-phases ,phases
+           (replace 'build-program
+             (lambda* (#:key lisp inputs outputs #:allow-other-keys)
+               (define program (string-append (assoc-ref outputs "out")
+                                              "/bin/stumpwm"))
+               (build-program lisp program
+                              #:inputs inputs
+                              #:entry-program '((stumpwm:stumpwm) 0)
+                              #:dependencies '("stumpwm"
+                                               ,@slynk-systems))
+               #t))
+           (delete 'copy-source)
+           (delete 'build)
+           (delete 'check)
+           (delete 'link-dependencies)
+           (delete 'cleanup)
+           (delete 'create-symlinks)))))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-07  8:07     ` Andy Patterson
@ 2016-10-07 12:44       ` Ludovic Courtès
  2016-10-07 21:57         ` Andy Patterson
  0 siblings, 1 reply; 51+ messages in thread
From: Ludovic Courtès @ 2016-10-07 12:44 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

Hello,

Adding my 2¢ as 宋文武 suggested.  :-)

Andy Patterson <ajpatter@uwaterloo.ca> skribis:

> From 31dea60d8f4d876c24352b3279c8bef7d5a1ffc4 Mon Sep 17 00:00:00 2001
> From: Andy Patterson <ajpatter@uwaterloo.ca>
> Date: Mon, 26 Sep 2016 20:11:54 -0400
> Subject: [PATCH v3 01/12] build-system: Add asdf-build-system.
>
> * guix/build-system/asdf.scm: New file.
> * guix/build/asdf-build-system.scm: New file.
> * guix/build/lisp-utils.scm: New file.
> * Makefile.am (MODULES): Add them.
> * doc/guix.texi (Build Systems): Document 'asdf-build-system'.

Woohoo, nice stuff!

> +@defvr {Scheme Variable} asdf-build-system/source
> +@defvrx {Scheme Variable} asdf-build-system/sbcl
> +@defvrx {Scheme Variable} asdf-build-system/ecl

And great doc.

> +(define* (package-with-build-system from-build-system to-build-system
> +                                    from-prefix to-prefix
> +                                    #:key variant-property
> +                                    phases-transformer)
> +  "Return a precedure which takes a package PKG which uses FROM-BUILD-SYSTEM,
> +and returns one using TO-BUILD-SYSTEM. If PKG was prefixed by FROM-PREFIX, the
> +resulting package will be prefixed by TO-PREFIX. Inputs of PKG are recursively
> +transformed using the same rule. The result's #:phases argument will be
> +modified by PHASES-TRANSFORMER, an S-expression which evaluates on the build
> +side to a procedure of one argument.

This code seems to be adapted from ‘package-with-python2’.  It seems
that ‘package-input-rewriting’ is too specific to be used here, but at
any rate, we should keep an eye towards factorizing this and keep it as
simple as possible to facilitate that.

Is #:variant-property necessary here?  It was necessary in
‘package-with-python2’ due to python-2 and python-3 packages sometimes
having a different set of dependencies.  If it can be avoided here, it’s
better.  Otherwise that’s fine.

(I haven’t followed closely, so apologies if this has already been
discussed.)

Note: Two spaces after end-of-sentence period please.  :-)

> +  (define target-is-source? (eq? 'asdf/source
> +                                 (build-system-name to-build-system)))

Rather:

  (eq? ast-build-system/source to-build-system)

The name is purely for debugging purposes.

> +(define asdf-build-system/sbcl
> +  (build-system
> +    (name 'asdf/sbcl)
> +    (description "The build system for asdf binary packages using sbcl")
> +    (lower (lower "sbcl"))))
> +
> +(define asdf-build-system/ecl
> +  (build-system
> +    (name 'asdf/ecl)
> +    (description "The build system for asdf binary packages using ecl")
> +    (lower (lower "ecl"))))
> +
> +(define asdf-build-system/source
> +  (build-system
> +    (name 'asdf/source)
> +    (description "The build system for asdf source packages")
> +    (lower lower/source)))

Probably uppercase: SBCL, ECL, ASDF.

> +(define* (strip #:key lisp #:allow-other-keys #:rest args)
> +  ;; stripping sbcl binaries removes their entry program and extra systems
> +  (unless (string=? lisp "sbcl")
> +    (apply (assoc-ref gnu:%standard-phases 'strip) args))
> +  #t)

Shouldn’t it be:

  (or (string=? lisp "sbcl")
      (apply …))

?  Otherwise the real return value is discarded.

> +(define %lisp
> +  (make-parameter "lisp"))

Add a comment like “File name of the Lisp compiler.” (?).

> +(define %install-prefix "/share/common-lisp")

What about “lib/common-lisp” for architecture-dependent files
(binaries)?  What do other distros do?

That’s it.

Thank you!

Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-07 12:44       ` Ludovic Courtès
@ 2016-10-07 21:57         ` Andy Patterson
  2016-10-08 12:39           ` Ludovic Courtès
  0 siblings, 1 reply; 51+ messages in thread
From: Andy Patterson @ 2016-10-07 21:57 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Hi.

On Fri, 07 Oct 2016 14:44:38 +0200
ludo@gnu.org (Ludovic Courtès) wrote:

> Hello,
> 
> Adding my 2¢ as 宋文武 suggested.  :-)
> 
> Andy Patterson <ajpatter@uwaterloo.ca> skribis:
> 
> > +(define* (package-with-build-system from-build-system
> > to-build-system
> > +                                    from-prefix to-prefix
> > +                                    #:key variant-property
> > +                                    phases-transformer)
> > +  "Return a precedure which takes a package PKG which uses
> > FROM-BUILD-SYSTEM, +and returns one using TO-BUILD-SYSTEM. If PKG
> > was prefixed by FROM-PREFIX, the +resulting package will be
> > prefixed by TO-PREFIX. Inputs of PKG are recursively +transformed
> > using the same rule. The result's #:phases argument will be
> > +modified by PHASES-TRANSFORMER, an S-expression which evaluates on
> > the build +side to a procedure of one argument.  
> 
> This code seems to be adapted from ‘package-with-python2’.  It seems
> that ‘package-input-rewriting’ is too specific to be used here, but at
> any rate, we should keep an eye towards factorizing this and keep it
> as simple as possible to facilitate that.
> 

I'm not sure what the right abstraction is to encompass both.

> Is #:variant-property necessary here?  It was necessary in
> ‘package-with-python2’ due to python-2 and python-3 packages sometimes
> having a different set of dependencies.  If it can be avoided here,
> it’s better.  Otherwise that’s fine.
> 

It's necessary any time the variant package must differ from what the
transformer would ordinarily produce, so that a package which needs to
include the variant knows how to find it in the recursive step. In our
case, ecl packages may need different phases or outputs for binary
generation.

Also, the dependencies could differ, for example stumpwm used to use
the built-in clx on ecl.

>
> (I haven’t followed closely, so apologies if this has already been
> discussed.)
> 
> Note: Two spaces after end-of-sentence period please.  :-)
> 

Ok, fixed that elsewhere as well.

> > +  (define target-is-source? (eq? 'asdf/source
> > +                                 (build-system-name
> > to-build-system)))  
> 
> Rather:
> 
>   (eq? ast-build-system/source to-build-system)
> 
> The name is purely for debugging purposes.
> 

Ok.

> > +(define asdf-build-system/sbcl
> > +  (build-system
> > +    (name 'asdf/sbcl)
> > +    (description "The build system for asdf binary packages using
> > sbcl")
> > +    (lower (lower "sbcl"))))
> > +
> > +(define asdf-build-system/ecl
> > +  (build-system
> > +    (name 'asdf/ecl)
> > +    (description "The build system for asdf binary packages using
> > ecl")
> > +    (lower (lower "ecl"))))
> > +
> > +(define asdf-build-system/source
> > +  (build-system
> > +    (name 'asdf/source)
> > +    (description "The build system for asdf source packages")
> > +    (lower lower/source)))  
> 
> Probably uppercase: SBCL, ECL, ASDF.
> 

Sure.

> > +(define* (strip #:key lisp #:allow-other-keys #:rest args)
> > +  ;; stripping sbcl binaries removes their entry program and extra
> > systems
> > +  (unless (string=? lisp "sbcl")
> > +    (apply (assoc-ref gnu:%standard-phases 'strip) args))
> > +  #t)  
> 
> Shouldn’t it be:
> 
>   (or (string=? lisp "sbcl")
>       (apply …))
> 
> ?  Otherwise the real return value is discarded.
> 

Right.

> > +(define %lisp
> > +  (make-parameter "lisp"))  
> 
> Add a comment like “File name of the Lisp compiler.” (?).
> 

Ok.

> > +(define %install-prefix "/share/common-lisp")  
> 
> What about “lib/common-lisp” for architecture-dependent files
> (binaries)?  What do other distros do?
> 

Binaries are placed in /lib/<lisp>/. /share/common-lisp is just used
for source or symlinked .asd files (as is the convention). The other
distributions I've seen which package Common Lisp libraries (Debian and
Gentoo) do not distribute binaries for systems, and what they do is
basically equivalent to the asdf-build-system/source. I
think /lib/<lisp>/ is a good place for binaries, since the
implementations place their extra included system binaries there,
roughly (/lib/sbcl/contrib; /lib/ecl-<version>).

> That’s it.
> 

Cool. Fixes attached inline. Are the packages also OK? I'd like to
start fixing any problems with those as well.

> Thank you!
> 
> Ludo’.

Thanks for your comments.

--
Andy

From 3794fd653bd07496f9e538b27fe5e1b7795b88af Mon Sep 17 00:00:00 2001
From: Andy Patterson <ajpatter@uwaterloo.ca>
Date: Mon, 26 Sep 2016 20:11:54 -0400
Subject: [PATCH v4 01/12] build-system: Add asdf-build-system.

* guix/build-system/asdf.scm: New file.
* guix/build/asdf-build-system.scm: New file.
* guix/build/lisp-utils.scm: New file.
* Makefile.am (MODULES): Add them.
* doc/guix.texi (Build Systems): Document 'asdf-build-system'.
---
 Makefile.am                      |   3 +
 doc/guix.texi                    |  57 +++++++
 guix/build-system/asdf.scm       | 360 +++++++++++++++++++++++++++++++++++++++
 guix/build/asdf-build-system.scm | 282 ++++++++++++++++++++++++++++++
 guix/build/lisp-utils.scm        | 327 +++++++++++++++++++++++++++++++++++
 5 files changed, 1029 insertions(+)
 create mode 100644 guix/build-system/asdf.scm
 create mode 100644 guix/build/asdf-build-system.scm
 create mode 100644 guix/build/lisp-utils.scm

diff --git a/Makefile.am b/Makefile.am
index 1690a94..7f2281c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -63,6 +63,7 @@ MODULES =					\
   guix/build-system/ant.scm			\
   guix/build-system/cmake.scm			\
   guix/build-system/emacs.scm			\
+  guix/build-system/asdf.scm			\
   guix/build-system/glib-or-gtk.scm		\
   guix/build-system/gnu.scm			\
   guix/build-system/haskell.scm			\
@@ -84,6 +85,7 @@ MODULES =					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
   guix/build/emacs-build-system.scm		\
+  guix/build/asdf-build-system.scm		\
   guix/build/git.scm				\
   guix/build/hg.scm				\
   guix/build/glib-or-gtk-build-system.scm	\
@@ -106,6 +108,7 @@ MODULES =					\
   guix/build/syscalls.scm                       \
   guix/build/gremlin.scm			\
   guix/build/emacs-utils.scm			\
+  guix/build/lisp-utils.scm			\
   guix/build/graft.scm				\
   guix/build/bournish.scm			\
   guix/build/qt-utils.scm			\
diff --git a/doc/guix.texi b/doc/guix.texi
index 9bd8b43..2be589e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2967,6 +2967,63 @@ that should be run during the @code{build} phase.  By default the
 
 @end defvr
 
+@defvr {Scheme Variable} asdf-build-system/source
+@defvrx {Scheme Variable} asdf-build-system/sbcl
+@defvrx {Scheme Variable} asdf-build-system/ecl
+
+These variables, exported by @code{(guix build-system asdf)}, implement
+build procedures for Common Lisp packages using
+@url{https://common-lisp.net/project/asdf/, ``ASDF''}. ASDF is a system
+definition facility for Common Lisp programs and libraries.
+
+The @code{asdf-build-system/source} system installs the packages in
+source form, and can be loaded using any common lisp implementation, via
+ASDF.  The others, such as @code{asdf-build-system/sbcl}, install binary
+systems in the format which a particular implementation understands.
+These build systems can also be used to produce executable programs, or
+lisp images which contain a set of packages pre-loaded.
+
+The build system uses naming conventions.  For binary packages, the
+package itself as well as its run-time dependencies should begin their
+name with the lisp implementation, such as @code{sbcl-} for
+@code{asdf-build-system/sbcl}.  Beginning the input name with this
+prefix will allow the build system to encode its location into the
+resulting library, so that the input can be found at run-time.
+
+If dependencies are used only for tests, it is convenient to use a
+different prefix in order to avoid having a run-time dependency on such
+systems.  For example,
+
+@example
+(define-public sbcl-bordeaux-threads
+  (package
+    ...
+    (native-inputs `(("tests:cl-fiveam" ,sbcl-fiveam)))
+    ...))
+@end example
+
+Additionally, the corresponding source package should be labeled using
+the same convention as python packages (see @ref{Python Modules}), using
+the @code{cl-} prefix.
+
+For binary packages, each system should be defined as a Guix package.
+If one package @code{origin} contains several systems, package variants
+can be created in order to build all the systems.  Source packages,
+which use @code{asdf-build-system/source}, may contain several systems.
+
+In order to create executable programs and images, the build-side
+procedures @code{build-program} and @code{build-image} can be used.
+They should be called in a build phase after the @code{create-symlinks}
+phase, so that the system which was just built can be used within the
+resulting image.  @code{build-program} requires a list of Common Lisp
+expressions to be passed as the @code{#:entry-program} argument.
+
+If the system is not defined within its own @code{.asd} file of the same
+name, then the @code{#:asd-file} parameter should be used to specify
+which file the system is defined in.
+
+@end defvr
+
 @defvr {Scheme Variable} cmake-build-system
 This variable is exported by @code{(guix build-system cmake)}.  It
 implements the build procedure for packages using the
diff --git a/guix/build-system/asdf.scm b/guix/build-system/asdf.scm
new file mode 100644
index 0000000..f28c098
--- /dev/null
+++ b/guix/build-system/asdf.scm
@@ -0,0 +1,360 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build-system asdf)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix packages)
+  #:use-module (guix derivations)
+  #:use-module (guix search-paths)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system gnu)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (%asdf-build-system-modules
+            %asdf-build-modules
+            asdf-build
+            asdf-build-system/sbcl
+            asdf-build-system/ecl
+            asdf-build-system/source
+            sbcl-package->cl-source-package
+            sbcl-package->ecl-package))
+
+;; Commentary:
+;;
+;; Standard build procedure for asdf packages.  This is implemented as an
+;; extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define %asdf-build-system-modules
+  ;; Imported build-side modules
+  `((guix build asdf-build-system)
+    (guix build lisp-utils)
+    ,@%gnu-build-system-modules))
+
+(define %asdf-build-modules
+  ;; Used (visible) build-side modules
+  '((guix build asdf-build-system)
+    (guix build utils)
+    (guix build lisp-utils)))
+
+(define (default-lisp implementation)
+  "Return the default package for the lisp IMPLEMENTATION."
+  ;; Lazily resolve the binding to avoid a circular dependancy.
+  (let ((lisp-module (resolve-interface '(gnu packages lisp))))
+    (module-ref lisp-module implementation)))
+
+(define* (lower/source name
+                       #:key source inputs outputs native-inputs system target
+                       #:allow-other-keys
+                       #:rest arguments)
+  "Return a bag for NAME"
+  (define private-keywords
+    '(#:target #:inputs #:native-inputs))
+
+  (and (not target)
+       (bag
+         (name name)
+         (system system)
+         (host-inputs `(,@(if source
+                              `(("source" ,source))
+                              '())
+                        ,@inputs
+                        ,@(standard-packages)))
+         (build-inputs native-inputs)
+         (outputs outputs)
+         (build asdf-build/source)
+         (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define* (asdf-build/source store name inputs
+                            #:key source outputs
+                            (phases '(@ (guix build asdf-build-system)
+                                        %standard-phases/source))
+                            (search-paths '())
+                            (system (%current-system))
+                            (guile #f)
+                            (imported-modules %asdf-build-system-modules)
+                            (modules %asdf-build-modules))
+  (define builder
+    `(begin
+       (use-modules ,@modules)
+       (asdf-build/source #:name ,name
+                          #:source ,(match (assoc-ref inputs "source")
+                                      (((? derivation? source))
+                                       (derivation->output-path source))
+                                      ((source) source)
+                                      (source source))
+                          #:system ,system
+                          #:phases ,phases
+                          #:outputs %outputs
+                          #:search-paths ',(map search-path-specification->sexp
+                                                search-paths)
+                          #:inputs %build-inputs)))
+
+  (define guile-for-build
+    (match guile
+      ((? package?)
+       (package-derivation store guile system #:graft? #f))
+      (#f
+       (let* ((distro (resolve-interface '(gnu packages commencement)))
+              (guile (module-ref distro 'guile-final)))
+         (package-derivation store guile system #:graft? #f)))))
+
+  (build-expression->derivation store name builder
+                                #:inputs inputs
+                                #:system system
+                                #:modules imported-modules
+                                #:outputs outputs
+                                #:guile-for-build guile-for-build))
+
+(define* (package-with-build-system from-build-system to-build-system
+                                    from-prefix to-prefix
+                                    #:key variant-property
+                                    phases-transformer)
+  "Return a precedure which takes a package PKG which uses FROM-BUILD-SYSTEM,
+and returns one using TO-BUILD-SYSTEM.  If PKG was prefixed by FROM-PREFIX,
+the resulting package will be prefixed by TO-PREFIX.  Inputs of PKG are
+recursively transformed using the same rule.  The result's #:phases argument
+will be modified by PHASES-TRANSFORMER, an S-expression which evaluates on the
+build side to a procedure of one argument.
+
+VARIANT-PROPERTY can be added to a package's properties to indicate that the
+corresponding package promise should be used as the result of this
+transformation.  This allows the result to differ from what the transformation
+would otherwise produce.
+
+If TO-BUILD-SYSTEM is asdf-build-system/source, the resulting package will be
+set up using CL source package conventions."
+  (define target-is-source? (eq? asdf-build-system/source to-build-system))
+
+  (define (transform-package-name name)
+    (if (string-prefix? from-prefix name)
+        (let ((new-name (string-drop name (string-length from-prefix))))
+          (if (string-prefix? to-prefix new-name)
+              new-name
+              (string-append to-prefix new-name)))
+        name))
+
+  (define (has-from-build-system? pkg)
+    (eq? from-build-system (package-build-system pkg)))
+
+  (define transform
+    (memoize
+     (lambda (pkg)
+       (define rewrite
+         (match-lambda
+           ((name content . rest)
+            (let* ((is-package? (package? content))
+                   (new-content (if is-package? (transform content) content))
+                   (new-name (if (and is-package?
+                                      (string-prefix? from-prefix name))
+                                 (package-name new-content)
+                                 name)))
+              `(,new-name ,new-content ,@rest)))))
+
+       ;; Special considerations for source packages: CL inputs become
+       ;; propagated, and un-handled arguments are removed. Native inputs are
+       ;; removed as are extraneous outputs.
+       (define new-propagated-inputs
+         (if target-is-source?
+             (map rewrite
+                  (filter (match-lambda
+                            ((_ input . _)
+                             (has-from-build-system? input)))
+                          (package-inputs pkg)))
+             '()))
+
+       (define new-inputs
+         (if target-is-source?
+             (map rewrite
+                  (filter (match-lambda
+                            ((_ input . _)
+                             (not (has-from-build-system? input))))
+                          (package-inputs pkg)))
+             (map rewrite (package-inputs pkg))))
+
+       (define base-arguments
+         (if target-is-source?
+             (strip-keyword-arguments
+              '(#:tests? #:special-dependencies #:asd-file
+                #:test-only-systems #:lisp)
+              (package-arguments pkg))
+             (package-arguments pkg)))
+
+       (cond
+        ((and variant-property
+              (assoc-ref (package-properties pkg) variant-property))
+         => force)
+
+        ((has-from-build-system? pkg)
+         (package
+           (inherit pkg)
+           (location (package-location pkg))
+           (name (transform-package-name (package-name pkg)))
+           (build-system to-build-system)
+           (arguments
+            (substitute-keyword-arguments base-arguments
+              ((#:phases phases) (list phases-transformer phases))))
+           (inputs new-inputs)
+           (propagated-inputs new-propagated-inputs)
+           (native-inputs (if target-is-source?
+                              '()
+                              (map rewrite (package-native-inputs pkg))))
+           (outputs (if target-is-source?
+                        '("out")
+                        (package-outputs pkg)))))
+        (else pkg)))))
+
+  transform)
+
+(define (strip-variant-as-necessary variant pkg)
+  (define properties (package-properties pkg))
+  (if (assoc variant properties)
+      (package
+        (inherit pkg)
+        (properties (alist-delete variant properties)))
+      pkg))
+
+(define (lower lisp-implementation)
+  (lambda* (name
+            #:key source inputs outputs native-inputs system target
+            (lisp (default-lisp (string->symbol lisp-implementation)))
+            #:allow-other-keys
+            #:rest arguments)
+    "Return a bag for NAME"
+    (define private-keywords
+      '(#:target #:inputs #:native-inputs #:lisp))
+
+    (and (not target)
+         (bag
+           (name name)
+           (system system)
+           (host-inputs `(,@(if source
+                                `(("source" ,source))
+                                '())
+                          ,@inputs
+                          ,@(standard-packages)))
+           (build-inputs `((,lisp-implementation ,lisp)
+                           ,@native-inputs))
+           (outputs outputs)
+           (build (asdf-build lisp-implementation))
+           (arguments (strip-keyword-arguments private-keywords arguments))))))
+
+(define (asdf-build lisp-implementation)
+  (lambda* (store name inputs
+                  #:key source outputs
+                  (tests? #t)
+                  (special-dependencies ''())
+                  (asd-file #f)
+                  (test-only-systems ''())
+                  (lisp lisp-implementation)
+                  (phases '(@ (guix build asdf-build-system)
+                              %standard-phases))
+                  (search-paths '())
+                  (system (%current-system))
+                  (guile #f)
+                  (imported-modules %asdf-build-system-modules)
+                  (modules %asdf-build-modules))
+
+    (define builder
+      `(begin
+         (use-modules ,@modules)
+         (asdf-build #:name ,name
+                     #:source ,(match (assoc-ref inputs "source")
+                                 (((? derivation? source))
+                                  (derivation->output-path source))
+                                 ((source) source)
+                                 (source source))
+                     #:lisp ,lisp
+                     #:special-dependencies ,special-dependencies
+                     #:asd-file ,asd-file
+                     #:test-only-systems ,test-only-systems
+                     #:system ,system
+                     #:tests? ,tests?
+                     #:phases ,phases
+                     #:outputs %outputs
+                     #:search-paths ',(map search-path-specification->sexp
+                                           search-paths)
+                     #:inputs %build-inputs)))
+
+    (define guile-for-build
+      (match guile
+        ((? package?)
+         (package-derivation store guile system #:graft? #f))
+        (#f
+         (let* ((distro (resolve-interface '(gnu packages commencement)))
+                (guile (module-ref distro 'guile-final)))
+           (package-derivation store guile system #:graft? #f)))))
+
+    (build-expression->derivation store name builder
+                                  #:inputs inputs
+                                  #:system system
+                                  #:modules imported-modules
+                                  #:outputs outputs
+                                  #:guile-for-build guile-for-build)))
+
+(define asdf-build-system/sbcl
+  (build-system
+    (name 'asdf/sbcl)
+    (description "The build system for ASDF binary packages using SBCL")
+    (lower (lower "sbcl"))))
+
+(define asdf-build-system/ecl
+  (build-system
+    (name 'asdf/ecl)
+    (description "The build system for ASDF binary packages using ECL")
+    (lower (lower "ecl"))))
+
+(define asdf-build-system/source
+  (build-system
+    (name 'asdf/source)
+    (description "The build system for ASDF source packages")
+    (lower lower/source)))
+
+(define sbcl-package->cl-source-package
+  (let* ((property 'cl-source-variant)
+         (transformer
+          (package-with-build-system asdf-build-system/sbcl
+                                     asdf-build-system/source
+                                     "sbcl-"
+                                     "cl-"
+                                     #:variant-property property
+                                     #:phases-transformer
+                                     '(const %standard-phases/source))))
+    (lambda (pkg)
+      (transformer
+       (strip-variant-as-necessary property pkg)))))
+
+(define sbcl-package->ecl-package
+  (let* ((property 'ecl-variant)
+         (transformer
+          (package-with-build-system asdf-build-system/sbcl
+                                     asdf-build-system/ecl
+                                     "sbcl-"
+                                     "ecl-"
+                                     #:variant-property property
+                                     #:phases-transformer
+                                     'identity)))
+    (lambda (pkg)
+      (transformer
+       (strip-variant-as-necessary property pkg)))))
+
+;;; asdf.scm ends here
diff --git a/guix/build/asdf-build-system.scm b/guix/build/asdf-build-system.scm
new file mode 100644
index 0000000..085d073
--- /dev/null
+++ b/guix/build/asdf-build-system.scm
@@ -0,0 +1,282 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build asdf-build-system)
+  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+  #:use-module (guix build utils)
+  #:use-module (guix build lisp-utils)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 receive)
+  #:use-module (ice-9 regex)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 ftw)
+  #:export (%standard-phases
+            %standard-phases/source
+            asdf-build
+            asdf-build/source))
+
+;; Commentary:
+;;
+;; System for building ASDF packages; creating executable programs and images
+;; from them.
+;;
+;; Code:
+
+(define %object-prefix "/lib")
+
+(define (source-install-prefix lisp)
+  (string-append %install-prefix "/" lisp "-source"))
+
+(define %system-install-prefix
+  (string-append %install-prefix "/systems"))
+
+(define (output-path->package-name path)
+  (package-name->name+version (strip-store-file-name path)))
+
+(define (outputs->name outputs)
+  (output-path->package-name
+   (assoc-ref outputs "out")))
+
+(define (lisp-source-directory output lisp name)
+  (string-append output (source-install-prefix lisp) "/" name))
+
+(define (source-directory output name)
+  (string-append output %install-prefix "/source/" name))
+
+(define (library-directory output lisp)
+  (string-append output %object-prefix
+                 "/" lisp))
+
+(define (output-translation source-path
+                            object-output
+                            lisp)
+  "Return a translation for the system's source path
+to it's binary output."
+  `((,source-path
+     :**/ :*.*.*)
+    (,(library-directory object-output lisp)
+     :**/ :*.*.*)))
+
+(define (source-asd-file output lisp name asd-file)
+  (string-append (lisp-source-directory output lisp name) "/" asd-file))
+
+(define (copy-files-to-output outputs output name)
+  "Copy all files from OUTPUT to \"out\".  Create an extra link to any
+system-defining files in the source to a convenient location.  This is done
+before any compiling so that the compiled source locations will be valid."
+  (let* ((out (assoc-ref outputs output))
+         (source (getcwd))
+         (target (source-directory out name))
+         (system-path (string-append out %system-install-prefix)))
+    (copy-recursively source target)
+    (mkdir-p system-path)
+    (for-each
+     (lambda (file)
+       (symlink file
+                (string-append system-path "/" (basename file))))
+     (find-files target "\\.asd$"))
+    #t))
+
+(define* (install #:key outputs #:allow-other-keys)
+  "Copy and symlink all the source files."
+  (copy-files-to-output outputs "out" (outputs->name outputs)))
+
+(define* (copy-source #:key outputs lisp #:allow-other-keys)
+  "Copy the source to \"out\"."
+  (let* ((out (assoc-ref outputs "out"))
+         (name (remove-lisp-from-name (output-path->package-name out) lisp))
+         (install-path (string-append out %install-prefix)))
+    (copy-files-to-output outputs "out" name)
+    ;; Hide the files from asdf
+    (with-directory-excursion install-path
+      (rename-file "source" (string-append lisp "-source"))
+      (delete-file-recursively "systems")))
+  #t)
+
+(define* (build #:key outputs inputs lisp asd-file
+                #:allow-other-keys)
+  "Compile the system."
+  (let* ((out (assoc-ref outputs "out"))
+         (name (remove-lisp-from-name (output-path->package-name out) lisp))
+         (source-path (lisp-source-directory out lisp name))
+         (translations (wrap-output-translations
+                        `(,(output-translation source-path
+                                               out
+                                               lisp))))
+         (asd-file (and=> asd-file (cut source-asd-file out lisp name <>))))
+
+    (setenv "ASDF_OUTPUT_TRANSLATIONS"
+            (replace-escaped-macros (format #f "~S" translations)))
+
+    ;; We don't need this if we have the asd file, and it can mess with the
+    ;; load ordering we're trying to enforce
+    (unless asd-file
+      (prepend-to-source-registry (string-append source-path "//")))
+
+    (setenv "HOME" out) ; ecl's asdf sometimes wants to create $HOME/.cache
+
+    (parameterize ((%lisp (string-append
+                           (assoc-ref inputs lisp) "/bin/" lisp)))
+      (compile-system name lisp asd-file))
+
+    ;; As above, ecl will sometimes create this even though it doesn't use it
+
+    (let ((cache-directory (string-append out "/.cache")))
+      (when (directory-exists? cache-directory)
+        (delete-file-recursively cache-directory))))
+  #t)
+
+(define* (check #:key lisp tests? outputs inputs asd-file
+                #:allow-other-keys)
+  "Test the system."
+  (let* ((name (remove-lisp-from-name (outputs->name outputs) lisp))
+         (out (assoc-ref outputs "out"))
+         (asd-file (and=> asd-file (cut source-asd-file out lisp name <>))))
+    (if tests?
+        (parameterize ((%lisp (string-append
+                               (assoc-ref inputs lisp) "/bin/" lisp)))
+          (test-system name lisp asd-file))
+        (format #t "test suite not run~%")))
+  #t)
+
+(define* (patch-asd-files #:key outputs
+                          inputs
+                          lisp
+                          special-dependencies
+                          test-only-systems
+                          #:allow-other-keys)
+  "Patch any asd files created by the compilation process so that they can
+find their dependencies.  Exclude any TEST-ONLY-SYSTEMS which were only
+included to run tests.  Add any SPECIAL-DEPENDENCIES which the LISP
+implementation itself provides."
+  (let* ((out (assoc-ref outputs "out"))
+         (name (remove-lisp-from-name (output-path->package-name out) lisp))
+         (registry (lset-difference
+                    (lambda (input system)
+                      (match input
+                        ((name . path) (string=? name system))))
+                    (lisp-dependencies lisp inputs)
+                    test-only-systems))
+         (lisp-systems (map first registry)))
+
+    (for-each
+     (lambda (asd-file)
+       (patch-asd-file asd-file registry lisp
+                       (append lisp-systems special-dependencies)))
+     (find-files out "\\.asd$")))
+  #t)
+
+(define* (symlink-asd-files #:key outputs lisp #:allow-other-keys)
+  "Create an extra reference to the system in a convenient location."
+  (let* ((out (assoc-ref outputs "out")))
+    (for-each
+     (lambda (asd-file)
+       (substitute* asd-file
+         ((";;; Built for.*") "") ; remove potential non-determinism
+         (("^\\(DEFSYSTEM(.*)$" all end) (string-append "(asdf:defsystem" end)))
+       (receive (new-asd-file asd-file-directory)
+           (bundle-asd-file out asd-file lisp)
+         (mkdir-p asd-file-directory)
+         (symlink asd-file new-asd-file)
+         ;; Update the source registry for future phases which might want to
+         ;; use the newly compiled system.
+         (prepend-to-source-registry
+          (string-append asd-file-directory "/"))))
+
+     (find-files (string-append out %object-prefix) "\\.asd$"))
+)
+  #t)
+
+(define* (cleanup-files #:key outputs lisp
+                             #:allow-other-keys)
+  "Remove any compiled files which are not a part of the final bundle."
+  (let ((out (assoc-ref outputs "out")))
+    (match lisp
+      ("sbcl"
+       (for-each
+        (lambda (file)
+          (unless (string-suffix? "--system.fasl" file)
+            (delete-file file)))
+        (find-files out "\\.fasl$")))
+      ("ecl"
+       (for-each delete-file
+                 (append (find-files out "\\.fas$")
+                         (find-files out "\\.o$")
+                         (find-files out "\\.a$")))))
+
+    (with-directory-excursion (library-directory out lisp)
+      (for-each
+       (lambda (file)
+         (rename-file file
+                      (string-append "./" (basename file))))
+       (find-files "."))
+      (for-each delete-file-recursively
+                (scandir "."
+                         (lambda (file)
+                           (and
+                            (directory-exists? file)
+                            (string<> "." file)
+                            (string<> ".." file)))))))
+  #t)
+
+(define* (strip #:key lisp #:allow-other-keys #:rest args)
+  ;; stripping sbcl binaries removes their entry program and extra systems
+  (or (string=? lisp "sbcl")
+      (apply (assoc-ref gnu:%standard-phases 'strip) args)))
+
+(define %standard-phases/source
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'check)
+    (delete 'build)
+    (replace 'install install)))
+
+(define %standard-phases
+  (modify-phases gnu:%standard-phases
+    (delete 'configure)
+    (delete 'install)
+    (replace 'build build)
+    (add-before 'build 'copy-source copy-source)
+    (replace 'check check)
+    (replace 'strip strip)
+    (add-after 'check 'link-dependencies patch-asd-files)
+    (add-after 'link-dependencies 'cleanup cleanup-files)
+    (add-after 'cleanup 'create-symlinks symlink-asd-files)))
+
+(define* (asdf-build #:key inputs
+                     (phases %standard-phases)
+                     #:allow-other-keys
+                     #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+(define* (asdf-build/source #:key inputs
+                            (phases %standard-phases/source)
+                            #:allow-other-keys
+                            #:rest args)
+  (apply gnu:gnu-build
+         #:inputs inputs
+         #:phases phases
+         args))
+
+;;; asdf-build-system.scm ends here
diff --git a/guix/build/lisp-utils.scm b/guix/build/lisp-utils.scm
new file mode 100644
index 0000000..55a07c7
--- /dev/null
+++ b/guix/build/lisp-utils.scm
@@ -0,0 +1,327 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Andy Patterson <ajpatter@uwaterloo.ca>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix build lisp-utils)
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 regex)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (guix build utils)
+  #:export (%lisp
+            %install-prefix
+            lisp-eval-program
+            compile-system
+            test-system
+            replace-escaped-macros
+            generate-executable-wrapper-system
+            generate-executable-entry-point
+            generate-executable-for-system
+            patch-asd-file
+            bundle-install-prefix
+            lisp-dependencies
+            bundle-asd-file
+            remove-lisp-from-name
+            wrap-output-translations
+            prepend-to-source-registry
+            build-program
+            build-image))
+
+;;; Commentary:
+;;;
+;;; Tools to evaluate lisp programs within a lisp session, generate wrapper
+;;; systems for executables. Compile, test, and produce images for systems and
+;;; programs, and link them with their dependencies.
+;;;
+;;; Code:
+
+(define %lisp
+  ;; File name of the Lisp compiler.
+  (make-parameter "lisp"))
+
+(define %install-prefix "/share/common-lisp")
+
+(define (bundle-install-prefix lisp)
+  (string-append %install-prefix "/" lisp "-bundle-systems"))
+
+(define (remove-lisp-from-name name lisp)
+  (string-drop name (1+ (string-length lisp))))
+
+(define (wrap-output-translations translations)
+  `(:output-translations
+    ,@translations
+    :inherit-configuration))
+
+(define (lisp-eval-program lisp program)
+  "Evaluate PROGRAM with a given LISP implementation."
+  (unless (zero? (apply system*
+                        (lisp-invoke lisp (format #f "~S" program))))
+    (error "lisp-eval-program failed!" lisp program)))
+
+(define (lisp-invoke lisp program)
+  "Return a list of arguments for system* determining how to invoke LISP
+with PROGRAM."
+  (match lisp
+    ("sbcl" `(,(%lisp) "--non-interactive" "--eval" ,program))
+    ("ecl" `(,(%lisp) "-eval" ,program "-eval" "(quit)"))))
+
+(define (asdf-load-all systems)
+  (map (lambda (system)
+         `(funcall
+           (find-symbol
+            (symbol-name :load-system)
+            (symbol-name :asdf))
+           ,system))
+       systems))
+
+(define (compile-system system lisp asd-file)
+  "Use a lisp implementation to compile SYSTEM using asdf.  Load ASD-FILE
+first if SYSTEM is defined there."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       (in-package :asdf)
+                       ,@(if asd-file
+                             `((load ,asd-file))
+                             '())
+                       (in-package :cl-user)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :compile-bundle-op)
+                                 (symbol-name :asdf))
+                                ,system)
+                       (funcall (find-symbol
+                                 (symbol-name :operate)
+                                 (symbol-name :asdf))
+                                (find-symbol
+                                 (symbol-name :deliver-asd-op)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (test-system system lisp asd-file)
+  "Use a lisp implementation to test SYSTEM using asdf.  Load ASD-FILE first
+if SYSTEM is defined there."
+  (lisp-eval-program lisp
+                     `(progn
+                       (require :asdf)
+                       (in-package :asdf)
+                       ,@(if asd-file
+                             `((load ,asd-file))
+                             '())
+                       (in-package :cl-user)
+                       (funcall (find-symbol
+                                 (symbol-name :test-system)
+                                 (symbol-name :asdf))
+                                ,system))))
+
+(define (string->lisp-keyword . strings)
+  "Return a lisp keyword for the concatenation of STRINGS."
+  (string->symbol (apply string-append ":" strings)))
+
+(define (generate-executable-for-system type system lisp)
+  "Use LISP to generate an executable, whose TYPE can be \"image\" or
+\"program\".  The latter will always be standalone.  Depends on having created
+a \"SYSTEM-exec\" system which contains the entry program."
+  (lisp-eval-program
+   lisp
+   `(progn
+     (require :asdf)
+     (funcall (find-symbol
+               (symbol-name :operate)
+               (symbol-name :asdf))
+              (find-symbol
+               (symbol-name ,(string->lisp-keyword type "-op"))
+               (symbol-name :asdf))
+              ,(string-append system "-exec")))))
+
+(define (generate-executable-wrapper-system system dependencies)
+  "Generates a system which can be used by asdf to produce an image or program
+inside the current directory.  The image or program will contain
+DEPENDENCIES."
+  (with-output-to-file (string-append system "-exec.asd")
+    (lambda _
+      (format #t "~y~%"
+              `(defsystem ,(string->lisp-keyword system "-exec")
+                 :entry-point ,(string-append system "-exec:main")
+                 :depends-on (:uiop
+                              ,@(map string->lisp-keyword
+                                     dependencies))
+                 :components ((:file ,(string-append system "-exec"))))))))
+
+(define (generate-executable-entry-point system entry-program)
+  "Generates an entry point program from the list of lisp statements
+ENTRY-PROGRAM for SYSTEM within the current directory."
+  (with-output-to-file (string-append system "-exec.lisp")
+    (lambda _
+      (let ((system (string->lisp-keyword system "-exec")))
+        (format #t "~{~y~%~%~}"
+                `((defpackage ,system
+                    (:use :cl)
+                    (:export :main))
+
+                  (in-package ,system)
+
+                  (defun main ()
+                    (let ((arguments uiop:*command-line-arguments*))
+                      (declare (ignorable arguments))
+                      ,@entry-program))))))))
+
+(define (wrap-perform-method lisp registry dependencies file-name)
+  "Creates a wrapper method which allows the system to locate its dependent
+systems from REGISTRY, an alist of the same form as %outputs, which contains
+lisp systems which the systems is dependent on.  All DEPENDENCIES which the
+system depends on will the be loaded before this system."
+  (let* ((system (string-drop-right (basename file-name) 4))
+         (system-symbol (string->lisp-keyword system)))
+
+    `(defmethod asdf:perform :before
+       (op (c (eql (asdf:find-system ,system-symbol))))
+       (asdf/source-registry:ensure-source-registry)
+       ,@(map (match-lambda
+                ((name . path)
+                 (let ((asd-file (string-append path
+                                                (bundle-install-prefix lisp)
+                                                "/" name ".asd")))
+                   `(setf
+                     (gethash ,name
+                              asdf/source-registry:*source-registry*)
+                     ,(string->symbol "#p")
+                     ,(bundle-asd-file path asd-file lisp)))))
+              registry)
+       ,@(map (lambda (system)
+                `(asdf:load-system ,(string->lisp-keyword system)))
+              dependencies))))
+
+(define (patch-asd-file asd-file registry lisp dependencies)
+  "Patches ASD-FILE with a perform method as described in WRAP-PERFORM-METHOD."
+  (chmod asd-file #o644)
+  (let ((port (open-file asd-file "a")))
+    (dynamic-wind
+      (lambda _ #t)
+      (lambda _
+        (display
+         (replace-escaped-macros
+          (format #f "~%~y~%"
+                  (wrap-perform-method lisp registry
+                                       dependencies asd-file)))
+         port))
+      (lambda _ (close-port port))))
+  (chmod asd-file #o444))
+
+(define (lisp-dependencies lisp inputs)
+  "Determine which inputs are lisp system dependencies, by using the convention
+that a lisp system dependency will resemble \"system-LISP\"."
+  (filter-map (match-lambda
+                ((name . value)
+                 (and (string-prefix? lisp name)
+                      (string<> lisp name)
+                      `(,(remove-lisp-from-name name lisp)
+                        . ,value))))
+              inputs))
+
+(define (bundle-asd-file output-path original-asd-file lisp)
+  "Find the symlinked bundle file for ORIGINAL-ASD-FILE by looking in
+OUTPUT-PATH/share/common-lisp/LISP-bundle-systems/<system>.asd.  Returns two
+values: the asd file itself and the directory in which it resides."
+  (let ((bundle-asd-path (string-append output-path
+                                        (bundle-install-prefix lisp))))
+    (values (string-append bundle-asd-path "/" (basename original-asd-file))
+            bundle-asd-path)))
+
+(define (replace-escaped-macros string)
+  "Replace simple lisp forms that the guile writer escapes, for example by
+replacing #{#p}# with #p.  Should only be used to replace truly simple forms
+which are not nested."
+  (regexp-substitute/global #f "(#\\{)(\\S*)(\\}#)" string
+                            'pre 2 'post))
+
+(define (prepend-to-source-registry path)
+  (setenv "CL_SOURCE_REGISTRY"
+          (string-append path ":" (or (getenv "CL_SOURCE_REGISTRY") ""))))
+
+(define* (build-program lisp program #:key inputs
+                        (dependencies (list (basename program)))
+                        entry-program
+                        #:allow-other-keys)
+  "Generate an executable program containing all DEPENDENCIES, and which will
+execute ENTRY-PROGRAM.  The result is placed in PROGRAM.  When executed, it
+will run ENTRY-PROGRAM, a list of Common Lisp expressions in which `arguments'
+has been bound to the command-line arguments which were passed."
+  (generate-executable lisp program
+                       #:inputs inputs
+                       #:dependencies dependencies
+                       #:entry-program entry-program
+                       #:type "program")
+  (let* ((name (basename program))
+         (bin-directory (dirname program)))
+    (with-directory-excursion bin-directory
+      (rename-file (string-append name "-exec")
+                   name)))
+  #t)
+
+(define* (build-image lisp image #:key inputs
+                      (dependencies (list (basename image)))
+                      #:allow-other-keys)
+  "Generate an image, possibly standalone, which contains all DEPENDENCIES,
+placing the result in IMAGE.image."
+  (generate-executable lisp image
+                       #:inputs inputs
+                       #:dependencies dependencies
+                       #:entry-program '(nil)
+                       #:type "image")
+  (let* ((name (basename image))
+         (bin-directory (dirname image)))
+    (with-directory-excursion bin-directory
+      (rename-file (string-append name "-exec--all-systems.image")
+                   (string-append name ".image"))))
+  #t)
+
+(define* (generate-executable lisp out-file #:key inputs
+                              dependencies
+                              entry-program
+                              type
+                              #:allow-other-keys)
+  "Generate an executable by using asdf's TYPE-op, containing whithin the
+image all DEPENDENCIES, and running ENTRY-PROGRAM in the case of an
+executable."
+  (let* ((bin-directory (dirname out-file))
+         (name (basename out-file)))
+    (mkdir-p bin-directory)
+    (with-directory-excursion bin-directory
+      (generate-executable-wrapper-system name dependencies)
+      (generate-executable-entry-point name entry-program))
+
+    (prepend-to-source-registry
+     (string-append bin-directory "/"))
+
+    (setenv "ASDF_OUTPUT_TRANSLATIONS"
+            (replace-escaped-macros
+             (format
+              #f "~S"
+              (wrap-output-translations
+               `(((,bin-directory :**/ :*.*.*)
+                  (,bin-directory :**/ :*.*.*)))))))
+
+    (parameterize ((%lisp (string-append
+                           (assoc-ref inputs lisp) "/bin/" lisp)))
+      (generate-executable-for-system type name lisp))
+
+    (delete-file (string-append bin-directory "/" name "-exec.asd"))
+    (delete-file (string-append bin-directory "/" name "-exec.lisp"))))
-- 
2.10.0

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 01/13] build-system: Add asdf-build-system.
  2016-10-07 21:57         ` Andy Patterson
@ 2016-10-08 12:39           ` Ludovic Courtès
  0 siblings, 0 replies; 51+ messages in thread
From: Ludovic Courtès @ 2016-10-08 12:39 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

Hi Andy,

Andy Patterson <ajpatter@uwaterloo.ca> skribis:

> On Fri, 07 Oct 2016 14:44:38 +0200
> ludo@gnu.org (Ludovic Courtès) wrote:

[...]

>> Andy Patterson <ajpatter@uwaterloo.ca> skribis:
>> 
>> > +(define* (package-with-build-system from-build-system
>> > to-build-system
>> > +                                    from-prefix to-prefix
>> > +                                    #:key variant-property
>> > +                                    phases-transformer)
>> > +  "Return a precedure which takes a package PKG which uses
>> > FROM-BUILD-SYSTEM, +and returns one using TO-BUILD-SYSTEM. If PKG
>> > was prefixed by FROM-PREFIX, the +resulting package will be
>> > prefixed by TO-PREFIX. Inputs of PKG are recursively +transformed
>> > using the same rule. The result's #:phases argument will be
>> > +modified by PHASES-TRANSFORMER, an S-expression which evaluates on
>> > the build +side to a procedure of one argument.  
>> 
>> This code seems to be adapted from ‘package-with-python2’.  It seems
>> that ‘package-input-rewriting’ is too specific to be used here, but at
>> any rate, we should keep an eye towards factorizing this and keep it
>> as simple as possible to facilitate that.
>> 
>
> I'm not sure what the right abstraction is to encompass both.

I’m thinking of (package-input-map proc), which would take care of the
DAG traversal so we don’t have to rewrite that every time.

>> Is #:variant-property necessary here?  It was necessary in
>> ‘package-with-python2’ due to python-2 and python-3 packages sometimes
>> having a different set of dependencies.  If it can be avoided here,
>> it’s better.  Otherwise that’s fine.
>> 
>
> It's necessary any time the variant package must differ from what the
> transformer would ordinarily produce, so that a package which needs to
> include the variant knows how to find it in the recursive step. In our
> case, ecl packages may need different phases or outputs for binary
> generation.
>
> Also, the dependencies could differ, for example stumpwm used to use
> the built-in clx on ecl.

OK, that makes a lot of sense; it’s similar to the Python situation.

>> > +(define %install-prefix "/share/common-lisp")  
>> 
>> What about “lib/common-lisp” for architecture-dependent files
>> (binaries)?  What do other distros do?
>> 
>
> Binaries are placed in /lib/<lisp>/. /share/common-lisp is just used
> for source or symlinked .asd files (as is the convention). The other
> distributions I've seen which package Common Lisp libraries (Debian and
> Gentoo) do not distribute binaries for systems, and what they do is
> basically equivalent to the asdf-build-system/source. I
> think /lib/<lisp>/ is a good place for binaries, since the
> implementations place their extra included system binaries there,
> roughly (/lib/sbcl/contrib; /lib/ecl-<version>).

Alright.  Maybe just add a comment next to ‘%install-prefix’ stating
that this is the installation prefix for source, not for binaries (I had
overlooked that), and maybe rename it to ‘%source-install-prefix’.

> Cool. Fixes attached inline.

No further comments from me.

> Are the packages also OK? I'd like to start fixing any problems with
> those as well.

I’ll take a quick look and will leave the final word to 宋文武.

Thanks for your patience!

Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 02/12] gnu: Add alexandria.
  2016-09-27  4:15 ` [PATCH 02/12] gnu: Add alexandria Andy Patterson
@ 2016-10-08 12:43   ` Ludovic Courtès
  0 siblings, 0 replies; 51+ messages in thread
From: Ludovic Courtès @ 2016-10-08 12:43 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

Andy Patterson <ajpatter@uwaterloo.ca> skribis:

> * gnu/packages/lisp.scm (alexandria, alexandria-sbcl, alexandria-ecl):
>   New variables.

[...]

> +(define-public alexandria
> +  (let ((revision "1")
> +        (commit "926a066611b7b11cb71e26c827a271e500888c30"))
> +    (package
> +      (name "alexandria")
> +      (version (string-append "0.0.0-" revision "." (string-take commit 7)))
> +      (source (origin
> +                (method git-fetch)
> +                (uri
> +                 (git-reference
> +                  (url "https://gitlab.common-lisp.net/alexandria/alexandria.git")
> +                  (commit commit)))
> +                (sha256
> +                 (base32 "18yncicdkh294j05rhgm23gzi36y9qy6vrfba8vg69jrxjp1hx8l"))
> +                (file-name (string-append name "-" version "-checkout"))))
> +      (build-system asdf-build-system/source)
> +      (synopsis "Collection of portable utilities for Common Lisp")
> +      (description "Alexandria is a collection of portable utilities.  It does
> +not contain conceptual extensions to Common Lisp.  It is conservative in
> +scope, and portable between implementations.")
> +      (home-page "https://common-lisp.net/project/alexandria/")
> +      (license license:public-domain))))
> +
> +(define-public alexandria-sbcl
> +  (package
> +    (inherit alexandria)
> +    (name "alexandria-sbcl")
> +    (build-system asdf-build-system/sbcl)
> +    (inputs `(("alexandria" ,alexandria)))))
> +
> +(define-public alexandria-ecl
> +  (package
> +    (inherit alexandria)
> +    (name "alexandria-ecl")
> +    (build-system asdf-build-system/ecl)
> +    (inputs `(("alexandria" ,alexandria)))))

It’s unusual that the “alexandria” package provides the source and that
the others depend on it rather than have an ‘origin’ as their source.
But as you wrote in the build system code, the raw source can be
interpreted by CL implementations other than SBCL or ECL, right?

Otherwise LGTM.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 03/12] gnu: Add fiveam.
  2016-09-27  4:15 ` [PATCH 03/12] gnu: Add fiveam Andy Patterson
@ 2016-10-08 12:48   ` Ludovic Courtès
  0 siblings, 0 replies; 51+ messages in thread
From: Ludovic Courtès @ 2016-10-08 12:48 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

Andy Patterson <ajpatter@uwaterloo.ca> skribis:

> * gnu/packages/lisp.scm (fiveam, fiveam-sbcl, fiveam-ecl): New
>   variables.

LGTM.

Something that maybe wasn’t discussed is the package naming convention.
So far we usually prefix packages that provide libraries by the language
or implementation name: “python-”, “emacs-”, “guile-”, etc.  For
packages that provide standalone programs the convention is to use the
program name: “stumpwm”, “darcs”, “guix”, etc.

Perhaps we could use the “cl-” prefix for source packages, and then the
“sbcl-” and “ecl-” prefixes (instead of suffixes) for binaries?

That would make you change this patch series and I understand that may
not make you happy though.  :-)

Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 10/12] gnu: Add slynk.
  2016-09-27  4:15 ` [PATCH 10/12] gnu: Add slynk Andy Patterson
@ 2016-10-08 12:59   ` Ludovic Courtès
  0 siblings, 0 replies; 51+ messages in thread
From: Ludovic Courtès @ 2016-10-08 12:59 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

Andy Patterson <ajpatter@uwaterloo.ca> skribis:

> * gnu/packages/lisp.scm (slynk, slynk-sbcl, slynk-ecl): New variables.

[...]

> +    (synopsis "Common Lisp IDE for Emacs")
> +    (description "SLY is a fork of SLIME.  It also featrues a completely

To make it more standalone, maybe something like: “SLY is a fork of
SLIME, the foobar IDEish mode for Emacs.”

Typo: “features”.

> +redesigned REPL based on Emacs's own full-featured comint.el, live code

@file{comint.el}

> +(define slynk-sbcl-boot0
> +  (package
> +    (inherit slynk)
> +    (name "slynk-sbcl")

It’s best to include “-boot0” in ‘name’ too.

However, could you add a comment as to what this “boot” package does,
and what the general idea is?

> +(define slynk-mrepl-sbcl
> +  (package
> +    (inherit slynk-arglists-sbcl)
> +    (name "slynk-mrepl-sbcl")))
> +
> +(define slynk-mrepl-ecl
> +  (package
> +    (inherit slynk-arglists-ecl)
> +    (name "slynk-mrepl-ecl")))
> +
> +(define slynk-trace-dialog-sbcl
> +  (package
> +    (inherit slynk-arglists-sbcl)
> +    (name "slynk-trace-dialog-sbcl")))
> +
> +(define slynk-trace-dialog-ecl
> +  (package
> +    (inherit slynk-arglists-ecl)
> +    (name "slynk-trace-dialog-ecl")))
> +
> +(define slynk-profiler-sbcl
> +  (package
> +    (inherit slynk-arglists-sbcl)
> +    (name "slynk-profiler-sbcl")))

I don’t follow what’s going on here.  These are all the same packages as
“arglists” but with a different name?  What for?

> +                   (patch-asd-file
> +                    asd-file
> +                    (map
> +                     (lambda (dependency)
> +                       `(,dependency
> +                         . ,(string-append
> +                             (assoc-ref inputs dependency))))

Simply: (cons dependency (assoc-ref …)), more readable than the dot
notation here.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
                   ` (14 preceding siblings ...)
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
@ 2016-10-08 13:00 ` Ludovic Courtès
  2016-10-08 13:28   ` 宋文武
  2016-10-10 17:47   ` Andy Patterson
  15 siblings, 2 replies; 51+ messages in thread
From: Ludovic Courtès @ 2016-10-08 13:00 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel

I browsed the patch series quickly; the packages I did not comment on
LGTM, modulo the question of whether we should prefix them.

Thanks!

Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-10-08 13:00 ` [PATCH 0/12]: " Ludovic Courtès
@ 2016-10-08 13:28   ` 宋文武
  2016-10-10 17:54     ` Andy Patterson
  2016-10-10 17:47   ` Andy Patterson
  1 sibling, 1 reply; 51+ messages in thread
From: 宋文武 @ 2016-10-08 13:28 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

ludo@gnu.org (Ludovic Courtès) writes:

> I browsed the patch series quickly; the packages I did not comment on
> LGTM, modulo the question of whether we should prefix them.
>

Thanks for the review!  I push them :-)

(the V2 patches already use prefix names.)

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v2 00/13]: Add asdf-build-system.
  2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
                     ` (13 preceding siblings ...)
  2016-10-06 21:04   ` [PATCH v2 00/13]: Add asdf-build-system Ludovic Courtès
@ 2016-10-08 13:30   ` 宋文武
  14 siblings, 0 replies; 51+ messages in thread
From: 宋文武 @ 2016-10-08 13:30 UTC (permalink / raw)
  To: Andy Patterson; +Cc: guix-devel


All applied, thanks!

The `sbcl-stumpwm-with-slynk' package ends up with a 'stumpwm-exec.fasl'
file, so I remove it manually.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-10-08 13:00 ` [PATCH 0/12]: " Ludovic Courtès
  2016-10-08 13:28   ` 宋文武
@ 2016-10-10 17:47   ` Andy Patterson
  1 sibling, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-10 17:47 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

Hi.

On Sat, 08 Oct 2016 15:00:27 +0200
ludo@gnu.org (Ludovic Courtès) wrote:

> I browsed the patch series quickly; the packages I did not comment on
> LGTM, modulo the question of whether we should prefix them.

Thanks. It looks like there are some suggestions there which weren't
covered by the v2/v3 patch series, so I'll work on those when I get the
chance.

> 
> Thanks!
> 
> Ludo’.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 0/12]: Add asdf-build-system.
  2016-10-08 13:28   ` 宋文武
@ 2016-10-10 17:54     ` Andy Patterson
  0 siblings, 0 replies; 51+ messages in thread
From: Andy Patterson @ 2016-10-10 17:54 UTC (permalink / raw)
  To: 宋文武; +Cc: guix-devel

Hi.

On Sat, 08 Oct 2016 21:28:46 +0800
iyzsong@member.fsf.org (宋文武) wrote:

> ludo@gnu.org (Ludovic Courtès) writes:
> 
> > I browsed the patch series quickly; the packages I did not comment
> > on LGTM, modulo the question of whether we should prefix them.
> >  
> 
> Thanks for the review!  I push them :-)
> 
> (the V2 patches already use prefix names.)

Thanks, and especially for the review and suggestions.

Could you also take a look at the fix for ecl which I posted at
<https://lists.gnu.org/archive/html/guix-devel/2016-10/msg00330.html>?
Without it, the ecl packages are a bit broken, for example:

$ guix environment --container --ad-hoc ecl ecl-slynk -- ecl -eval \
"(mapc 'require '(asdf slynk))" 

which should give you a REPL with slynk loaded, but instead fails. As I
said, I'll try to get it fixed upstream for their next release.

Thanks,

--
Andy

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2016-10-10 17:54 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-27  4:15 [PATCH 0/12]: Add asdf-build-system Andy Patterson
2016-09-27  4:15 ` [PATCH 01/12] build-system: " Andy Patterson
2016-09-27  4:15 ` [PATCH 02/12] gnu: Add alexandria Andy Patterson
2016-10-08 12:43   ` Ludovic Courtès
2016-09-27  4:15 ` [PATCH 03/12] gnu: Add fiveam Andy Patterson
2016-10-08 12:48   ` Ludovic Courtès
2016-09-27  4:15 ` [PATCH 04/12] gnu: Add bordeaux-threads Andy Patterson
2016-09-27  4:15 ` [PATCH 05/12] gnu: Add trivial-gray-streams Andy Patterson
2016-09-27  4:15 ` [PATCH 06/12] gnu: Add flexi-streams Andy Patterson
2016-09-27  4:15 ` [PATCH 07/12] gnu: Add cl-ppcre Andy Patterson
2016-09-27  4:15 ` [PATCH 08/12] gnu: Add clx Andy Patterson
2016-09-27  4:15 ` [PATCH 09/12] gnu: Add stumpwm Andy Patterson
2016-09-27  4:15 ` [PATCH 10/12] gnu: Add slynk Andy Patterson
2016-10-08 12:59   ` Ludovic Courtès
2016-09-27  4:15 ` [PATCH 11/12] gnu: Add stumpwm-with-slynk-sbcl Andy Patterson
2016-09-27  4:15 ` [PATCH 12/12] gnu: Add stumpwm-with-slynk-image-sbcl Andy Patterson
2016-09-27 12:51 ` [PATCH 0/12]: Add asdf-build-system James Richardson
2016-09-29  2:30 ` Andy Patterson
2016-09-30 11:45   ` 宋文武
2016-10-03  2:41     ` Andy Patterson
2016-10-03  2:41 ` [PATCH v2 00/13]: " Andy Patterson
2016-10-03  2:41   ` [PATCH v2 01/13] build-system: " Andy Patterson
2016-10-05  4:55     ` 宋文武
2016-10-05 20:59       ` Andy Patterson
2016-10-07  8:07         ` Andy Patterson
2016-10-07  8:07     ` Andy Patterson
2016-10-07 12:44       ` Ludovic Courtès
2016-10-07 21:57         ` Andy Patterson
2016-10-08 12:39           ` Ludovic Courtès
2016-10-03  2:41   ` [PATCH v2 02/13] gnu: sbcl: Honour XDG_DATA_DIRS Andy Patterson
2016-10-03  2:41   ` [PATCH v2 03/13] gnu: ecl: " Andy Patterson
2016-10-03  2:41   ` [PATCH v2 04/13] gnu: Add cl-alexandria Andy Patterson
2016-10-03  2:41   ` [PATCH v2 05/13] gnu: Add cl-fiveam Andy Patterson
2016-10-03  2:41   ` [PATCH v2 06/13] gnu: Add cl-bordeaux-threads Andy Patterson
2016-10-03  2:41   ` [PATCH v2 07/13] gnu: Add cl-trivial-gray-streams Andy Patterson
2016-10-03  2:41   ` [PATCH v2 08/13] gnu: Add cl-flexi-streams Andy Patterson
2016-10-03  2:41   ` [PATCH v2 09/13] gnu: Add cl-ppcre Andy Patterson
2016-10-03  2:41   ` [PATCH v2 10/13] gnu: Add cl-clx Andy Patterson
2016-10-03  2:41   ` [PATCH v2 11/13] gnu: Add cl-stumpwm Andy Patterson
2016-10-07  8:07     ` Andy Patterson
2016-10-03  2:41   ` [PATCH v2 12/13] gnu: Add cl-slynk Andy Patterson
2016-10-07  8:07     ` Andy Patterson
2016-10-03  2:41   ` [PATCH v2 13/13] gnu: Add sbcl-stumpwm-with-slynk Andy Patterson
2016-10-07  8:07     ` Andy Patterson
2016-10-06 21:04   ` [PATCH v2 00/13]: Add asdf-build-system Ludovic Courtès
2016-10-07  0:59     ` 宋文武
2016-10-08 13:30   ` 宋文武
2016-10-08 13:00 ` [PATCH 0/12]: " Ludovic Courtès
2016-10-08 13:28   ` 宋文武
2016-10-10 17:54     ` Andy Patterson
2016-10-10 17:47   ` Andy Patterson

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).