SPS · log · files · refs · tags · releases · people · languages · GitHub · commit
3b4ba7c
mkiso: ship Mesa SPIRV, Xwayland, and gcc cc1 libraries
Parents
Stat
bin/mkiso | 232 +++++++++++++++++++++++++++++++++++++++++++++++-- bin/setup | 18 ++++ lib/mkiso/live-plasma | 13 ++- lib/mkiso/live-rc | 6 +- lib/mkiso/plasma-bins | 2 + lib/mkiso/plasma-trees | 1 + tests/test_mkiso.sh | 20 +++++ tests/test_setup.sh | 2 + 8 files changed, 285 insertions(+), 9 deletions(-)
Diff
diff --git a/bin/mkiso b/bin/mkiso
index ac7fedd..4297af5 100755
--- a/bin/mkiso
+++ b/bin/mkiso
@@ -285,6 +285,107 @@ mkiso_copy_libs()
done
}
+# close_libs only walks bin/sbin. cc1 (libmpc/libisl) and Mesa DRI
+# (libSPIRV-Tools) are dlopened helpers, so a seeded disc can have gcc
+# and still fail "C compiler cannot create executables", and Plasma can
+# have /dev/dri/card0 and still report "No suitable DRM devices".
+mkiso_copy_so_deps()
+{
+ mkiso_so=$1
+ [ -e "$mkiso_so" ] || [ -L "$mkiso_so" ] || return 0
+ case $mkiso_so in
+ *.a|*-rust*|*nvidia*) return 0 ;;
+ esac
+ mkiso_copy_path "$mkiso_so"
+ mkiso_copy_libs "$mkiso_so"
+}
+
+mkiso_copy_gcc_deps()
+{
+ command -v find >/dev/null 2>&1 || return 0
+ printf '%s: resolving gcc cc1 libraries\n' "$sps_prog" >&2
+ for mkiso_d in /usr/libexec/gcc /usr/lib64/gcc /usr/lib/gcc
+ do
+ [ -d "$mkiso_d" ] || continue
+ find "$mkiso_d" -type f \( \
+ -name cc1 -o -name cc1plus -o -name collect2 -o \
+ -name lto-wrapper -o -name lto1 -o \
+ -name liblto_plugin.so -o -name 'liblto_plugin.so.*' \
+ \) -print 2>/dev/null |
+ while IFS= read -r mkiso_elf || [ -n "$mkiso_elf" ]; do
+ [ -n "$mkiso_elf" ] || continue
+ mkiso_copy_so_deps "$mkiso_elf"
+ done
+ done
+}
+
+mkiso_copy_mesa_deps()
+{
+ printf '%s: resolving Mesa DRI/GBM libraries\n' "$sps_prog" >&2
+ for mkiso_d in /usr/lib64/dri /usr/lib/dri /usr/lib64/gbm /usr/lib/gbm
+ do
+ [ -d "$mkiso_d" ] || continue
+ find "$mkiso_d" -type f -name '*.so*' -print 2>/dev/null |
+ while IFS= read -r mkiso_so || [ -n "$mkiso_so" ]; do
+ [ -n "$mkiso_so" ] || continue
+ mkiso_copy_so_deps "$mkiso_so"
+ done
+ done
+ for mkiso_so in /usr/lib64/libgallium*.so /usr/lib64/libgallium*.so.* \
+ /usr/lib64/libEGL_mesa.so /usr/lib64/libEGL_mesa.so.* \
+ /usr/lib64/libGLX_mesa.so /usr/lib64/libGLX_mesa.so.* \
+ /usr/lib64/libgbm.so /usr/lib64/libgbm.so.* \
+ /usr/lib64/libglapi.so /usr/lib64/libglapi.so.* \
+ /usr/lib64/libSPIRV-Tools.so \
+ /usr/lib64/qt6/plugins/platforms/libqwayland.so \
+ /usr/lib64/qt6/plugins/platforms/libqxcb.so \
+ /usr/lib64/qt6/plugins/wayland-shell-integration/libxdg-shell.so \
+ /usr/bin/kwin_wayland /usr/bin/kwin_wayland_wrapper \
+ /usr/bin/Xwayland
+ do
+ [ -e "$mkiso_so" ] || [ -L "$mkiso_so" ] || continue
+ mkiso_copy_so_deps "$mkiso_so"
+ done
+ # Live uses nouveau. A dangling nvidia GBM backend makes libgbm
+ # probe a proprietary stack that is not on the disc.
+ rm -f "$mkiso_live/usr/lib64/gbm/nvidia-drm_gbm.so" \
+ "$mkiso_live/usr/lib/gbm/nvidia-drm_gbm.so"
+}
+
+# ldd a host ELF and require each resolved library to exist in the live
+# root. Used so we refuse to ship gcc without libmpc or Mesa without SPIRV.
+mkiso_verify_elf_in_live()
+{
+ mkiso_host=$1
+ [ -e "$mkiso_host" ] || return 0
+ command -v ldd >/dev/null 2>&1 || return 0
+ mkiso_ldd=$(ldd "$mkiso_host" 2>/dev/null) || return 0
+ mkiso_oldifs=$IFS
+ IFS='
+'
+ for mkiso_line in $mkiso_ldd
+ do
+ IFS=$mkiso_oldifs
+ case $mkiso_line in
+ *linux-vdso*|*'not a dynamic'*|*'not found'*) continue ;;
+ esac
+ mkiso_lib=${mkiso_line#*=> }
+ mkiso_lib=${mkiso_lib%% (*}
+ mkiso_lib=${mkiso_lib## }
+ case $mkiso_lib in
+ /*)
+ if [ ! -e "$mkiso_live$mkiso_lib" ] &&
+ [ ! -L "$mkiso_live$mkiso_lib" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" \
+ "live image missing $mkiso_lib (needed by $mkiso_host)"
+ fi
+ ;;
+ esac
+ done
+ IFS=$mkiso_oldifs
+}
+
# Copy a host command by name. live-bins lists common paths, but util-linux
# puts lsblk in /bin on this builder and /usr/bin on others. Silent skips
# of a missing path are why live setup printed "no disks found".
@@ -449,14 +550,117 @@ mkiso_verify_live()
fi
fi
- # chroot needs privileges; skip it in unprivileged tests.
+ # chroot needs privileges; skip it when the kernel refuses the
+ # syscall (user namespaces, unprivileged root in tests).
if [ "$(id -u 2>/dev/null)" = 0 ]; then
- if ! "$mkiso_live/bin/busybox" chroot "$mkiso_live" /bin/sh -c ':' \
- >/dev/null 2>&1; then
- sps_die "$SPS_EX_BUILD" \
- "live /bin/sh cannot execute inside the image"
+ mkiso_chroot_st=0
+ mkiso_chroot_err=$("$mkiso_live/bin/busybox" chroot \
+ "$mkiso_live" /bin/sh -c ':' 2>&1) || mkiso_chroot_st=$?
+ if [ "$mkiso_chroot_st" -ne 0 ]; then
+ case $mkiso_chroot_err in
+ *'Operation not permitted'*|*'not permitted'*) ;;
+ *)
+ sps_die "$SPS_EX_BUILD" \
+ "live /bin/sh cannot execute inside the image"
+ ;;
+ esac
fi
fi
+
+ mkiso_verify_compiler
+ mkiso_verify_plasma
+}
+
+# Seeded images ship gcc. The driver DT_NEEDs only libc; cc1 needs
+# libmpc/libisl. Refuse to ship a disc whose first autoconf check dies.
+mkiso_verify_compiler()
+{
+ if [ ! -e "$mkiso_live/usr/bin/gcc" ] &&
+ [ ! -L "$mkiso_live/usr/bin/gcc" ]
+ then
+ return 0
+ fi
+ if [ ! -e "$mkiso_live/usr/lib64/crt1.o" ] &&
+ [ ! -e "$mkiso_live/lib64/crt1.o" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" \
+ "seeded live gcc is missing crt1.o"
+ fi
+ if [ ! -e "$mkiso_live/usr/lib64/libc.so" ] &&
+ [ ! -L "$mkiso_live/usr/lib64/libc.so" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" \
+ "seeded live gcc is missing the libc.so linker script"
+ fi
+ if [ ! -e "$mkiso_live/usr/bin/as" ] &&
+ [ ! -L "$mkiso_live/usr/bin/as" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" "seeded live gcc is missing as"
+ fi
+ if [ ! -e "$mkiso_live/usr/bin/ld" ] &&
+ [ ! -L "$mkiso_live/usr/bin/ld" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" "seeded live gcc is missing ld"
+ fi
+ mkiso_cc1=
+ for mkiso_d in "$mkiso_live/usr/libexec/gcc" "$mkiso_live/usr/lib64/gcc"
+ do
+ [ -d "$mkiso_d" ] || continue
+ mkiso_cc1=$(find "$mkiso_d" -name cc1 -type f -print 2>/dev/null |
+ head -1) || mkiso_cc1=
+ [ -n "$mkiso_cc1" ] && break
+ done
+ [ -n "$mkiso_cc1" ] ||
+ sps_die "$SPS_EX_PACKAGE" "seeded live gcc is missing cc1"
+ mkiso_verify_elf_in_live "${mkiso_cc1#"$mkiso_live"}"
+ mkiso_verify_elf_in_live /usr/bin/as
+ if [ -e /usr/bin/ld.bfd ]; then
+ mkiso_verify_elf_in_live /usr/bin/ld.bfd
+ elif [ -e /usr/bin/ld ]; then
+ mkiso_verify_elf_in_live /usr/bin/ld
+ fi
+}
+
+mkiso_verify_plasma()
+{
+ [ "$mkiso_session" = plasma ] || return 0
+ mkiso_miss=
+ for mkiso_need in usr/bin/kwin_wayland usr/bin/kwin_wayland_wrapper \
+ usr/bin/startplasma-wayland usr/lib64/gbm/dri_gbm.so \
+ usr/lib64/libxcb-cursor.so.0
+ do
+ if [ ! -e "$mkiso_live/$mkiso_need" ] &&
+ [ ! -L "$mkiso_live/$mkiso_need" ]
+ then
+ mkiso_miss="$mkiso_miss $mkiso_need"
+ fi
+ done
+ if ! ls "$mkiso_live"/usr/lib64/libgallium*.so* >/dev/null 2>&1
+ then
+ mkiso_miss="$mkiso_miss libgallium"
+ fi
+ if [ -e /usr/lib64/libSPIRV-Tools.so ] ||
+ [ -L /usr/lib64/libSPIRV-Tools.so ]
+ then
+ if ! ls "$mkiso_live"/usr/lib64/libSPIRV-Tools.so* >/dev/null 2>&1
+ then
+ mkiso_miss="$mkiso_miss libSPIRV-Tools.so"
+ fi
+ fi
+ if [ -e /usr/bin/Xwayland ] &&
+ [ ! -e "$mkiso_live/usr/bin/Xwayland" ] &&
+ [ ! -L "$mkiso_live/usr/bin/Xwayland" ]
+ then
+ mkiso_miss="$mkiso_miss usr/bin/Xwayland"
+ fi
+ [ -z "$mkiso_miss" ] ||
+ sps_die "$SPS_EX_PACKAGE" "plasma image missing:$mkiso_miss"
+ for mkiso_g in /usr/lib64/libgallium*.so
+ do
+ [ -e "$mkiso_g" ] || continue
+ mkiso_verify_elf_in_live "$mkiso_g"
+ break
+ done
}
# BusyBox --install -s writes absolute symlinks to the host path. Relative
@@ -507,7 +711,9 @@ mkiso_copy_plasma()
/usr/lib64/libEGL_mesa.so* /usr/lib64/libGLX_mesa.so* \
/usr/lib64/libgallium*.so* /usr/lib64/dri/libdril_dri.so \
/usr/lib64/libLLVM.so /usr/lib64/libLLVM.so.[0-9]* \
- /usr/lib64/libOpenGL.so* /usr/lib64/libxcb-cursor.so*
+ /usr/lib64/libOpenGL.so* /usr/lib64/libxcb-cursor.so* \
+ /usr/lib64/libgbm.so* /usr/lib64/libglapi.so* \
+ /usr/lib64/libSPIRV-Tools.so
do
for mkiso_so in $mkiso_pat; do
[ -e "$mkiso_so" ] || continue
@@ -552,6 +758,7 @@ EOF
mkdir -p "$mkiso_live/etc/systemd/system"
ln -sf /dev/null "$mkiso_live/etc/systemd/system/dbus.service"
ln -sf /dev/null "$mkiso_live/etc/systemd/system/dbus.socket"
+ mkiso_copy_mesa_deps
}
# PID 1 must be an ELF. A shell script that execs getty/setsid is what
@@ -829,11 +1036,22 @@ if [ "$mkiso_copy_seed" -eq 1 ] && [ -f "$mkiso_libdir/seed-bins" ]; then
/usr/lib64/libthread_db.so /usr/lib64/libgcc_s.so \
/usr/lib64/libstdc++.so /usr/lib64/libc_nonshared.a \
/usr/lib64/libpthread_nonshared.a \
- /usr/lib64/libmvec_nonshared.a
+ /usr/lib64/libmvec_nonshared.a \
+ /usr/lib64/rcrt1.o /usr/lib64/grcrt1.o \
+ /lib64/libc.so.6 /usr/lib64/libc.so.6 \
+ /lib64/libm.so.6 /usr/lib64/libm.so.6 \
+ /lib64/libmvec.so.1 /usr/lib64/libmvec.so.1 \
+ /lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2
do
[ -e "$mkiso_crt" ] || [ -L "$mkiso_crt" ] || continue
mkiso_copy_path "$mkiso_crt"
done
+ # cc1 DT_NEEDs libmpc/libisl. ldd of the gcc driver does not.
+ mkiso_copy_gcc_deps
+ for mkiso_cmd in gcc g++ cc c++ as ld ld.bfd
+ do
+ mkiso_copy_host_cmd "$mkiso_cmd" || :
+ done
mkiso_copy_path /usr/lib64/python3.12
mkiso_copy_path /usr/share/terminfo
mkiso_copy_path /usr/share/zoneinfo
diff --git a/bin/setup b/bin/setup
index 53e0431..dcf25c8 100755
--- a/bin/setup
+++ b/bin/setup
@@ -1715,6 +1715,24 @@ $(sort -u "$setup_pkg_file")
EOF
printf '%s: installing packages:%s\n' "$sps_prog" "$setup_pkgs" >&2
+# Fail before the first autoconf package if the live gcc cannot link.
+# Missing libmpc (cc1) or crt1.o shows up as "C compiler cannot create
+# executables" two screens later otherwise.
+if command -v gcc >/dev/null 2>&1; then
+ setup_cc_dir=${SPS_BUILD:-$setup_root/var/tmp/sps}
+ mkdir -p "$setup_cc_dir" ||
+ setup_fail "$SPS_EX_PERMISSION" "cannot create $setup_cc_dir"
+ setup_cc_log=$setup_cc_dir/sps-cc-probe.log
+ setup_cc_out=$setup_cc_dir/sps-cc-probe
+ if ! printf '%s\n' 'int main(void){return 0;}' |
+ gcc -x c - -o "$setup_cc_out" >"$setup_cc_log" 2>&1
+ then
+ printf '%s: live gcc cannot create executables\n' "$sps_prog" >&2
+ cat "$setup_cc_log" >&2
+ setup_fail "$SPS_EX_BUILD" "live gcc cannot create executables"
+ fi
+ rm -f "$setup_cc_out"
+fi
# sget treats requested names as explicit world roots.
# shellcheck disable=SC2086
sget install $setup_pkgs ||
diff --git a/lib/mkiso/live-plasma b/lib/mkiso/live-plasma
index 50531b1..0cd960c 100644
--- a/lib/mkiso/live-plasma
+++ b/lib/mkiso/live-plasma
@@ -18,14 +18,17 @@ export FONTCONFIG_PATH=/etc/fonts
export QT_PLUGIN_PATH=/usr/lib64/qt6/plugins
export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib64/qt6/plugins/platforms
export QML2_IMPORT_PATH=/usr/lib64/qt6/qml
+export LIBGL_DRIVERS_PATH=/usr/lib64/dri:/usr/lib/dri
+export GBM_BACKENDS_PATH=/usr/lib64/gbm:/usr/lib/gbm
# KWin is the compositor. QT_QPA_PLATFORM=wayland makes Qt try to
# connect to a display that does not exist yet, so kwin_wayland dies
# with "Failed to create wl_display" and plasmashell follows.
unset QT_QPA_PLATFORM
mkdir -p "$XDG_RUNTIME_DIR" /run/dbus /var/lib/dbus /etc/dbus-1 \
- /root/.config/kdedefaults
+ /root/.config/kdedefaults /tmp/.X11-unix /tmp/.ICE-unix
chmod 700 "$XDG_RUNTIME_DIR"
+chmod 1777 /tmp /tmp/.X11-unix /tmp/.ICE-unix 2>/dev/null || :
# startplasma reads this before KSplash. A missing file logs
# QIODevice::readLineInto ... kdedefaults/package.
if [ ! -s /root/.config/kdedefaults/package ]; then
@@ -114,6 +117,14 @@ if [ ! -e /dev/dri/card0 ] && [ ! -e /dev/dri/card1 ]; then
printf '%s\n' "SPS: use tty2 (Ctrl-Alt-F2) for a shell."
ls /dev/dri 2>/dev/null || :
fi
+if [ ! -e /usr/lib64/gbm/dri_gbm.so ] && [ ! -e /usr/lib/gbm/dri_gbm.so ]
+then
+ printf '%s\n' "SPS: Mesa GBM backend dri_gbm.so is missing; KWin cannot use DRM."
+fi
+if ! ls /usr/lib64/libSPIRV-Tools.so* >/dev/null 2>&1
+then
+ printf '%s\n' "SPS: libSPIRV-Tools.so is missing; Mesa GBM will fail to open DRI."
+fi
if command -v startplasma-wayland >/dev/null 2>&1; then
# Give the user a console they can see if Wayland dies.
diff --git a/lib/mkiso/live-rc b/lib/mkiso/live-rc
index 10883dc..5890128 100644
--- a/lib/mkiso/live-rc
+++ b/lib/mkiso/live-rc
@@ -21,7 +21,11 @@ mount -t devtmpfs devtmpfs /dev 2>/dev/null || :
mkdir -p /dev/pts /dev/shm
mount -t devpts devpts /dev/pts 2>/dev/null || :
mount -t tmpfs tmpfs /run 2>/dev/null || :
-mount -t tmpfs tmpfs /tmp 2>/dev/null || :
+mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /tmp 2>/dev/null || \
+ mount -t tmpfs tmpfs /tmp 2>/dev/null || :
+chmod 1777 /tmp 2>/dev/null || :
+mkdir -p /tmp/.X11-unix /tmp/.ICE-unix
+chmod 1777 /tmp/.X11-unix /tmp/.ICE-unix 2>/dev/null || :
mkdir -p /run/dbus
if [ ! -e /var/run ]; then
mkdir -p /var
diff --git a/lib/mkiso/plasma-bins b/lib/mkiso/plasma-bins
index 542e19e..7f301c5 100644
--- a/lib/mkiso/plasma-bins
+++ b/lib/mkiso/plasma-bins
@@ -34,6 +34,7 @@
/usr/bin/dbus-send
/usr/libexec/dbus-daemon-launch-helper
/usr/bin/seatd
+/usr/bin/Xwayland
/usr/bin/Xorg
/usr/bin/xauth
/usr/bin/xrdb
@@ -55,5 +56,6 @@
/usr/libexec/plasma-startup-sound
/usr/libexec/xdg-desktop-portal
/usr/libexec/xdg-desktop-portal-kde
+/usr/libexec/xdg-document-portal
/usr/libexec/xdg-permission-store
diff --git a/lib/mkiso/plasma-trees b/lib/mkiso/plasma-trees
index e29d82b..951bd6d 100644
--- a/lib/mkiso/plasma-trees
+++ b/lib/mkiso/plasma-trees
@@ -14,6 +14,7 @@
/usr/share/applications
/usr/share/desktop-directories
/usr/share/icons
+/usr/share/color-schemes
/usr/share/mime
/usr/share/knotifications6
/usr/share/kglobalaccel
diff --git a/tests/test_mkiso.sh b/tests/test_mkiso.sh
index 6541f44..64cdc8e 100755
--- a/tests/test_mkiso.sh
+++ b/tests/test_mkiso.sh
@@ -167,6 +167,26 @@ grep -q 'copying glibc startfiles' "$mkiso" ||
fail 'seeded ISO must copy glibc crt1.o for gcc'
grep -q crt1.o "$mkiso" ||
fail 'mkiso must copy crt1.o with the seed compiler'
+grep -q 'resolving gcc cc1 libraries' "$mkiso" ||
+ fail 'seeded ISO must ldd cc1 so libmpc/libisl land on the disc'
+grep -q 'resolving Mesa DRI/GBM libraries' "$mkiso" ||
+ fail 'plasma ISO must ldd Mesa DRI/GBM so libSPIRV-Tools lands on the disc'
+grep -q libSPIRV-Tools "$mkiso" ||
+ fail 'plasma ISO must copy libSPIRV-Tools for Mesa GBM'
+grep -q nvidia-drm_gbm "$mkiso" ||
+ fail 'plasma ISO must drop the nvidia GBM backend'
+grep -q Xwayland "$project_dir/lib/mkiso/plasma-bins" ||
+ fail 'plasma-bins must include Xwayland'
+grep -q xdg-document-portal "$project_dir/lib/mkiso/plasma-bins" ||
+ fail 'plasma-bins must include xdg-document-portal'
+grep -q /usr/share/color-schemes "$project_dir/lib/mkiso/plasma-trees" ||
+ fail 'plasma-trees must include Breeze color schemes'
+grep -q '/tmp/.X11-unix' "$layout/etc/sps/live-rc" ||
+ fail 'live-rc must create /tmp/.X11-unix for Xwayland'
+grep -q '/tmp/.X11-unix' "$layout/etc/sps/live-plasma" ||
+ fail 'live-plasma must create /tmp/.X11-unix for Xwayland'
+grep -q 'live gcc cannot create executables' "$project_dir/bin/setup" ||
+ fail 'setup must probe live gcc before the first package build'
grep -q 'copying disk tools for setup' "$mkiso" ||
fail 'mkiso must copy partition tools by command name'
grep -q grub-install "$mkiso" ||
diff --git a/tests/test_setup.sh b/tests/test_setup.sh
index 56c9a67..617c963 100755
--- a/tests/test_setup.sh
+++ b/tests/test_setup.sh
@@ -263,6 +263,8 @@ contains "$(cat "$tmp/err")" '--format yes'
grep -q 'remount,rw,exec' "$project_dir/lib/setup/partition.sh" ||
fail 'setup must remount the target exec so autoconf can run conftest'
+grep -q 'live gcc cannot create executables' "$setup" ||
+ fail 'setup must probe live gcc before sget install'
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --init systemd \
--disable qol-cli --disable power --disable firmware)