--- /dev/null
+#!/bin/bash
+
+progname=$(basename $0)
+
+usage() {
+ cat >&2 <<EOF
+Usage: $progname [options] <outdir> <depends>...
+
+options:
+ -t, --exclude-tests exclude test/ directories from ccan modules
+ -c, --exclude-configurator exclude configurator. config.h must be
+ supplied by another method (eg, autotools)
+EOF
+}
+
+# parse options, setting the following flags
+exclude_tests=
+exclude_configurator=
+
+opts=$(getopt -o tc --long exclude-tests,exclude-configurator -n $progname \
+ -- "$@")
+
+if [ $? != 0 ]
+then
+ usage
+ exit 1
+fi
+
+eval set -- "$opts"
+
+while :
+do
+ case "$1" in
+ -t|--exclude-tests)
+ exclude_tests=1
+ shift
+ ;;
+ -c|--exclude-configurator)
+ exclude_configurator=1
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ echo "Internal error!">&2
+ exit 1
+ ;;
+ esac
+done
+
+# we need at least two non-option arguments: outdir and a list of ccan
+# modules
+if [ $# -lt 2 ]
+then
+ usage
+ exit 1
+fi
+
+srcdir=$(dirname $0)/../
+outdir="$1"
+shift
+modules="$@"
+
+if [ -e "$outdir" ]
+then
+ echo "Output directory '$outdir' already exists" >&2
+ exit 1
+fi
+
+tmpdir="$(mktemp -d)"
+# sanity check, we don't want to be overwriting stuff in arbitrary dirs
+[ $? -eq 0 -a -d "${tmpdir}" ] || exit 1
+
+# We'll need the ccan_depends tool, but also a clean source tree. Build
+# tools/ccan_depends, and store it in $tmpdir for later use
+
+echo "Building ccan_depends"
+ccan_depends="$tmpdir/ccan_depends"
+make -s -C "$srcdir" tools/ccan_depends
+[ $? -eq 0 ] || exit 1
+cp "$srcdir/tools/ccan_depends" "$ccan_depends"
+
+echo "Cleaning source tree"
+make -s -C "$srcdir" clean
+[ $? -eq 0 ] || exit 1
+
+# clean up on error
+trap 'rm -rf $tmpdir' EXIT
+
+# generate list of directories to copy
+for module in $modules
+do
+ # ccan_depends takes a directory name
+ module_dir="$srcdir/ccan/$module"
+
+ # we need the module itself...
+ echo "ccan/$module"
+
+ # .. plus dependencies
+ "$ccan_depends" "$module_dir"
+
+ if [ $? -ne 0 ]
+ then
+ echo "Invalid ccan module '$module'?" >&2
+ exit 1
+ fi
+done |
+sort -u |
+while read dir
+do
+ module_srcdir="$srcdir/$dir"
+ module_destdir="$tmpdir/$dir"
+ echo "Adding $dir"
+ mkdir -p "$(dirname "$module_destdir")"
+ cp -a "$module_srcdir" "$module_destdir"
+ if [ -n "$exclude_tests" ]
+ then
+ rm -rf "$module_destdir/test"
+ fi
+done
+
+# we're done with the dependency-tracking, remove the tool from our
+# temporary directory
+rm "$ccan_depends"
+
+echo "Adding licenses"
+license_dir="$tmpdir/licenses"
+mkdir "$license_dir"
+
+find "$tmpdir" -type l -name LICENSE |
+while read license
+do
+ license_link=$(readlink "$license")
+ licence_file=$(basename "$license_link")
+ license_src="$srcdir/licenses/$licence_file"
+ license_dest="$license_dir/$license_file"
+ cp "$license_src" "$license_dest"
+done
+
+# add ccan Makefile
+echo "Adding build infrastructure"
+cp "$srcdir/Makefile-ccan" "$tmpdir/"
+
+# add top-level Makefile
+top_makefile="$tmpdir/Makefile"
+cat > "$top_makefile" << EOF
+all: libccan.a
+
+include Makefile-ccan
+EOF
+
+# optionally add configurator, and relevant parts to top-level Makefile
+if [ -z "$exclude_configurator" ]
+then
+ echo "Adding configurator"
+ mkdir -p "$tmpdir/tools/configurator"
+ cp -a "$srcdir/tools/configurator" "$tmpdir/tools/"
+
+ cat >> "$top_makefile" <<EOF
+tools/configurator/configurator: tools/configurator/configurator.c
+
+config.h: tools/configurator/configurator Makefile Makefile-ccan
+ tools/configurator/configurator \$(CC) \$(CCAN_CFLAGS) > \$@ \\
+ || rm -f \$@
+
+objs = \$(patsubst %.c, %.o, \$(wildcard ccan/*/*.c))
+\$(objs): config.h
+
+EOF
+fi
+
+mv "$tmpdir" "$outdir"
+echo "Done. ccan source tree built in $outdir"
+
+trap - EXIT