summaryrefslogtreecommitdiff
path: root/scripts/build_arch.sh
blob: 3cdc4fbc1c9c68b4919444bdb74df8ab2655e54f (plain)
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
55
56
57
58
59
60
61
62
63
64
65
66
67
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"