nixpkgs/pkgs/development/lisp-modules/quicklisp-to-nix/quicklisp-bootstrap.lisp
Brad Jensen f0c8027ae3 Overhaul quicklisp-to-nix
1. Detect (and automatically handle) parasitic systems.
2. Each nix package has only one asd, and (almost) every parasitic
   package inside it builds.
3. Ensure that parasitic systems are compiled.
4. Remove unnecessary testnames lisp override mechanism (the
   testnae/testSystem is replaced by parasites/buildSystems).
5. Parasitic systems (if included in the system closure) become
   aliases to their host package.
6. Support caching fasl files in a known directory (for faster
   re-generation after modifying quicklisp-to-nix-system-info).
7. Eliminate unnecessary overrides.  We're going to determine ALL
   lisp dependencies correctly.
8. Don't try to "build" lisp packages with make.  lispPackages should
   be about bringing in a lisp library.
9. Eliminate the hand-maintained list of aliases.  Parasites should
   become aliases.  Everything else should be a real package.
2017-08-31 20:10:18 -07:00

77 lines
3.3 KiB
Common Lisp

(unless (find-package :ql-to-nix-util)
(load "ql-to-nix-util.lisp"))
(defpackage :ql-to-nix-quicklisp-bootstrap
(:use :common-lisp :ql-to-nix-util)
(:export #:with-quicklisp)
(:documentation
"This package provides a way to create a temporary quicklisp installation."))
(in-package :ql-to-nix-quicklisp-bootstrap)
(declaim (optimize (debug 3) (speed 0) (space 0) (compilation-speed 0) (safety 3)))
;; This file cannot have any dependencies beyond quicklisp and asdf.
;; Otherwise, we'll miss some dependencies!
(defvar *quicklisp*
(namestring (pathname-as-directory (uiop:getenv "quicklisp")))
"The path to the nix quicklisp package.")
(defun prepare-quicklisp-dir (target-dir quicklisp-prototype-dir)
"Install quicklisp into the specified `target-dir'.
`quicklisp-prototype-dir' should be the path to the quicklisp nix
package."
(ensure-directories-exist target-dir)
(dolist (subdir '(#P"dists/quicklisp/" #P"tmp/" #P"local-projects/" #P"quicklisp/"))
(ensure-directories-exist (merge-pathnames subdir target-dir)))
(with-open-file (s (merge-pathnames #P"dists/quicklisp/enabled.txt" target-dir) :direction :output :if-exists :supersede)
(format s "1~%"))
(uiop:copy-file
(merge-pathnames #P"lib/common-lisp/quicklisp/quicklisp-distinfo.txt" quicklisp-prototype-dir)
(merge-pathnames #P"dists/quicklisp/distinfo.txt" target-dir))
(uiop:copy-file
(merge-pathnames #P"lib/common-lisp/quicklisp/asdf.lisp" quicklisp-prototype-dir)
(merge-pathnames #P"asdf.lisp" target-dir))
(uiop:copy-file
(merge-pathnames #P"lib/common-lisp/quicklisp/setup.lisp" quicklisp-prototype-dir)
(merge-pathnames #P"setup.lisp" target-dir))
(copy-directory-tree
(merge-pathnames #P"lib/common-lisp/quicklisp/quicklisp/" quicklisp-prototype-dir)
(merge-pathnames #P"quicklisp/" target-dir)))
(defun call-with-quicklisp (function &key (target-dir :temp) (cache-dir :temp))
"Invoke the given function with the path to a quicklisp installation.
Quicklisp will be loaded before the function is called. `target-dir'
can either be a pathname for the place where quicklisp should be
installed or `:temp' to request installation in a temporary directory.
`cache-dir' can either be a pathname for a place to store fasls or
`:temp' to request caching in a temporary directory."
(when (find-package :ql)
(error "Already loaded quicklisp in this process"))
(labels
((make-ql (ql-dir)
(prepare-quicklisp-dir ql-dir *quicklisp*)
(with-temporary-asdf-cache (ql-dir)
(load (merge-pathnames #P"setup.lisp" ql-dir))
(if (eq :temp cache-dir)
(funcall function ql-dir)
(with-asdf-cache (ql-dir cache-dir)
(funcall function ql-dir))))))
(if (eq :temp target-dir)
(with-temporary-directory (dir)
(make-ql dir))
(make-ql target-dir))))
(defmacro with-quicklisp ((quicklisp-dir) (&key (cache-dir :temp)) &body body)
"Install quicklisp in a temporary directory, load it, bind
`quicklisp-dir' to the path where quicklisp was installed, and then
evaluate `body'.
`cache-dir' can either be a pathname for a place to store fasls or
`:temp' to request caching in a temporary directory."
`(call-with-quicklisp
(lambda (,quicklisp-dir)
,@body)
:cache-dir ,cache-dir))