aboutsummaryrefslogtreecommitdiff
path: root/src/tools/zcc
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
commitecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch)
tree70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /src/tools/zcc
a
Diffstat (limited to 'src/tools/zcc')
-rwxr-xr-xsrc/tools/zcc54
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)"