blob: 19904ea77ede332fcae155e5e9e86af5927e9741 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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)"
|