Created
June 7, 2018 23:20
-
-
Save rduplain/23eca22a971e4e3f25d142f4a00aecfd to your computer and use it in GitHub Desktop.
ClojureScript - Native Executables
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## ClojureScript - Native Executables\n", | |
"\n", | |
"#### Objective\n", | |
"\n", | |
"Compile a ClojureScript program to a native executable, which can be run without additional dependencies on the target machine.\n", | |
"\n", | |
"#### Summary\n", | |
"\n", | |
"* The resulting executables are working, distributable, standalone files.\n", | |
"* That said, the executables are quite large (34MB).\n", | |
"* Note that these are \"Hello, world!\" programs and do not test limitations of ClojureScript APIs or any libraries.\n", | |
"* Be ready to build Node.js on various platforms if the prebuilt runtimes do not match your target (though they are probably fine for many use cases).\n", | |
"\n", | |
"#### References\n", | |
"\n", | |
"* https://clojurescript.org/guides/native-executables\n", | |
"* https://github.com/nexe/nexe\n", | |
"* https://github.com/zeit/pkg" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Note that these cells are executing bash shell commands." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Linux 4.4.0-127-generic\n" | |
] | |
} | |
], | |
"source": [ | |
"# Print OS detail.\n", | |
"\n", | |
"uname -a | awk '{ print $1 \" \" $3 }'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"java version \"1.8.0_171\"\n", | |
"Java(TM) SE Runtime Environment (build 1.8.0_171-b11)\n", | |
"Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)\n" | |
] | |
} | |
], | |
"source": [ | |
"# Print Java version.\n", | |
"\n", | |
"java -version" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"node v8.11.2\n", | |
"npm 6.1.0\n", | |
"nexe 2.0.0-rc.29\n", | |
"pkg 4.3.1\n" | |
] | |
} | |
], | |
"source": [ | |
"# Print version of each tool in use.\n", | |
"\n", | |
"for program in node npm nexe pkg; do\n", | |
" echo -n \"$program \"\n", | |
" $program --version | head -1\n", | |
"done" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Download ClojureScript.\n", | |
"\n", | |
"if [ ! -e cljs.jar ]; then\n", | |
" wget -q https://github.com/clojure/clojurescript/releases/download/r1.10.238/cljs.jar\n", | |
"fi" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"cljs.jar: OK\n" | |
] | |
} | |
], | |
"source": [ | |
"# Verify ClojureScript download.\n", | |
"\n", | |
"SHA256=4c1746a365f01fa22069d49354391d3c0e9c233f91b17c5f488a0a7f5e3784ce\n", | |
"echo \"$SHA256 cljs.jar\" > cljs.jar.sha256\n", | |
"if ! sha256sum -c cljs.jar.sha256; then\n", | |
" mv cljs.jar cljs.jar.rej\n", | |
"fi" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"{:major 1, :minor 10, :incremental 0, :qualifier alpha4}\n" | |
] | |
} | |
], | |
"source": [ | |
"# Verify ClojureScript execution by printing its version internally.\n", | |
"\n", | |
"java -cp cljs.jar clojure.main - <<EOF\n", | |
"(println clojure.core/*clojure-version*)\n", | |
"EOF" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Create a simple \"Hello, world!\" program.\n", | |
"\n", | |
"mkdir -p src\n", | |
"cat > src/hello.cljs <<EOF\n", | |
"(ns hello)\n", | |
"(println \"Hello, world!\")\n", | |
"EOF" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Remove build output, for repeat run.\n", | |
"\n", | |
"rm -fr out" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"WARNING: hello is a single segment namespace at line 1 src/hello.cljs\n" | |
] | |
} | |
], | |
"source": [ | |
"# Compile ClojureScript to JavaScript.\n", | |
"\n", | |
"java -cp cljs.jar clojure.main - <<EOF\n", | |
"(require 'cljs.build.api)\n", | |
"(cljs.build.api/build \"src\" {:optimizations :advanced :output-to \"out/main.js\"})\n", | |
"EOF" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"RUN\n" | |
] | |
} | |
], | |
"source": [ | |
"# Compile a binary with nexe.\n", | |
"\n", | |
"# Choose a version (-t) that is prebuilt to speed up compilation.\n", | |
"# Versions: https://github.com/nexe/nexe/releases\n", | |
"#\n", | |
"# Other targets: alpine-x64-8.9.4, mac-x64-8.9.4, windows-x64-8.9.4\n", | |
"\n", | |
"mkdir -p out/nexe\n", | |
"nexe --silent -t linux-x64-8.9.4 -i out/main.js -o out/nexe/hello" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Hello, world!\n" | |
] | |
} | |
], | |
"source": [ | |
"# Run nexe-built binary.\n", | |
"\n", | |
"./out/nexe/hello" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"34M out/nexe/hello\n", | |
"11M out/nexe/hello.bz2\n" | |
] | |
} | |
], | |
"source": [ | |
"# Review nexe-built binary size.\n", | |
"\n", | |
"bzip2 -k out/nexe/hello\n", | |
"ls -lh out/nexe/hello* | awk '{ print $5 \" \" $9 }'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"> [email protected]\n", | |
"'out/pkg/main' -> 'out/pkg/hello'\n" | |
] | |
} | |
], | |
"source": [ | |
"# Compile a binary with pkg.\n", | |
"\n", | |
"# Other targets: node8-macos-x64, node8-win-x64\n", | |
"#\n", | |
"# node8-freebsd-x64?\n", | |
"#\n", | |
"# Issue: There is no freeBSD build for 2.5\n", | |
"# https://github.com/zeit/pkg-fetch/issues/39\n", | |
"\n", | |
"mkdir -p out/pkg\n", | |
"pkg --targets node8-linux-x64 --out-path out/pkg out/main.js\n", | |
"mv -v out/pkg/main out/pkg/hello" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"34M out/pkg/hello\n", | |
"11M out/pkg/hello.bz2\n" | |
] | |
} | |
], | |
"source": [ | |
"# Review pkg-built binary size.\n", | |
"\n", | |
"bzip2 -k out/pkg/hello\n", | |
"ls -lh out/pkg/hello* | awk '{ print $5 \" \" $9 }'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Hello, world!\n" | |
] | |
} | |
], | |
"source": [ | |
"# Run pkg-built binary.\n", | |
"\n", | |
"./out/pkg/hello" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Bash", | |
"language": "bash", | |
"name": "bash" | |
}, | |
"language_info": { | |
"codemirror_mode": "shell", | |
"file_extension": ".sh", | |
"mimetype": "text/x-sh", | |
"name": "bash" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Comparison of nexe & pkg.