diff options
Diffstat (limited to 'ship/build')
-rwxr-xr-x | ship/build | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/ship/build b/ship/build new file mode 100755 index 00000000..916953cc --- /dev/null +++ b/ship/build @@ -0,0 +1,93 @@ +#! /bin/sh +set -euf + +## SYNOPSIS +# build compile SRCFILE DSTFILE +# build deps SRCFILE +build() { + case "$1" in + compile) build_compile "$2" "$3";; + deps) build_deps "$2";; + *) echo "build: $1: bad command" >&2; return 23;; + esac +} + +## build directives +build_info_directive='#@info' +build_include_directive='#@include \([0-9A-Za-z]\+\)' + +input_parser="\ +s:^ *\([0-9]\+\) "$build_info_directive"$:build_info \1: +s:^ *\([0-9]\+\) "$build_include_directive"$:build_include \1 \2: +t +s:^ *\([0-9]\+\) .*:echo \1p:" + +## usage: build_include LINENO LIBNAME +build_include() { cat<<EOF +$1a\\ +# begin $2 +$1r$(build_resolve $2) +$1a\\ +# end $2 +EOF +} + +## usage: build_info LINENO +build_info() { cat<<EOF +$1a\\ +# this file was generated by //ship/build\\ +# date: $(date -u --rfc-3339=s)\\ +# version: $(git rev-parse HEAD) +EOF +} + +## usage: build_compile SRCFILE DSTFILE +build_compile() { + srcfile="$(cat "$1")" + + while needs_compilation "$srcfile"; do + script="$(make_sedscript_maker_shellscript "$srcfile")" + srcfile="$(echo "$srcfile" | sed -n "$script")" + done + + echo "$srcfile" > "$2" + chmod +x "$2" +} + +## usage: needs_compilation SHELLSCRIPT +# Returns true if SRCFILE contains compilation directives. +needs_compilation() { + echo "$1" | + grep -q "^\\($build_include_directive\\|$build_info_directive\\)$" +} + +## usage: make_sedscript_maker_shellscript SRCFILE +# Print a shellscript that creates a sedscript that resolves all the build +# directives in SRCFILE. +make_sedscript_maker_shellscript() { + sedscript_generator="$(echo "$1" | nl -b a -s ' ' | sed "$input_parser")" + sedscript="$(eval "$sedscript_generator")" + echo "$sedscript" +} + +## usage: build_deps SRCFILE +build_deps() { + for libname in $(sed -n 's:^'"$build_include_directive"'$:\1:p' "$1"); do + build_resolve "$libname" + done +} + +## usage: build_resolve LIBNAME +build_resolve() { + echo "$BUILD_PATH" | tr : \\n | + xargs -I: printf '%s/%s\n' : "$1" | + xargs -I: ls -d : 2>/dev/null | + head -n 1 | + grep . || + { + echo "build resolve: $1: library not found" >&2 + return 23 + } +} + +build "$@" |