refactor(buildLisp): Inline dependency loading in genCompileLisp

This commit is contained in:
Vincent Ambo 2020-01-08 21:39:06 +00:00
parent b5e1e81a3d
commit 2bfe073eb2

View file

@ -15,46 +15,52 @@ let
# Internal helper definitions # Internal helper definitions
# #
# 'genLoadLisp' generates Lisp code that instructs SBCL to load all
# the provided Lisp libraries.
genLoadLisp = deps: lib.concatStringsSep "\n"
(map (lib: "(load \"${lib}/${lib.lispName}.fasl\")") (allDeps deps));
# 'genCompileLisp' generates a Lisp file that instructs SBCL to # 'genCompileLisp' generates a Lisp file that instructs SBCL to
# compile the provided list of Lisp source files to $out. # compile the provided list of Lisp source files to $out.
genCompileLisp = srcs: writeText "compile.lisp" '' genCompileLisp = srcs: deps: writeText "compile.lisp" ''
;; This file compiles the specified sources into the Nix build ;; This file compiles the specified sources into the Nix build
;; directory, creating one FASL file for each source. ;; directory, creating one FASL file for each source.
(require 'sb-posix) (require 'sb-posix)
(defun nix-compile-lisp (srcfile) ${genLoadLisp deps}
(let ((outfile (make-pathname :type "fasl"
:directory (or (sb-posix:getenv "NIX_BUILD_TOP")
(error "not running in a Nix build"))
:defaults srcfile)))
(multiple-value-bind (_outfile _warnings-p failure-p)
(compile-file srcfile :output-file outfile)
(when failure-p
(sb-posix:exit 1)))))
(let ((*compile-verbose* t) (defun nix-compile-lisp (srcfile)
;; FASL files are compiled into the working directory of the (let ((outfile (make-pathname :type "fasl"
;; build and *then* moved to the correct out location. :directory (or (sb-posix:getenv "NIX_BUILD_TOP")
(pwd (sb-posix:getcwd))) (error "not running in a Nix build"))
:defaults srcfile)))
(multiple-value-bind (_outfile _warnings-p failure-p)
(compile-file srcfile :output-file outfile)
(when failure-p
(sb-posix:exit 1)))))
;; These forms were inserted by the Nix build: (let ((*compile-verbose* t)
${ ;; FASL files are compiled into the working directory of the
lib.concatStringsSep "\n" (map (src: "(nix-compile-lisp \"${src}\")") srcs) ;; build and *then* moved to the correct out location.
} (pwd (sb-posix:getcwd)))
)
''; ;; These forms were inserted by the Nix build:
${
lib.concatStringsSep "\n" (map (src: "(nix-compile-lisp \"${src}\")") srcs)
}
)
'';
# 'allDeps' flattens the list of dependencies (and their # 'allDeps' flattens the list of dependencies (and their
# dependencies) into one list of unique deps. # dependencies) into one list of unique deps.
allDeps = deps: lib.unique (lib.flatten (deps ++ (map (d: d.lispDeps) deps))); #
# TODO(tazjin): Ordering needs to be stable (first occurences from
# 'genLoadLisp' generates a Lisp file that instructs a Lisp to load # innermost to outer), I don't know if this works accidentally or is
# all the provided Lisp libraries. # guaranteed by these lib functions.
genLoadLisp = deps: writeText "load.lisp" ( allDeps = deps: lib.reverseList (
lib.concatStringsSep "\n" (map (lib: "(load \"${lib}/${lib.lispName}.fasl\")") (allDeps deps)) lib.unique (lib.flatten (deps ++ (map (d: d.lispDeps) deps)))
); );
insertLibraryLoads = deps: if deps == [] then "" else "--load ${genLoadLisp deps}";
# #
# Public API functions # Public API functions
@ -70,7 +76,7 @@ let
# 'library' builds a list of Common Lisp files into a single FASL # 'library' builds a list of Common Lisp files into a single FASL
# which can then be loaded into SBCL. # which can then be loaded into SBCL.
library = { name, srcs, deps ? [] }: runCommandNoCC "${name}-cllib" {} '' library = { name, srcs, deps ? [] }: runCommandNoCC "${name}-cllib" {} ''
${sbcl}/bin/sbcl ${insertLibraryLoads deps} --script ${genCompileLisp srcs} ${sbcl}/bin/sbcl --script ${genCompileLisp srcs deps}
# FASL files can be combined by simply concatenating them together: # FASL files can be combined by simply concatenating them together:
mkdir $out mkdir $out
@ -84,7 +90,10 @@ let
# 'sbclWith' creates an image with the specified libraries / # 'sbclWith' creates an image with the specified libraries /
# programs loaded. # programs loaded.
sbclWith = deps: writeShellScriptBin "sbcl" '' sbclWith = deps: writeShellScriptBin "sbcl" ''
exec ${sbcl}/bin/sbcl ${insertLibraryLoads deps} $@ exec ${sbcl}/bin/sbcl ${
if deps == [] then ""
else "--load ${writeText "load.lisp" (genLoadLisp deps)}"
} $@
''; '';
in { in {
library = makeOverridable library; library = makeOverridable library;