#!/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")