#!/bin/bash # ============================================================================= # fix-xml-parser.sh – naprawa XML::Parser (perl 5.44) w bieżącym rootfs Pagan # ============================================================================= # Problem: plasma-desktop pada z "You must have XML::Parser installed to run # /mnt/pagan/usr/bin/intltool-merge". Przyczyna: # • /bin/sh w rootfs jest martwym symlinkiem (-> bash, a bash jest w /usr/bin), # przez co chrootowy build XML::Parser z CPAN kończył się: "env: 'sh': No such file" # • dla perla 5.44 XML::Parser nie został zbudowany (jest tylko stary 5.42 z repo # = ABI mismatch). # # Skrypt: naprawia /bin/sh, buduje XML::Parser w chrocie i weryfikuje intltool-merge. # # URUCHOMIENIE: # sudo ./fix-xml-parser.sh # a potem wznowij build: # sudo ./build-pagan.sh # ============================================================================= set -euo pipefail R="${PAGAN_ROOT:-/mnt/pagan}" [ "$(id -u)" = "0" ] || { echo "❌ Uruchom jako root: sudo ./fix-xml-parser.sh"; exit 1; } # 1) Napraw /bin/sh – wskaż wprost na /usr/bin/bash echo "=== 1. Naprawa /bin/sh ===" ln -sfv /usr/bin/bash "$R/bin/sh" # 1b) libcrypt.so.2 – target perl zbudowany na hoście linkuje libcrypt.so.2 (SONAME 2), # a libxcrypt w rootfs ma SONAME 1 (libcrypt.so.1.1.0). Wersje symboli XCRYPT_* # identyczne → symlink wyrównuje obie strony (perl + narzędzia shadow). echo "=== 1b. Kompatybilność libcrypt (libcrypt.so.2) ===" [[ -e "$R/usr/lib/libcrypt.so.2" ]] || \ ln -sfv libcrypt.so.1.1.0 "$R/usr/lib/libcrypt.so.2" # 2) Wirtualne FS dla chroot (best-effort – przy wznowieniu build i tak je zamontuje) echo "=== 2. Montowanie wirtualnych FS ===" # /dev bywa nieobecny (init_build go nie tworzył, a bind po przerwaniu builda # znika) → bez /dev/null MakeMaker perla nie działa ("Unable to find a perl 5", # make: Permission denied / 127). Zapewniamy /dev z urządzeniami. if [[ -e "$R/dev/null" ]]; then echo " ✓ /dev już gotowy (jest /dev/null)" else grep -q " $R/dev " /proc/mounts 2>/dev/null && umount -l "$R/dev" 2>/dev/null || true mkdir -p "$R/dev" if ! mount --bind /dev "$R/dev" 2>/dev/null; then mount -t devtmpfs devtmpfs "$R/dev" 2>/dev/null || true fi [[ -e "$R/dev/null" ]] && echo " ✓ /dev zamontowany (jest /dev/null)" \ || echo " ⚠ /dev bez /dev/null – chroot może zawodzić" fi mkdir -p "$R/dev/pts" mount --bind /dev/pts "$R/dev/pts" 2>/dev/null || true mount -t proc proc "$R/proc" 2>/dev/null || true mount -t sysfs sysfs "$R/sys" 2>/dev/null || true mount -t tmpfs tmpfs "$R/run" 2>/dev/null || true # 2c) NATYWNY binutils (as/ld/ar) – build_final_system go nie buduje, a gcc w # chrocie nie ma asemblera ("gcc: fatal error: cannot execute 'as'"). Budujemy # na hoście z DESTDIR do rootfs (glibc hosta == target == 2.44 → bez ryzyka ABI). echo "=== 2c. Build natywnego binutils (as/ld) ===" if [ -x "$R/usr/bin/as" ] && [ -x "$R/usr/bin/ld" ]; then echo " ✓ binutils już w target" else BU_ARCH="$R/sources/binutils-2.47.tar.xz" [ -f "$BU_ARCH" ] || wget -q --timeout=120 -O "$BU_ARCH" \ "https://ftp.gnu.org/gnu/binutils/binutils-2.47.tar.xz" rm -rf "$R/sources/build-binutils" && mkdir -p "$R/sources/build-binutils" tar -xf "$BU_ARCH" -C "$R/sources/build-binutils" --strip-components=1 ( cd "$R/sources/build-binutils" export PATH="/usr/bin:/bin" export CFLAGS="-std=gnu17 -O2 -Wno-error=implicit-function-declaration -Wno-error=int-conversion -Wno-error=return-type" export LDFLAGS="-L$R/usr/lib -Wl,-rpath-link,$R/usr/lib" mkdir -p build && cd build ../configure --prefix=/usr --sysconfdir=/etc \ --enable-libctf --disable-werror --enable-ld=default \ --enable-plugins --enable-relro --enable-threads make -j"$(nproc)" make tooldir=/usr install DESTDIR="$R" ) > "$R/sources/binutils-build.log" 2>&1 # LFS: usuń statyczne liby binutils (mają zaszyte ścieżki builda) rm -f "$R/usr/lib"/libbfd.a "$R/usr/lib"/libbfd.la "$R/usr/lib"/libctf.a \ "$R/usr/lib"/libctf.la "$R/usr/lib"/libctf-nobfd.a "$R/usr/lib"/libctf-nobfd.la \ "$R/usr/lib"/libopcodes.a "$R/usr/lib"/libopcodes.la 2>/dev/null || true rm -rf "$R/sources/build-binutils" if [ -x "$R/usr/bin/as" ] && [ -x "$R/usr/bin/ld" ]; then echo " ✓ binutils zainstalowany: $("$R/usr/bin/as" --version 2>/dev/null | head -1)" else echo " ❌ binutils build nieudany (log: $R/sources/binutils-build.log)" exit 1 fi fi # 3) Build XML::Parser (perl 5.44) w chrocie – czyste env, bash -c echo "=== 3. Build XML::Parser (perl 5.44) ===" XP="$R/sources/XML-Parser-2.44.tar.gz" if [ ! -f "$XP" ]; then echo "Pobieranie XML-Parser-2.44..." wget -q --timeout=60 -O "$XP" \ "https://cpan.metacpan.org/authors/id/T/TO/TODDR/XML-Parser-2.44.tar.gz" fi rm -rf "$R/tmp/xml-parser-build" && mkdir -p "$R/tmp/xml-parser-build" tar -xzf "$XP" -C "$R/tmp/xml-parser-build" --strip-components=1 chroot "$R" env -i PATH=/usr/bin:/bin HOME=/root \ bash -c "cd /tmp/xml-parser-build && PERL_MM_USE_DEFAULT=1 perl Makefile.PL && make && make install" 2>&1 | tail -20 rm -rf "$R/tmp/xml-parser-build" # 4) Weryfikacja: target perl na HOŚCIE ładuje XML::Parser (tak działa intltool-merge) echo "=== 4. Weryfikacja ===" _pver="" for _d in "$R"/usr/lib/perl5/5.*; do [[ -d "$_d" ]] && _pver="$(basename "$_d")"; done _parch="" for _d in "$R/usr/lib/perl5/$_pver"/*/; do [[ -d "$_d/CORE" ]] && _parch="$(basename "$_d")" && break; done echo "perl: $_pver, arch: $_parch" if LD_LIBRARY_PATH="$R/usr/lib/perl5/$_pver/$_parch/CORE:/usr/lib:$R/usr/lib" \ PERL5LIB="$R/usr/lib/perl5/$_pver:$R/usr/lib/perl5/site_perl/$_pver:$R/usr/lib/perl5/$_pver/$_parch:$R/usr/lib/perl5/site_perl/$_pver/$_parch" \ "$R/usr/bin/perl" -MXML::Parser -e 'print "XML::Parser ", $XML::Parser::VERSION, " OK\n"' 2>&1; then echo else echo "❌ XML::Parser NIE działa dla perl $_pver – sprawdź log powyżej" exit 1 fi # 5) Ostateczny test: intltool-merge (dokładnie tak woła go CMake/plasma-desktop) echo "=== 5. Test intltool-merge (na hoście) ===" if LD_LIBRARY_PATH="$R/usr/lib/perl5/$_pver/$_parch/CORE:/usr/lib:$R/usr/lib" \ PERL5LIB="$R/usr/lib/perl5/$_pver:$R/usr/lib/perl5/site_perl/$_pver:$R/usr/lib/perl5/$_pver/$_parch:$R/usr/lib/perl5/site_perl/$_pver/$_parch" \ "$R/usr/bin/intltool-merge" --version; then echo echo "✅ intltool-merge działa – plasma-desktop (KAccounts) przejdzie dalej" else echo "❌ intltool-merge nadal nie działa – sprawdź powyżej" exit 1 fi echo echo "=== Gotowe. Wznów build: sudo ./build-pagan.sh ==="