🔒 Repository is read-only – file editing is disabled.

PaganLinux/tmp-patch-pagbuild-perf.py main

114 linii Raw ← Powrót
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
#!/usr/bin/env python3
"""Zmiany wydajnosciowe w pagbuild:
  A) naprawa .pc w rootfs: rutynowo tylko pliki z biezacego pakietu
     (zamiast dwoch pelnych przelotow po ~870 tys. plikow)
  B) unpack_archive: dekompresory wielowatkowe z fallbackiem
"""
import sys

P = "/tmp/pagbuild-src/pagbuild"
APPLY = "--apply" in sys.argv

text = open(P, newline="", encoding="utf-8").read()
orig = text

# ── B) unpack_archive ──────────────────────────────────────────────────────
OLD_B = """        *.tar.gz|*.tgz)   tar -xzf "$f" -C "$dest" ;;
        *.tar.bz2|*.tbz2) tar -xjf "$f" -C "$dest" ;;
        *.tar.xz|*.txz)   tar -xJf "$f" -C "$dest" ;;
        *.tar)            tar -xf "$f" -C "$dest" ;;
"""

NEW_B = """        # bzip2/gzip są jednowątkowe – przy dużych archiwach (np. linux-firmware
        # 875 MB) dekompresja zajmuje minuty na JEDNYM rdzeniu z sześciu. Jeśli
        # jest dekompresor wielowątkowy, używamy go; fallback do klasycznego
        # tara sprawia, że brak narzędzia niczego nie psuje.
        *.tar.gz|*.tgz)
            if command -v pigz >/dev/null 2>&1; then
                tar -I pigz -xf "$f" -C "$dest" || tar -xzf "$f" -C "$dest"
            else
                tar -xzf "$f" -C "$dest"
            fi ;;
        *.tar.bz2|*.tbz2)
            if command -v lbzip2 >/dev/null 2>&1; then
                tar -I lbzip2 -xf "$f" -C "$dest" || tar -xjf "$f" -C "$dest"
            elif command -v pbzip2 >/dev/null 2>&1; then
                tar -I pbzip2 -xf "$f" -C "$dest" || tar -xjf "$f" -C "$dest"
            else
                tar -xjf "$f" -C "$dest"
            fi ;;
        *.tar.xz|*.txz)
            if command -v xz >/dev/null 2>&1; then
                tar -I "xz -T0" -xf "$f" -C "$dest" || tar -xJf "$f" -C "$dest"
            else
                tar -xJf "$f" -C "$dest"
            fi ;;
        *.tar)            tar -xf "$f" -C "$dest" ;;
"""

# ── A) naprawa .pc ─────────────────────────────────────────────────────────
OLD_A = """if [[ -d "$ROOTFS/usr" ]]; then
    find "$ROOTFS/usr" -name '*.pc' \\
        -exec sed -i "s#^prefix=.*#prefix=/usr#; s#^exec_prefix=.*#exec_prefix=/usr#" {} + 2>/dev/null || true
    # libdir/includedir: usuń tylko zakodowaną ścieżkę rootfs (np. libdir=/mnt/.../usr/lib)
    # – poprawny wpis (np. /usr/lib64) zostaje nietknięty.
    if [[ "$ROOTFS" != "/" ]]; then
        _pc_rf=$(printf '%s' "$ROOTFS" | sed 's/[\\/&]/\\\\&/g')
        find "$ROOTFS/usr" -name '*.pc' \\
            -exec sed -i "s#^\\(libdir\\|includedir\\)=${_pc_rf}#\\1=#" {} + 2>/dev/null || true
    fi
fi"""

NEW_A = """# WYDAJNOŚĆ: pełny find po $ROOTFS/usr to ~870 tys. plików (~1-2 min na
# przejście, a były DWA przejścia) PRZY KAŻDYM buildzie – nawet gdy pakiet to
# jeden plik firmware bez ani jednego .pc. Rutynowo poprawiamy więc wyłącznie
# pliki .pc z WŁAŚNIE zbudowanego pakietu (lista z data.tar.xz). Niezmiennik
# jest ten sam: każdy pakiet przechodzi tu raz, przy swoim buildzie, więc każdy
# jego .pc zostaje naprawiony. Pełny przelot robimy TYLKO raz na rootfs – po
# jego utworzeniu lub odtworzeniu (znacznik żyje w rootfs, więc nowy rootfs =
# brak znacznika = pełna naprawa).
_pc_marker="$ROOTFS/var/lib/pagbuild/.pc-prefix-fixed"
if [[ -d "$ROOTFS/usr" ]]; then
    _pc_rf=$(printf '%s' "$ROOTFS" | sed 's/[\\/&]/\\\\&/g')
    if [[ ! -f "$_pc_marker" ]]; then
        echo "🔧 pkg-config: jednorazowa naprawa calego rootfsu"
        find "$ROOTFS/usr" -name '*.pc' \\
            -exec sed -i "s#^prefix=.*#prefix=/usr#; s#^exec_prefix=.*#exec_prefix=/usr#" {} + 2>/dev/null || true
        find "$ROOTFS/usr" -name '*.pc' \\
            -exec sed -i "s#^\\(libdir\\|includedir\\)=${_pc_rf}#\\1=#" {} + 2>/dev/null || true
        mkdir -p "$ROOTFS/var/lib/pagbuild" 2>/dev/null || true
        : > "$_pc_marker" 2>/dev/null || true
    fi
    _pc_n=0
    if [[ -f "$TEMP_PKG/data.tar.xz" ]]; then
        while IFS= read -r _pc_rel; do
            _pc_rel="${_pc_rel#./}"
            case "$_pc_rel" in *.pc) ;; *) continue ;; esac
            _pc_f="$ROOTFS/$_pc_rel"
            [[ -f "$_pc_f" ]] || continue
            sed -i "s#^prefix=.*#prefix=/usr#; s#^exec_prefix=.*#exec_prefix=/usr#" "$_pc_f" 2>/dev/null || true
            if [[ "$ROOTFS" != "/" ]]; then
                sed -i "s#^\\(libdir\\|includedir\\)=${_pc_rf}#\\1=#" "$_pc_f" 2>/dev/null || true
            fi
            _pc_n=$((_pc_n + 1))
        done < <(tar -tJf "$TEMP_PKG/data.tar.xz" 2>/dev/null || true)
    fi
    if [[ $_pc_n -gt 0 ]]; then
        echo "🔧 pkg-config: poprawiono $_pc_n plik(ow) .pc z tego pakietu"
    fi
fi"""

for name, old, new in (("B (unpack_archive)", OLD_B, NEW_B), ("A (naprawa .pc)", OLD_A, NEW_A)):
    n = text.count(old)
    print(f"{name}: dopasowan dokladnych = {n}")
    if n != 1:
        print(f"   !!! PRZERWANO – oczekiwano 1 dopasowania")
        sys.exit(1)
    text = text.replace(old, new, 1)

print("\nzmiana linii:", len(text.splitlines()) - len(orig.splitlines()))
if APPLY:
    open(P, "w", newline="", encoding="utf-8").write(text)
    print("ZAPISANO", P)
else:
    print("DRY-RUN")