SPS · log · files · refs · tags · releases · people · languages · GitHub · commit
e2b9369
mkiso: seed a working Meson instead of a setuptools stub.
Parents
Stat
PACKAGE-MAINTAINER.md | 5 +- bin/mkiso | 150 +++++++++++++++++++++++++++++++++++++++++++++++++- bin/setup | 14 +++++ man/mkiso.1 | 9 ++- tests/test_mkiso.sh | 18 ++++++ tests/test_setup.sh | 2 + 6 files changed, 194 insertions(+), 4 deletions(-)
Diff
diff --git a/PACKAGE-MAINTAINER.md b/PACKAGE-MAINTAINER.md
index 4bbd677..5cccaaa 100644
--- a/PACKAGE-MAINTAINER.md
+++ b/PACKAGE-MAINTAINER.md
@@ -154,11 +154,14 @@ install DESTDIR="$PKG" cmake --install build
```
```text
-configure meson setup build --prefix=/usr --buildtype=release
+configure meson setup build --prefix=/usr --libdir=lib64 --buildtype=release
build meson compile -C build -j "$MAKEJOBS"
install DESTDIR="$PKG" meson install -C build
```
+Meson feature options take `enabled`, `disabled`, or `auto`, not `true`/`false`.
+Passing `-Dpython=false` to libxml2 2.15 is a meson error, not a compiler error.
+
Use the upstream project's intended build system and supported options. Build
commands run on the host; `mkpkg` is not a chroot and cannot prevent a bad
command from modifying paths outside `$PKG`.
diff --git a/bin/mkiso b/bin/mkiso
index 17c28ae..8729df6 100755
--- a/bin/mkiso
+++ b/bin/mkiso
@@ -24,7 +24,10 @@
# this host does not ship, so the image is built with grub-mkimage and
# xorriso.
#
-# Seed toolchain (--no-seed to skip): gcc, headers, cmake, ninja, python.
+# Seed toolchain (--no-seed to skip): gcc, headers, cmake, ninja, python
+# stdlib, Meson (mesonbuild), Perl library. Host /usr/bin/meson is a
+# setuptools wrapper; mesonbuild lives under site-packages, not next
+# to the Python stdlib, so copying python3.12 is not enough.
# Pass --core/--extra so the live image can build packages without cloning
# the recipe repos. --with-go copies the official Go tree; gccgo on PATH
# is too old for the Go recipes in extra.
@@ -324,6 +327,121 @@ mkiso_copy_gcc_deps()
done
}
+# Python's stdlib is under lib64; Meson is a pure-Python package under
+# /usr/lib/pythonX.Y/site-packages. Copying the interpreter and
+# lib64/pythonX.Y is not enough: that tree's site-packages is PyQt and
+# friends, not mesonbuild. The setuptools /usr/bin/meson then dies with
+# ModuleNotFoundError, which looks like a Python error at the first
+# meson recipe (often libxml2).
+mkiso_python_version()
+{
+ python3 -c 'import sys; print("%d.%d" % sys.version_info[:2])' \
+ 2>/dev/null || printf '%s\n' 3.12
+}
+
+mkiso_copy_python_stdlib()
+{
+ mkiso_pyver=$(mkiso_python_version)
+ for mkiso_pylib in /usr/lib64/python$mkiso_pyver \
+ /usr/lib/python$mkiso_pyver
+ do
+ [ -d "$mkiso_pylib" ] || continue
+ printf '%s: copying Python %s stdlib from %s\n' \
+ "$sps_prog" "$mkiso_pyver" "$mkiso_pylib" >&2
+ for mkiso_pyent in "$mkiso_pylib"/*; do
+ [ -e "$mkiso_pyent" ] || continue
+ mkiso_pybase=${mkiso_pyent##*/}
+ case $mkiso_pybase in
+ test|idlelib|ensurepip|turtledemo|site-packages)
+ continue
+ ;;
+ esac
+ mkiso_copy_path "$mkiso_pyent"
+ done
+ if [ -d "$mkiso_pylib/lib-dynload" ]; then
+ for mkiso_pyso in "$mkiso_pylib/lib-dynload"/*.so \
+ "$mkiso_pylib/lib-dynload"/*.so.*
+ do
+ [ -e "$mkiso_pyso" ] || continue
+ mkiso_copy_libs "$mkiso_pyso"
+ done
+ fi
+ done
+}
+
+# Install Meson as meson.py next to mesonbuild so it does not need
+# importlib.metadata or a setuptools egg-info (the host /usr/bin/meson
+# does). Same layout the meson recipe ships.
+mkiso_install_meson()
+{
+ mkiso_mod=
+ mkiso_mod=$(python3 -c 'import mesonbuild, os; print(os.path.dirname(mesonbuild.__file__))' \
+ 2>/dev/null) || mkiso_mod=
+ if [ -z "$mkiso_mod" ] || [ ! -d "$mkiso_mod" ]; then
+ for mkiso_cand in \
+ /usr/lib/python*/site-packages/mesonbuild \
+ /usr/lib64/python*/site-packages/mesonbuild
+ do
+ [ -d "$mkiso_cand" ] || continue
+ mkiso_mod=$mkiso_cand
+ break
+ done
+ fi
+ [ -n "$mkiso_mod" ] && [ -d "$mkiso_mod" ] || return 0
+ printf '%s: copying Meson from %s\n' "$sps_prog" "$mkiso_mod" >&2
+ mkdir -p "$mkiso_live/usr/share/meson" "$mkiso_live/usr/bin"
+ rm -rf "$mkiso_live/usr/share/meson/mesonbuild"
+ cp -a --reflink=auto "$mkiso_mod" \
+ "$mkiso_live/usr/share/meson/mesonbuild" 2>/dev/null ||
+ cp -a "$mkiso_mod" "$mkiso_live/usr/share/meson/mesonbuild" 2>/dev/null ||
+ cp -R "$mkiso_mod" "$mkiso_live/usr/share/meson/mesonbuild"
+ cat >"$mkiso_live/usr/share/meson/meson.py" <<'EOF'
+#!/usr/bin/python3
+import sys
+from pathlib import Path
+meson_exe = Path(sys.argv[0]).resolve()
+if (meson_exe.parent / 'mesonbuild').is_dir():
+ sys.path.insert(0, str(meson_exe.parent))
+from mesonbuild import mesonmain
+if __name__ == '__main__':
+ sys.exit(mesonmain.main())
+EOF
+ chmod 755 "$mkiso_live/usr/share/meson/meson.py"
+ rm -f "$mkiso_live/usr/bin/meson"
+ ln -s ../share/meson/meson.py "$mkiso_live/usr/bin/meson"
+}
+
+mkiso_copy_cmake_data()
+{
+ printf '%s: copying CMake modules\n' "$sps_prog" >&2
+ for mkiso_cmake in /usr/share/cmake /usr/share/cmake-*
+ do
+ [ -e "$mkiso_cmake" ] || continue
+ mkiso_copy_path "$mkiso_cmake"
+ done
+}
+
+mkiso_copy_perl_lib()
+{
+ printf '%s: copying Perl library\n' "$sps_prog" >&2
+ for mkiso_perl in /usr/lib64/perl5 /usr/lib/perl5 \
+ /usr/share/perl5 /usr/share/perl
+ do
+ [ -e "$mkiso_perl" ] || continue
+ mkiso_copy_path "$mkiso_perl"
+ done
+}
+
+# Host /usr/include is copied so gcc can compile against libc. Optional
+# third-party headers on that tree make configure detect libraries the
+# disc does not ship (alsa-utils vs samplerate.h) or compile a recipe
+# against a different upstream version (host libxml2 vs the tarball).
+mkiso_prune_seed_headers()
+{
+ rm -f "$mkiso_live/usr/include/samplerate.h"
+ rm -rf "$mkiso_live/usr/include/libxml2"
+}
+
mkiso_copy_mesa_deps()
{
printf '%s: resolving Mesa DRI/GBM libraries\n' "$sps_prog" >&2
@@ -755,6 +873,30 @@ mkiso_verify_compiler()
elif [ -e /usr/bin/ld ]; then
mkiso_verify_elf_in_live /usr/bin/ld
fi
+ # Meson is a Python program. The host driver is a setuptools
+ # wrapper; without mesonbuild and encodings, the first meson
+ # recipe dies with a traceback (libxml2's -Dpython= option is a
+ # second, separate failure).
+ if [ -e /usr/bin/meson ] || [ -L /usr/bin/meson ]; then
+ if [ ! -e "$mkiso_live/usr/share/meson/mesonbuild/mesonmain.py" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" \
+ "seeded meson is missing mesonbuild"
+ fi
+ if [ ! -e "$mkiso_live/usr/bin/meson" ] &&
+ [ ! -L "$mkiso_live/usr/bin/meson" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" \
+ "seeded meson wrapper is missing"
+ fi
+ mkiso_pyver=$(mkiso_python_version)
+ if [ ! -e "$mkiso_live/usr/lib64/python$mkiso_pyver/encodings/__init__.py" ] &&
+ [ ! -e "$mkiso_live/usr/lib/python$mkiso_pyver/encodings/__init__.py" ]
+ then
+ sps_die "$SPS_EX_PACKAGE" \
+ "seeded python is missing the encodings stdlib module"
+ fi
+ fi
}
mkiso_verify_plasma()
@@ -1486,6 +1628,7 @@ if [ "$mkiso_copy_seed" -eq 1 ] && [ -f "$mkiso_libdir/seed-bins" ]; then
mkiso_copy_path /usr/lib64/gcc
mkiso_copy_path /usr/lib/gcc
mkiso_copy_path /usr/include
+ mkiso_prune_seed_headers
# gcc and ld without glibc startfiles fail the first autoconf check
# with "C compiler cannot create executables". Runtime libc.so.6 is
# not enough; the linker needs crt1.o and the libc.so script.
@@ -1530,7 +1673,10 @@ if [ "$mkiso_copy_seed" -eq 1 ] && [ -f "$mkiso_libdir/seed-bins" ]; then
do
mkiso_copy_host_cmd "$mkiso_cmd" || :
done
- mkiso_copy_path /usr/lib64/python3.12
+ mkiso_copy_python_stdlib
+ mkiso_install_meson
+ mkiso_copy_cmake_data
+ mkiso_copy_perl_lib
mkiso_copy_path /usr/share/terminfo
mkiso_copy_path /usr/share/zoneinfo
mkiso_copy_path /etc/ssl
diff --git a/bin/setup b/bin/setup
index b920e2a..c18e038 100755
--- a/bin/setup
+++ b/bin/setup
@@ -1999,6 +1999,20 @@ if command -v gcc >/dev/null 2>&1; then
fi
rm -f "$setup_cc_out"
fi
+# Meson recipes (libxml2 is the first for many desktop graphs) fail with
+# a Python traceback when mesonbuild is missing, or with a meson error
+# about option "python" when the recipe passes -Dpython=false.
+if command -v meson >/dev/null 2>&1; then
+ setup_meson_dir=${SPS_BUILD:-$setup_root/var/tmp/sps}
+ mkdir -p "$setup_meson_dir" ||
+ setup_fail "$SPS_EX_PERMISSION" "cannot create $setup_meson_dir"
+ setup_meson_log=$setup_meson_dir/sps-meson-probe.log
+ if ! meson --version >"$setup_meson_log" 2>&1; then
+ printf '%s: live meson cannot run\n' "$sps_prog" >&2
+ cat "$setup_meson_log" >&2
+ setup_fail "$SPS_EX_BUILD" "live meson cannot run"
+ fi
+fi
# sget treats requested names as explicit world roots.
# shellcheck disable=SC2086
sget install $setup_pkgs ||
diff --git a/man/mkiso.1 b/man/mkiso.1
index 4bec931..e6b7240 100644
--- a/man/mkiso.1
+++ b/man/mkiso.1
@@ -40,7 +40,14 @@ writes the live root only, for tests and inspection.
.PP
Host compiler tools can be copied into the image so
.B setup
-can build packages from the bundled recipes. Pass
+can build packages from the bundled recipes. The seed includes gcc,
+the Python stdlib, Meson as
+.B meson.py
+next to
+.BR mesonbuild ,
+CMake modules, and the Perl library. Host
+.B /usr/bin/meson
+is a setuptools wrapper and is replaced. Pass
.B --no-seed
to omit them.
.SH OPTIONS
diff --git a/tests/test_mkiso.sh b/tests/test_mkiso.sh
index 7ed048c..73067f3 100755
--- a/tests/test_mkiso.sh
+++ b/tests/test_mkiso.sh
@@ -235,6 +235,8 @@ 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 'live meson cannot run' "$project_dir/bin/setup" ||
+ fail 'setup must probe live meson before the first meson package'
grep -q 'copying disk tools for setup' "$mkiso" ||
fail 'mkiso must copy partition tools by command name'
grep -q grub-install "$mkiso" ||
@@ -276,6 +278,22 @@ grep -q /usr/bin/msgfmt "$project_dir/lib/mkiso/seed-bins" ||
fail 'seeded ISO must include msgfmt for alsa-utils translations'
grep -q /usr/bin/xgettext "$project_dir/lib/mkiso/seed-bins" ||
fail 'seeded ISO must include xgettext with the gettext tools'
+grep -q mkiso_install_meson "$mkiso" ||
+ fail 'seeded ISO must install mesonbuild next to meson.py'
+grep -q mkiso_copy_python_stdlib "$mkiso" ||
+ fail 'seeded ISO must copy the Python stdlib without host site-packages'
+grep -q 'seeded meson is missing mesonbuild' "$mkiso" ||
+ fail 'mkiso must refuse a disc whose meson cannot import mesonbuild'
+grep -q encodings "$mkiso" ||
+ fail 'mkiso must verify the Python encodings module landed'
+grep -q mkiso_copy_cmake_data "$mkiso" ||
+ fail 'seeded ISO must copy CMake modules'
+grep -q mkiso_copy_perl_lib "$mkiso" ||
+ fail 'seeded ISO must copy the Perl library for autoconf'
+grep -q mkiso_prune_seed_headers "$mkiso" ||
+ fail 'mkiso must drop host samplerate.h and libxml2 headers'
+grep -q samplerate.h "$mkiso" ||
+ fail 'mkiso must prune host samplerate.h from seeded includes'
grep -q '/etc/file' "$mkiso" ||
fail 'mkiso must copy /etc/file magic used by this host file(1)'
grep -q kactivitymanagerd "$project_dir/lib/mkiso/plasma-bins" ||
diff --git a/tests/test_setup.sh b/tests/test_setup.sh
index a7d8607..760aeaa 100755
--- a/tests/test_setup.sh
+++ b/tests/test_setup.sh
@@ -295,6 +295,8 @@ 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'
+grep -q 'live meson cannot run' "$setup" ||
+ fail 'setup must probe live meson before sget install'
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --init systemd \
--disable qol-cli --disable power --disable firmware)