summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2017-12-29T15·42+0100
committerVincent Ambo <tazjin@gmail.com>2017-12-29T15·42+0100
commit8703b6102c348d5e860af83a980ba5e1585e3964 (patch)
treee51d41d6da4411caab333f951ff12b34fedc25a7
parent5579ca7d6c620c5dd874ed0654d9a03a73fbf6d6 (diff)
feat(build): Add initial Nix-based build process
Adds a build script using ASDF's program-op to build an executable out
of the Gemma source code.

In addition a Nix derivation is provided that will both compile the
Elm source and place it in a folder, as well as create the executable.

Currently static file serving does not function as intended.
-rw-r--r--build.lisp37
-rw-r--r--default.nix53
-rw-r--r--gemma.asd1
3 files changed, 91 insertions, 0 deletions
diff --git a/build.lisp b/build.lisp
new file mode 100644
index 000000000000..3c8ce3372177
--- /dev/null
+++ b/build.lisp
@@ -0,0 +1,37 @@
+;; Build script for use within Nix.
+
+(require :asdf)
+(require :sb-posix)
+(require :cffi)
+
+(push (format nil "~A/" (sb-posix:getcwd)) asdf:*central-registry*)
+
+;; Quicklisp is configured in the Nix build script
+(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
+                                       (user-homedir-pathname))))
+  (when (probe-file quicklisp-init)
+    (load quicklisp-init)))
+
+;; OpenSSL linking requires pkg_config on NixOS.
+(ql:quickload "inferior-shell")
+
+(defun pkg-config-lib-path (lib)
+  "Look up the location of a library using pkg-config."
+  (let ((flag (inferior-shell:run `("pkg-config" "--libs-only-L" ,lib)
+                                  :output '(:string :stripped t))))
+    (concatenate 'string (subseq flag 2) "/")))
+
+(pushnew (pathname (pkg-config-lib-path "openssl"))
+         cffi:*foreign-library-directories*
+         :test #'equal)
+
+;; cl-prevalence is not in the current Quicklisp -> Nix snapshot
+(ql:quickload "cl-prevalence")
+
+;; the $out path should be set in the application to let Hunchentoot serve the
+;; correct static files.
+
+(if (sb-posix:getenv "out")
+    (defvar *gemma-nix-out-dir* (sb-posix:getenv "out")))
+
+(asdf:operate 'asdf:program-op :gemma)
diff --git a/default.nix b/default.nix
new file mode 100644
index 000000000000..f4a10b542691
--- /dev/null
+++ b/default.nix
@@ -0,0 +1,53 @@
+with import <nixpkgs> {};
+
+stdenv.mkDerivation rec {
+  name = "gemma";
+
+  src = ./.;
+
+  buildInputs = with lispPackages; [
+    sbcl
+    quicklisp
+    hunchentoot
+    cl-json
+    local-time
+    elmPackages.elm
+    pkgconfig
+  ];
+
+  # The build phase has three distinct things it needs to do:
+  #
+  # 1. "Compile" the Elm source into something useful to browsers.
+  #
+  # 2. Configure the Lisp part of the application to serve the compiled Elm
+  #
+  # 3. Build (and don't strip!) an executable out of the Lisp backend.
+  buildPhase = ''
+    mkdir -p $out/share/gemma $out/bin $src/build
+    mkdir .home && export HOME="$PWD/.home"
+
+    # Build Elm
+    cd frontend
+    elm-make --yes Main.elm --output $out/share/gemma/index.html
+
+    # Build Lisp
+    cd $src
+    quicklisp init
+    sbcl --load build.lisp
+
+    # ASDF writes this output into an extremely annoying path, but I also can't
+    # be bothered to figure out the output-translation definition for it.
+    mv $HOME/.cache/common-lisp/sbcl-*/$PWD/build/gemma $out/bin/gemma
+  '';
+
+  installPhase = "true";
+
+  # Stripping an SBCL executable removes the application, which is unfortunate.
+  dontStrip = true;
+
+  meta = with stdenv.lib; {
+    description = "Tool for tracking recurring tasks";
+    homepage    = "https://github.com/tazjin/gemma";
+    license     = licenses.gpl3;
+  };
+}
diff --git a/gemma.asd b/gemma.asd
index 1da8aa0b20c2..54e794a1eea3 100644
--- a/gemma.asd
+++ b/gemma.asd
@@ -21,6 +21,7 @@
                 :components
                 ((:file "gemma"))))
   :build-operation program-op
+  :output-files (program-op (c o) '("build/gemma"))
   :entry-point "gemma::entrypoint"
   :description "Gemma is a household task management system"
   :long-description