fix(buildLisp): Cursed code to fix load ordering

It's not enough to compile in the right order - turns out you also
have to load the compiled objects in the right order.

To achieve this some cursed code has been added that changes the Lisp
generated by Nix to compile the other Lisp so that it also generates
some bash, which Nix can then use to concatenate the FASLs in the
right order to feed them to Lisp again.

It works but I'll replace it with a more elegant solution once one is
needed.
This commit is contained in:
Vincent Ambo 2020-01-08 23:57:34 +00:00
parent 7bc10eb9b7
commit e3a8dc9500

View file

@ -29,26 +29,36 @@ let
${genLoadLisp deps} ${genLoadLisp deps}
(defun nix-compile-lisp (srcfile) (defun nix-compile-lisp (file srcfile)
(let ((outfile (make-pathname :type "fasl" (let ((outfile (make-pathname :type "fasl"
:directory (or (sb-posix:getenv "NIX_BUILD_TOP") :directory (or (sb-posix:getenv "NIX_BUILD_TOP")
(error "not running in a Nix build")) (error "not running in a Nix build"))
:defaults srcfile))) :defaults srcfile)))
(multiple-value-bind (_outfile _warnings-p failure-p) (multiple-value-bind (_outfile _warnings-p failure-p)
(compile-file srcfile :output-file outfile) (compile-file srcfile :output-file outfile)
(when failure-p (if failure-p (sb-posix:exit 1)
(sb-posix:exit 1))))) (progn
;; For the case of multiple files belonging to the same
;; library being compiled, load them in order:
(load outfile)
;; Write them to the FASL list in the same order:
(format file "cat ~a~%" (namestring outfile)))))))
(let ((*compile-verbose* t) (let ((*compile-verbose* t)
;; FASL files are compiled into the working directory of the ;; FASL files are compiled into the working directory of the
;; build and *then* moved to the correct out location. ;; build and *then* moved to the correct out location.
(pwd (sb-posix:getcwd))) (pwd (sb-posix:getcwd)))
(with-open-file (file "cat_fasls"
:direction :output
:if-does-not-exist :create)
;; These forms were inserted by the Nix build: ;; These forms were inserted by the Nix build:
${ ${
lib.concatStringsSep "\n" (map (src: "(nix-compile-lisp \"${src}\")") srcs) lib.concatStringsSep "\n" (map (src: "(nix-compile-lisp file \"${src}\")") srcs)
} }
) ))
''; '';
# 'allDeps' flattens the list of dependencies (and their # 'allDeps' flattens the list of dependencies (and their
@ -97,9 +107,12 @@ let
library = { name, srcs, deps ? [] }: runCommandNoCC "${name}-cllib" {} '' library = { name, srcs, deps ? [] }: runCommandNoCC "${name}-cllib" {} ''
${sbcl}/bin/sbcl --script ${genCompileLisp srcs deps} ${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, but it needs to be in the compilation order.
mkdir $out mkdir $out
cat ./*.fasl > $out/${name}.fasl
chmod +x cat_fasls
./cat_fasls > $out/${name}.fasl
'' // { lispName = name; lispDeps = deps; }; '' // { lispName = name; lispDeps = deps; };
# 'program' creates an executable containing a dumped image of the # 'program' creates an executable containing a dumped image of the