From a0a05786ae2ac7ae8cbd8551c75acaed821228f1 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Fri, 3 Apr 2026 14:17:55 +0100 Subject: [PATCH] Added tooling to create a standalone `binary`, using one neat hack! --- README.md | 32 ++++++++++++++++++++++++-------- project.clj | 4 +++- resources/sh/builder.sh | 19 +++++++++++++++++++ resources/sh/stub.sh | 8 ++++++++ 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 resources/sh/builder.sh create mode 100644 resources/sh/stub.sh diff --git a/README.md b/README.md index 47aee7e..dfa7339 100644 --- a/README.md +++ b/README.md @@ -82,9 +82,32 @@ implement one. You are of course welcome to fork the project and do whatever you like with it! + +### Building + +Build with + + lein uberjar + +This will build a jar file in `target/uberjar/beowulf-VERSION-standalone.jar`, +where VERSION is the current version number. + +On UNIX platforms (includeing Linux), you can build a standalone binary by +invoking a script, `resources/sh/builder.sh`, *after* invoking `lein uberjar`, +so: + + lein uberjar + sh resources/sh/builder.sh + +This should build a standalone binary in `target/beowulf`. + +In order to be able to invoke this binary just like any other program, move it +to somewhere on your path, idealy `${HOME}/bin` or `/usr/local/bin`. + ### Invoking -Invoke with +If you have not built and installed the standalone binary, you may invoke the +uberjar with java -jar target/uberjar/beowulf-0.3.1-standalone.jar --help @@ -103,13 +126,6 @@ Command line arguments as follows: To end a session, type `STOP` at the command prompt. -### Building and Invoking - -Build with - - lein uberjar - - ### Reader macros Currently `SETQ` and `DEFUN` are implemented as reader macros, sort of. It would diff --git a/project.clj b/project.clj index 64742f2..c9b7fc5 100644 --- a/project.clj +++ b/project.clj @@ -25,7 +25,8 @@ :main beowulf.core :plugins [[lein-cloverage "1.2.2"] [lein-codox "0.10.8"] - [lein-environ "1.1.0"]] + [lein-environ "1.1.0"] + [lein-shell "0.5.0"]] :profiles {:jar {:aot :all} :uberjar {:aot :all} :dev {:resource-paths ["resources"]}} @@ -36,6 +37,7 @@ ["clean"] ["codox"] ["uberjar"] + ;; ["shell" "resources/sh/builder.sh" ] ["change" "version" "leiningen.release/bump-version"] ["vcs" "commit"]] :target-path "target/%s" diff --git a/resources/sh/builder.sh b/resources/sh/builder.sh new file mode 100644 index 0000000..2650eb6 --- /dev/null +++ b/resources/sh/builder.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +# Create an executable from an arbitrary uberjar file. +# I am grateful to +# https://coderwall.com/p/ssuaxa/how-to-make-a-jar-file-linux-executable +# for this extremely cute trick. This version is intended for +# Leiningen projects, but if you can understand this you can +# easily hack it for the conventions of any build tool you use. +# +# Simon Brooke, simon@journeyman.cc, 20260403 + +BASEDIR=$(dirname "$0") +PROJECT=beowulf +BINARY=target/${PROJECT} + +cat ${BASEDIR}/stub.sh \ + target/uberjar/${PROJECT}*-standalone.jar > ${BINARY} \ + && chmod +x ${BINARY} + diff --git a/resources/sh/stub.sh b/resources/sh/stub.sh new file mode 100644 index 0000000..689b831 --- /dev/null +++ b/resources/sh/stub.sh @@ -0,0 +1,8 @@ +#!/bin/sh +MYSELF=`which "$0" 2>/dev/null` +[ $? -gt 0 -a -f "$0" ] && MYSELF="./$0" +java=java +if test -n "$JAVA_HOME"; then + java="$JAVA_HOME/bin/java" +fi +exec "$java" $java_args -jar $MYSELF "$@"