@@ -1,56 +1,165 @@
1#!/usr/bin/env sh
1#!/usr/bin/env sh
3−if [ "$#" -lt 2 ]; then
3+fail() {
4− cat <<EOF
4+ echo "Try '$0 --help'." >&2
6−Usage: $0 TARGET EXECUTABLE
8+build() {
10+ nix build "$@" --out-link "$linkdir/result"
11+ readlink "$linkdir/result"
8−Create a single-file bundle from the nixpkgs attribute "TARGET".
14+check_arg() {
9−EXECUTABLE should be relative to the TARGET's output path.
15+ if [ $# -le 1 ]
17+ echo "error: flag '$1' requires an argument" >&2
11−For example:
22+nix_file=`dirname $0`/default.nix
33+ -f|--file|-I|--include)
43+ echo "error: flag '$1' requires two arguments" >&2
61+Usage: $0 <FLAGS>... [<TARGET>] <targets>...
13−$ $0 hello /bin/hello
63+Summary: Similar to nix build, but creates a single-file bundle.
66+ --arg <NAME> <EXPR> argument to be passed to Nix functions
67+ --argstr <NAME> <STRING> string-valued argument to be passed to Nix functions
68+ -f, --file <FILE> evaluate FILE rather than the default
69+ -I, --include <PATH> add a path to the list of locations used to look up <...> file names
70+ --bin <BINARY> the binary to bundle, relative to TARGET's output path
74+ To bundle GNU Hello from NixOS 19.03:
75+ $ $0 -f channel:nixos-19.03 hello --bin /bin/hello
77+ To bundle the executable from within a project that has a default.nix for build:
78+ $ $0 --bin /bin/name-of-the-executable
87+ echo "error: unrecognized flag '$1'" >&2
19− exit 1
103+# Check if all required arguments were passed
107+ echo "error: flag '--bin' is required" >&2
22−nix_file=`dirname $0`/default.nix
111+# Create tmp directory for the links produced by `nix build`
114+build_flags+=("--out-link")
115+build_flags+=("$linkdir/result")
24−target="$1"
119+target_path=
25−shift
120+extra_target_paths=
27−extraTargets=
122+for target in "${targets[@]}"
28−if [ "$#" -gt 1 ]; then
123+do
29− while [ "$#" -gt 1 ]; do
124+ nix build "${build_flags[@]}" "$target" || exit $?
30− extraTargets="$extraTargets $1"
125+ if [ -z "$target_path" ]
127+ target_path="$(readlink "$linkdir/result")"
129+ extra_target_paths="$extra_target_paths $(readlink "$linkdir/result")"
133+if [ -z "$target_path" ]
135+ nix build "${build_flags[@]}" || exit $?
136+ target_path="$(readlink "$linkdir/result")"
35−exec="$1"
139+# Determine bootstrap function -- This seems like a total hack!
38bootstrap=nix-bootstrap
141bootstrap=nix-bootstrap
39−if [ "$target" = "nix-bundle" ] || [ "$target" = "nixStable" ] || [ "$target" = "nixUnstable" ] || [ "$target" = "nix" ]; then
142+if [ "${targets[0]}" = "nix-bundle" ] || [ "${targets[0]}" = "nixStable" ] || [ "${targets[0]}" = "nixUnstable" ] || [ "${targets[0]}" = "nix" ]; then
40 bootstrap=nix-bootstrap-nix
143 bootstrap=nix-bootstrap-nix
41−elif ! [ -z "$extraTargets" ]; then
144+elif ! [ -z "$extra_target_paths" ]; then
42 bootstrap=nix-bootstrap-path
145 bootstrap=nix-bootstrap-path
148+# Run bootstrap function
45−expr="with import <nixpkgs> {}; with import $nix_file {}; $bootstrap { target = $target; extraTargets = [ $extraTargets ]; run = \"$exec\"; }"
150+expr="(with import $nix_file {}; $bootstrap { target = $target_path; extraTargets = [$extra_target_paths ]; run = \"$bin\"; })"
47out=$(nix-store --no-gc-warning -r $(nix-instantiate --no-gc-warning -E "$expr"))
154out=$(nix-store --no-gc-warning -r $(nix-instantiate --no-gc-warning -E "$expr"))
156+# Copy the created bundle to the working directory
49if [ -z "$out" ]; then
158if [ -z "$out" ]; then
50 >&2 echo "$0 failed. Exiting."
159 >&2 echo "$0 failed. Exiting."
52elif [ -t 1 ]; then
161elif [ -t 1 ]; then
53− filename=$(basename $exec)
162+ filename=$(basename $bin)
54 echo "Nix bundle created at $filename."
163 echo "Nix bundle created at $filename."
55 cp -f $out $filename
164 cp -f $out $filename