mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-07-12 18:19:42 -07:00
archr: symlink PortMaster compat libs into the default linker path
PortMaster runtimes failed to launch: love_11.5's love.aarch64 died with "error while loading shared libraries: libtheoradec.so.1: cannot open shared object file" (caught live over SSH while a port was launched). Root cause: ArchR keeps the ~50 PortMaster compat libraries (older Debian-11-era SONAMEs: libtheoradec.so.1, libavcodec.so.58, libwebp.so.6, libx264.so.160, etc.) under /usr/lib/compat to stay out of the base system, and the image ships NO ld.so.cache. glibc's dynamic linker therefore only searches the hardcoded /usr/lib + /lib plus LD_LIBRARY_PATH, so /usr/lib/compat is invisible to anything that does not explicitly prepend it. control.txt does set LD_LIBRARY_PATH=/usr/lib/compat, but the per-runtime invocation overwrites it, dropping compat for binaries like love.aarch64. docs/PortMaster_CFW.md is explicit on the fix: "add these older .so symlinks alongside [the newer versions]" and "Keep [libtheoradec] at standard versions." So we expose the compat SONAMEs in the default path. New archr-compat-symlinks script + archr-compat-libs.service oneshot (ordered Before=archr-autostart so it runs before any port launches): walks /usr/lib/compat (and /usr/lib32/compat) and symlinks each SONAME into /usr/lib, but ONLY when the base system does not already provide that exact name, so real libraries (libogg.so.0, libvorbis.so.0, ...) are never shadowed. Idempotent via the `[ -e ]` guard; the writable ext4 rootfs keeps the links so later boots are no-ops. Verified live on the R36S: 46 compat-only SONAMEs linked into /usr/lib, libtheoradec.so.1 now resolvable, libogg.so.0 left untouched (still the real /usr/lib/libogg.so.0.8.6).
This commit is contained in:
@@ -153,6 +153,12 @@ EOF
|
||||
### Take a backup of the system configuration on shutdown
|
||||
enable_service save-sysconfig.service
|
||||
|
||||
### Expose PortMaster compat libs (/usr/lib/compat) in the default
|
||||
### linker path. No ld.so.cache ships, so love_11.5 et al. fail on
|
||||
### libtheoradec.so.1 unless it is symlinked into /usr/lib (see
|
||||
### docs/PortMaster_CFW.md and the archr-compat-symlinks script).
|
||||
enable_service archr-compat-libs.service
|
||||
|
||||
### System locale. glibc/package.mk only generates en_US.UTF-8; without
|
||||
### this file LANG stays empty and every shell falls back to POSIX,
|
||||
### which breaks UTF-8 input, pacman messages and emulator menus.
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# archr-compat-symlinks: expose the PortMaster compat libraries
|
||||
# (/usr/lib/compat/*.so*, the older Debian-11-era SONAMEs that ports and
|
||||
# their runtimes link against) in the default linker search path.
|
||||
#
|
||||
# ArchR keeps these libs under /usr/lib/compat to stay out of the base
|
||||
# system, but the image ships no ld.so.cache: the dynamic linker only
|
||||
# searches the hardcoded /usr/lib + /lib plus LD_LIBRARY_PATH, so
|
||||
# /usr/lib/compat is invisible to anything that does not explicitly
|
||||
# prepend it. PortMaster runtimes such as love_11.5 link
|
||||
# libtheoradec.so.1 as a normal system library and die with
|
||||
# "cannot open shared object file: libtheoradec.so.1" when it lives only
|
||||
# under compat. docs/PortMaster_CFW.md is explicit: "add these older .so
|
||||
# symlinks alongside [the newer versions]" and "Keep [libtheoradec] at
|
||||
# standard versions."
|
||||
#
|
||||
# We therefore symlink each compat lib into /usr/lib, but ONLY when the
|
||||
# base system does not already provide that exact SONAME, so we never
|
||||
# shadow a real system library (e.g. libogg.so.0, libvorbis.so.0).
|
||||
#
|
||||
# Idempotent: the `[ -e ]` guard skips anything already present, so it is
|
||||
# safe to run every boot. The rootfs is writable ext4, so the links
|
||||
# persist and later boots are no-ops.
|
||||
|
||||
link_dir() {
|
||||
local compat="$1" libdir="$2" n=0 f base
|
||||
[ -d "${compat}" ] || return 0
|
||||
for f in "${compat}"/*.so*; do
|
||||
[ -e "${f}" ] || continue
|
||||
base="${f##*/}"
|
||||
if [ ! -e "${libdir}/${base}" ]; then
|
||||
ln -sf "compat/${base}" "${libdir}/${base}" && n=$((n + 1))
|
||||
fi
|
||||
done
|
||||
echo "${n}"
|
||||
}
|
||||
|
||||
created=$(link_dir /usr/lib/compat /usr/lib)
|
||||
# armhf / 32-bit ports use the lib32 tree when present.
|
||||
created32=$(link_dir /usr/lib32/compat /usr/lib32)
|
||||
|
||||
echo "archr-compat-symlinks: linked ${created:-0} (lib) + ${created32:-0} (lib32) compat SONAMEs into the default path"
|
||||
exit 0
|
||||
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=ArchR PortMaster compat library symlinks
|
||||
# Ports are launched from EmulationStation, which archr-autostart.service
|
||||
# brings up; ordering before it guarantees the compat SONAMEs are linked
|
||||
# into /usr/lib before any port (or its runtime) can dlopen them.
|
||||
Before=archr-autostart.service
|
||||
After=systemd-tmpfiles-setup.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/archr-compat-symlinks
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=archr.target
|
||||
Reference in New Issue
Block a user