diff options
author | Vincent Ambo <Vincent Ambo> | 2020-01-09T02·57+0000 |
---|---|---|
committer | Vincent Ambo <Vincent Ambo> | 2020-01-09T02·57+0000 |
commit | 44820827d191b9a7bec152b5a51d101661e8f4a5 (patch) | |
tree | 041acde1a09670bf6cd289737f47816605d5c596 | |
parent | fd9fb7730ad1f99fe24b524985bb80116a2fd31c (diff) |
feat(buildLisp): Initial implementation of foreign library loading r/364
Adds a new 'native' parameter to the buildLisp functions in which libraries can be passed in. This does not yet work with CFFI packages.
-rw-r--r-- | nix/buildLisp/default.nix | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/nix/buildLisp/default.nix b/nix/buildLisp/default.nix index 15dddfbbab93..15dc5f73e4ba 100644 --- a/nix/buildLisp/default.nix +++ b/nix/buildLisp/default.nix @@ -70,6 +70,22 @@ let lib.flatten (deps ++ (map (d: d.lispDeps) deps)) ))).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 # the currently loaded image as an executable to $out/bin/$name. # @@ -80,6 +96,10 @@ let ${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")) (outpath (make-pathname :name "${name}" :directory bindir))) @@ -103,8 +123,16 @@ let # 'library' builds a list of Common Lisp files into a single FASL # which can then be loaded into SBCL. - library = { name, srcs, deps ? [] }: runCommandNoCC "${name}-cllib" {} '' - ${sbcl}/bin/sbcl --script ${genCompileLisp srcs deps} + library = { name, srcs, deps ? [], native ? [] }: + 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 # together, but it needs to be in the compilation order. @@ -112,25 +140,34 @@ let chmod +x cat_fasls ./cat_fasls > $out/${name}.fasl - '' // { lispName = name; lispDeps = deps; }; + '' // { + inherit lispNativeDeps lispDeps; + lispName = name; + }; # 'program' creates an executable containing a dumped image of the # 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 ${sbcl}/bin/sbcl --script ${ - genDumpLisp name main (lib.singleton (library { - inherit name srcs deps; - })) + genDumpLisp name main ([ selfLib ] ++ lispDeps) } ''; # 'sbclWith' creates an image with the specified libraries / # 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 ${ if deps == [] then "" - else "--load ${writeText "load.lisp" (genLoadLisp deps)}" + else "--load ${writeText "load.lisp" (genLoadLisp lispDeps)}" } $@ ''; in { |