diff options
Diffstat (limited to 'src/tools/zcc')
| -rwxr-xr-x | src/tools/zcc | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/tools/zcc b/src/tools/zcc new file mode 100755 index 0000000..19904ea --- /dev/null +++ b/src/tools/zcc @@ -0,0 +1,54 @@ +#!/bin/bash +# zcc: compiles a ZC (ZygoteC) program into a static binary. the binary holds +# the runtime, the program and a memory map sized to them, and needs nothing +# from the system but the kernel (linux x86-64 and any host with a static +# libc). the program reads and writes through the same syscalls as zy(1). +# +# src/tools/zcc [-o OUT] [-k] FILE.zc +# +# -o OUT the binary to write (default: FILE without .zc) +# -k keep the build directory and print where it is +# CC the C compiler (default cc). CFLAGS adds to the default -O2 +# +# the build is three steps: automap sizes the map to the program and writes the +# genome (the compiled program image) for it; the micro core and its linux port +# are compiled against that map; and the link is static. make run PROG= builds +# the same image without the static link. +set -e +here="$(cd "$(dirname "$0")/../.." && pwd)" +CC=${CC:-cc} +out=""; keep=0 +while [ $# -gt 0 ]; do + case "$1" in + -o) [ $# -ge 2 ] || { echo "zcc: -o needs a name" >&2; exit 2; }; out="$2"; shift 2 ;; + -k) keep=1; shift ;; + -h|--help) sed -n '2,15p' "$0"; exit 0 ;; + -*) echo "zcc: unknown option $1" >&2; exit 2 ;; + *) break ;; + esac +done +[ $# -eq 1 ] || { echo "usage: src/tools/zcc [-o OUT] [-k] FILE.zc" >&2; exit 2; } +src="$1" +[ -f "$src" ] || { echo "zcc: no such file: $src" >&2; exit 1; } +case "$src" in *.zc) ;; *) echo "zcc: the source must end in .zc" >&2; exit 2 ;; esac +[ -n "$out" ] || { out="${src%.zc}"; out="$(basename "$out")"; } +case "$src" in /*) abs="$src" ;; *) abs="$PWD/$src" ;; esac + +work="$(mktemp -d "${TMPDIR:-/tmp}/zcc.XXXXXX")" +cleanup() { [ "$keep" = 1 ] && echo "zcc: build kept in $work" >&2 || rm -rf "$work"; } +trap cleanup EXIT + +# the map and the genome for this program only +( cd "$here" && bash src/tools/automap.sh run "$work/run" src/runtime/run.zc "$abs" ) >/dev/null +cp "$here/src/micro/micro.c" "$here/src/micro/micro_port.h" "$here/src/micro/port_linux.c" \ + "$here/src/core/fops.h" "$here/src/core/bops.h" "$here/src/core/stack.h" "$work/run/" + +# static where the toolchain allows it; a plain link otherwise, with a note +static=-static +if ! printf 'int main(void){return 0;}\n' | $CC -x c -static -o "$work/probe" - >/dev/null 2>&1; then + static="" + echo "zcc: this toolchain cannot link -static; the binary is dynamic" >&2 +fi +$CC -O2 -w -fwrapv ${CFLAGS:-} $static "$work/run/micro.c" "$work/run/port_linux.c" \ + -I"$work/run" -o "$out" +echo "zcc: wrote $out ($(wc -c < "$out" | tr -d ' ') bytes)" |
