diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/build_al.sh | 57 | ||||
| -rw-r--r-- | scripts/build_all.sh | 19 | ||||
| -rw-r--r-- | scripts/build_arch.sh | 68 | ||||
| -rw-r--r-- | scripts/setup.sh | 30 |
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" |
