feat(buildLisp): Initial implementation of foreign library loading
Adds a new 'native' parameter to the buildLisp functions in which libraries can be passed in. This does not yet work with CFFI packages.
This commit is contained in:
parent
fd9fb7730a
commit
44820827d1
1 changed files with 46 additions and 9 deletions
|
@ -70,6 +70,22 @@ let
|
||||||
lib.flatten (deps ++ (map (d: d.lispDeps) deps))
|
lib.flatten (deps ++ (map (d: d.lispDeps) deps))
|
||||||
))).result;
|
))).result;
|
||||||
|
|
||||||
|
# 'allNative' extracts all native dependencies of a dependency list
|
||||||
|
# to ensure that library load paths are set correctly during all
|
||||||
|
# compilations and program assembly.
|
||||||
|
allNative = native: deps: lib.unique (
|
||||||
|
lib.flatten (native ++ (map (d: d.lispNativeDeps) deps))
|
||||||
|
);
|
||||||
|
|
||||||
|
# 'pushLibDirs' generates forms that push all native library paths
|
||||||
|
# onto the variable `CFFI:*FOREIGN-LIBRARY-DIRECTORIES*` which is
|
||||||
|
# required for any runtime loading of libraries via CFFI.
|
||||||
|
pushLibDirs = deps: lib.concatStringsSep "\n" (
|
||||||
|
map (l: "(push \"${
|
||||||
|
lib.getLib l
|
||||||
|
}/lib\" cffi:*foreign-library-directories*)") (allNative [] deps)
|
||||||
|
);
|
||||||
|
|
||||||
# 'genDumpLisp' generates a Lisp file that instructs SBCL to dump
|
# 'genDumpLisp' generates a Lisp file that instructs SBCL to dump
|
||||||
# the currently loaded image as an executable to $out/bin/$name.
|
# the currently loaded image as an executable to $out/bin/$name.
|
||||||
#
|
#
|
||||||
|
@ -80,6 +96,10 @@ let
|
||||||
|
|
||||||
${genLoadLisp deps}
|
${genLoadLisp deps}
|
||||||
|
|
||||||
|
;; Push library directories if CFFI is in use.
|
||||||
|
(when (boundp 'cffi:*foreign-library-directories*)
|
||||||
|
${pushLibDirs deps})
|
||||||
|
|
||||||
(let* ((bindir (concatenate 'string (sb-posix:getenv "out") "/bin"))
|
(let* ((bindir (concatenate 'string (sb-posix:getenv "out") "/bin"))
|
||||||
(outpath (make-pathname :name "${name}"
|
(outpath (make-pathname :name "${name}"
|
||||||
:directory bindir)))
|
:directory bindir)))
|
||||||
|
@ -103,8 +123,16 @@ 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 ? [], native ? [] }:
|
||||||
${sbcl}/bin/sbcl --script ${genCompileLisp srcs deps}
|
let
|
||||||
|
lispNativeDeps = (allNative native deps);
|
||||||
|
lispDeps = allDeps deps;
|
||||||
|
in runCommandNoCC "${name}-cllib" {
|
||||||
|
LD_LIBRARY_PATH = lib.makeLibraryPath lispNativeDeps;
|
||||||
|
} ''
|
||||||
|
${sbcl}/bin/sbcl --script ${genCompileLisp srcs lispDeps}
|
||||||
|
|
||||||
|
echo "Compilation finished, assembling FASL files"
|
||||||
|
|
||||||
# FASL files can be combined by simply concatenating them
|
# FASL files can be combined by simply concatenating them
|
||||||
# together, but it needs to be in the compilation order.
|
# together, but it needs to be in the compilation order.
|
||||||
|
@ -112,25 +140,34 @@ let
|
||||||
|
|
||||||
chmod +x cat_fasls
|
chmod +x cat_fasls
|
||||||
./cat_fasls > $out/${name}.fasl
|
./cat_fasls > $out/${name}.fasl
|
||||||
'' // { lispName = name; lispDeps = deps; };
|
'' // {
|
||||||
|
inherit lispNativeDeps lispDeps;
|
||||||
|
lispName = name;
|
||||||
|
};
|
||||||
|
|
||||||
# 'program' creates an executable containing a dumped image of the
|
# 'program' creates an executable containing a dumped image of the
|
||||||
# specified sources and dependencies.
|
# specified sources and dependencies.
|
||||||
program = { name, main ? "${name}:main", srcs, deps ? [] }: runCommandNoCC "${name}" {} ''
|
program = { name, main ? "${name}:main", srcs, deps ? [], native ? [] }:
|
||||||
|
let
|
||||||
|
lispDeps = allDeps deps;
|
||||||
|
selfLib = library {
|
||||||
|
inherit name srcs native;
|
||||||
|
deps = lispDeps;
|
||||||
|
};
|
||||||
|
in runCommandNoCC "${name}" {} ''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
${sbcl}/bin/sbcl --script ${
|
${sbcl}/bin/sbcl --script ${
|
||||||
genDumpLisp name main (lib.singleton (library {
|
genDumpLisp name main ([ selfLib ] ++ lispDeps)
|
||||||
inherit name srcs deps;
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# '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: let lispDeps = allDeps deps; in writeShellScriptBin "sbcl" ''
|
||||||
|
export LD_LIBRARY_PATH=${lib.makeLibraryPath (allNative [] lispDeps)};
|
||||||
exec ${sbcl}/bin/sbcl ${
|
exec ${sbcl}/bin/sbcl ${
|
||||||
if deps == [] then ""
|
if deps == [] then ""
|
||||||
else "--load ${writeText "load.lisp" (genLoadLisp deps)}"
|
else "--load ${writeText "load.lisp" (genLoadLisp lispDeps)}"
|
||||||
} $@
|
} $@
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
|
|
Loading…
Reference in a new issue