diff options
| author | claude <[email protected]> | 2026-07-12 01:19:32 +0000 |
|---|---|---|
| committer | claude <[email protected]> | 2026-07-12 01:19:32 +0000 |
| commit | a4dce7f4d920e492d38c32ad3e42efdcfef3b3f1 (patch) | |
| tree | b0a0ad513792f5c0ddc524d67f6ab89e2044c642 /scripts/build_arch.sh | |
| download | plan9-kencc-linux-a4dce7f4d920e492d38c32ad3e42efdcfef3b3f1.tar.gz plan9-kencc-linux-a4dce7f4d920e492d38c32ad3e42efdcfef3b3f1.zip | |
🌭 plan9-kencc-linux: кросс-тулчейн Plan9 (cc/as/ld) + EFI-болванка
- build_arch.sh / build_al.sh: сборка kencc-компиляторов, ассемблеров,
линкеров всех арок (5/6/8/v/q/k) на Linux-хосте через plan9port.
- патчи под musl/gcc: sbrk->mmap, round/log2->p9*, Runemask, swcmp const,
-fcommon, machcap/omachcap, /sys рантайм-файлы. Подробно в PATCHES.md.
- bin/: готовые 8c 6c 5c vc qc kc + 6a 6l (Linux/musl x86_64).
- efi/: болваночный bootx64.efi (PE32+) тем же тулчейном (6a+6c+6l+dd),
референс — 9legacy nboot/efi; ESP-образ через mkesp.py.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Diffstat (limited to 'scripts/build_arch.sh')
| -rw-r--r-- | scripts/build_arch.sh | 68 |
1 files changed, 68 insertions, 0 deletions
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" |
