summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/build_al.sh57
-rw-r--r--scripts/build_all.sh19
-rw-r--r--scripts/build_arch.sh68
-rw-r--r--scripts/setup.sh30
4 files changed, 174 insertions, 0 deletions
diff --git a/scripts/build_al.sh b/scripts/build_al.sh
new file mode 100644
index 0000000..750f9e0
--- /dev/null
+++ b/scripts/build_al.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# Собирает Plan9 ассемблер (Xa) или линкер (Xl) на Linux-хосте.
+# Использование: PLAN9SRC=... PLAN9PORT=... build_al.sh 6a | build_al.sh 6l
+set -e
+T="$1"; [ -z "$T" ] && { echo "usage: $0 <напр. 6a|6l|8a|8l>"; exit 1; }
+X="${T:0:1}"; K="${T:1:1}"
+
+: "${PLAN9SRC:?укажи PLAN9SRC}"; : "${PLAN9PORT:?укажи PLAN9PORT}"
+[ -n "$MUSL_ENV" ] && . "$MUSL_ENV"
+export PLAN9="$PLAN9PORT"; export PATH="$PLAN9/bin:$PATH"
+SRC="$PLAN9SRC/sys/src/cmd"
+OUT="${OUT:-$PWD/build}"; B="$OUT/$T"
+
+rm -rf "$B"; mkdir -p "$B"; cd "$B"
+cp "$SRC/$T"/* "$B"/ 2>/dev/null || true
+cp "$SRC/${X}c"/*.h "$B"/ 2>/dev/null || true # X.out.h
+cp "$SRC"/cc/compat "$SRC"/cc/macbody "$SRC"/cc/lexbody "$SRC"/cc/cc.h "$B"/ 2>/dev/null || true
+if [ "$K" = "l" ]; then # линкеру: имена опкодов + общий ELF-вывод
+ cp "$SRC/${X}c"/enam.c "$B"/ 2>/dev/null || true
+ cp "$SRC"/8l/elf.c "$SRC"/8l/elf.h "$B"/ 2>/dev/null || true
+fi
+
+# ---- патчи (те же, что и для компиляторов) ----
+for c in *.c; do grep -qE '#include[ \t]*[<"]/sys/' "$c" 2>/dev/null && { echo " пропуск: $c"; rm -f "$c"; }; done
+sed -i 's|"\.\./[a-zA-Z0-9]*/|"|g' *.c *.h 2>/dev/null || true
+sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' *.c *.h compat macbody lexbody 2>/dev/null || true
+python3 - <<'PY'
+import glob,re
+pat=re.compile(r'\{\s*return\s+sbrk\s*\(\s*(\w+)\s*\)\s*;\s*\}')
+mm='''{
+\tvoid *p;
+\tp = mmap(0, %s, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+\tif(p == MAP_FAILED) return (void*)-1;
+\treturn p;
+}'''
+for f in glob.glob('*')+['compat']:
+ try: s=open(f).read()
+ except: continue
+ if 'sbrk(' in s and 'mmap' not in s:
+ m=pat.search(s)
+ if m:
+ s2=pat.sub(mm%m.group(1), s, count=1)
+ if '#include <sys/mman.h>' not in s2: s2='#include <sys/mman.h>\n'+s2
+ open(f,'w').write(s2); print(" mmap-патч:",f)
+PY
+[ -f a.y ] && { yacc -d a.y; sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' y.tab.c 2>/dev/null || true; }
+
+ok=0; fail=0; errf=""; rm -f *.o
+for f in *.c; do
+ if 9c -fcommon -I. "$f" >/tmp/al_$$ 2>&1; then ok=$((ok+1)); else fail=$((fail+1)); [ -z "$errf" ] && errf="$f" && cp /tmp/al_$$ /tmp/alf_$$; fi
+done
+echo "[$T] компиляция: OK=$ok FAIL=$fail"
+[ "$fail" != 0 ] && { echo "первая ошибка ($errf):"; head -10 /tmp/alf_$$; exit 2; }
+
+if [ "$K" = "l" ]; then EXTRA="-lmach"; else EXTRA=""; fi # линкеру нужен libmach
+9l -o "$T" *.o $EXTRA
+echo "[$T] бинарь: $(ls -la $T | awk '{print $5}') байт -> $B/$T"
diff --git a/scripts/build_all.sh b/scripts/build_all.sh
new file mode 100644
index 0000000..7f058aa
--- /dev/null
+++ b/scripts/build_all.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Собирает ВЕСЬ кросс-кит: C-компиляторы + ассемблеры + линкеры всех арок.
+# Требует экспортированных PLAN9SRC и PLAN9PORT (см. setup.sh).
+set -e
+here="$(cd "$(dirname "$0")" && pwd)"
+: "${PLAN9SRC:?export PLAN9SRC (см. scripts/setup.sh)}"
+: "${PLAN9PORT:?export PLAN9PORT (см. scripts/setup.sh)}"
+export OUT="${OUT:-$PWD/build}"
+
+echo "=== C-компиляторы ==="
+for X in 5 6 8 v q k; do bash "$here/build_arch.sh" $X; done
+echo "=== ассемблеры ==="
+for X in 5 6 8 v q k; do bash "$here/build_al.sh" ${X}a || echo " (${X}a — пропущен/ошибка)"; done
+echo "=== линкеры ==="
+for X in 5 6 8 v q k; do bash "$here/build_al.sh" ${X}l || echo " (${X}l — пропущен/ошибка)"; done
+
+echo
+echo "=== собранные бинари ($OUT) ==="
+find "$OUT" -maxdepth 2 -type f -perm -u+x \( -name '[0-9kvq][cal]' \) -printf '%f %s байт\n' 2>/dev/null | sort
diff --git a/scripts/build_arch.sh b/scripts/build_arch.sh
new file mode 100644
index 0000000..3cdc4fb
--- /dev/null
+++ b/scripts/build_arch.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+# Собирает Plan9 kencc C-компилятор для арки X (5,6,8,v,q,k) на Linux-хосте.
+# Использование: PLAN9SRC=.../plan9foundation PLAN9PORT=.../plan9port build_arch.sh 6
+# Опц.: MUSL_ENV=.../env.sh (активатор musl-тулчейна), OUT=каталог сборки.
+set -e
+X="$1"; [ -z "$X" ] && { echo "usage: $0 <arch: 5|6|8|v|q|k>"; exit 1; }
+A="${X}c"
+
+: "${PLAN9SRC:?укажи PLAN9SRC — дерево исходников plan9 (plan9foundation)}"
+: "${PLAN9PORT:?укажи PLAN9PORT — собранный plan9port (bin/9c,9l,9ar,yacc + lib/)}"
+[ -n "$MUSL_ENV" ] && . "$MUSL_ENV"
+export PLAN9="$PLAN9PORT"; export PATH="$PLAN9/bin:$PATH"
+SRC="$PLAN9SRC/sys/src/cmd"
+OUT="${OUT:-$PWD/build}"
+B="$OUT/$A"
+
+rm -rf "$B"; mkdir -p "$B"; cd "$B"
+# кодоген арки СНАЧАЛА, потом фронтенд cc/ — cc/ авторитетен при совпадении имён
+# (у kc свой устаревший bits.c с Fconv — берём cc/bits.c)
+cp "$SRC/$A"/*.c "$SRC/$A"/*.h "$B"/
+cp "$SRC"/cc/*.c "$SRC"/cc/*.h "$B"/
+cp "$SRC"/cc/compat "$SRC"/cc/macbody "$SRC"/cc/lexbody "$B"/ 2>/dev/null || true
+
+# ---- ПАТЧИ под линукс-хост ----
+# 0) выкинуть плановские рантайм-файлы (тянут /sys/... хедеры, не часть компилятора)
+for c in *.c; do grep -qE '#include[ \t]*[<"]/sys/' "$c" 2>/dev/null && { echo " пропуск рантайм: $c"; rm -f "$c"; }; done
+# 1) плоская раскладка: убрать относительные ../cc/ ../Xc/
+sed -i "s|\"\.\./cc/|\"|g; s|\"\.\./${A}/|\"|g" *.c *.h 2>/dev/null || true
+# 2) round/log2 конфликтуют с musl math.h -> p9round/p9log2
+sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' *.c *.h compat macbody lexbody 2>/dev/null || true
+# 3) Runemask нет в plan9port
+grep -q 'define Runemask' lex.c || sed -i '/#include[ \t]*"y.tab.h"/a #ifndef Runemask\n#define Runemask 0x1FFFFF\n#endif' lex.c
+# 3b) прототип swcmp -> const (musl qsort-компаратор)
+sed -i 's/swcmp(void\*, *void\*)/swcmp(const void*, const void*)/' gc.h *.h 2>/dev/null || true
+# 4) mysbrk: sbrk() на musl отдаёт -1 -> mmap
+python3 - "$B/compat" <<'PY'
+import sys
+p=sys.argv[1]; s=open(p).read()
+old='void*\nmysbrk(ulong size)\n{\n\treturn sbrk(size);\n}'
+new='''#include <sys/mman.h>
+void*
+mysbrk(ulong size)
+{
+\tvoid *p;
+\tp = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+\tif(p == MAP_FAILED) return (void*)-1;
+\treturn p;
+}'''
+if old in s: open(p,'w').write(s.replace(old,new)); print(" mmap-патч: ок")
+else: print(" mmap-патч: паттерн не найден")
+PY
+
+# ---- yacc: cc.y -> y.tab.c / y.tab.h ----
+yacc -d cc.y 2>/dev/null || yacc -d "$SRC/cc/cc.y"
+sed -i -E 's/\bround\b/p9round/g; s/\blog2\b/p9log2/g' y.tab.c 2>/dev/null || true
+
+# ---- компиляция (-fcommon: tentative-глобалы под gcc -fno-common) ----
+ok=0; fail=0; errf=""; rm -f *.o
+for f in *.c; do
+ if 9c -fcommon -I. "$f" >/tmp/ba_$$ 2>&1; then ok=$((ok+1)); else fail=$((fail+1)); [ -z "$errf" ] && errf="$f" && cp /tmp/ba_$$ /tmp/baf_$$; fi
+done
+echo "[$A] компиляция: OK=$ok FAIL=$fail"
+[ "$fail" != 0 ] && { echo "первая ошибка ($errf):"; head -8 /tmp/baf_$$; exit 2; }
+
+# ---- линковка: свой machcap.o -> выкинуть omachcap.o; иначе omachcap и есть machcap ----
+if [ -f machcap.o ]; then LINK=$(ls *.o | grep -v '^omachcap.o$'); else LINK=$(ls *.o); fi
+9l -o "$A" $LINK
+echo "[$A] бинарь: $(ls -la $A | awk '{print $5}') байт -> $B/$A"
diff --git a/scripts/setup.sh b/scripts/setup.sh
new file mode 100644
index 0000000..2d693f0
--- /dev/null
+++ b/scripts/setup.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Готовит зависимости для сборки тулчейна: исходники plan9 + собранный plan9port.
+# Требуется: git, gcc/clang, make, yacc (или plan9port-овский). Каталоги кладутся
+# рядом со скриптом (или в $DEPS). После — экспортни PLAN9SRC/PLAN9PORT (печатает в конце).
+set -e
+DEPS="${DEPS:-$PWD/deps}"
+mkdir -p "$DEPS"; cd "$DEPS"
+
+# 1) дерево исходников plan9 (plan9foundation — тут живут cc/ и Xc/Xa/Xl)
+if [ ! -d plan9foundation ]; then
+ echo ">> клонирую plan9foundation ..."
+ git clone --depth 1 https://github.com/plan9foundation/plan9.git plan9foundation \
+ || git clone --depth 1 https://git.9front.org/plan9front/plan9front plan9foundation
+fi
+
+# 2) plan9port (даёт 9c/9l/9ar/yacc + lib9/libbio/libmach — ими и собираем kencc)
+if [ ! -d plan9port ]; then
+ echo ">> клонирую plan9port ..."
+ git clone --depth 1 https://github.com/9fans/plan9port.git plan9port
+fi
+if [ ! -x plan9port/bin/9c ]; then
+ echo ">> собираю plan9port (может занять пару минут) ..."
+ ( cd plan9port && ./INSTALL -b ) # -b: только собрать, без установки в систему
+fi
+
+echo
+echo "Готово. Экспортни:"
+echo " export PLAN9SRC=$DEPS/plan9foundation"
+echo " export PLAN9PORT=$DEPS/plan9port"
+echo " # если используешь musl-тулчейн: export MUSL_ENV=/path/to/env.sh"