mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-19 03:49:50 -05:00
Package numpy, because klippy does not start without it
extras/stepper_resonance_tester.py opens with a bare `import numpy as np`; klippy.py:122 walks EVERY config section through a load_object whose importlib.import_module is not wrapped in except ImportError; printer.base.cfg includes FlashForge's printer.vibration.cfg, which declares [stepper_resonance_tester]. Since klippy moved to our own CPython 3.13 that has not been a printer missing resonance testing. It has been a klippy that never reaches ready. So this is not a scientific extra. anvil-klipper depends on anvil-python-numpy the way it depends on cffi, except that the others mean "klippy imports this" and this one means "klippy starts". It also gives back SHAPER_CALIBRATE and TEST_RESONANCES, dead since the same switch, and the VFA calibration behind STEPPER_RESONANCE_FACTORY_CALIBRATE that docs/notes/44-vfa-calibration.md traces end to end. WHAT WAS NOT OBVIOUS, in the order it bit. numpy 2.x builds with meson-python, and meson has never heard of _PYTHON_SYSCONFIGDATA_NAME -- the trick every other python-* recipe here leans on. pkg_mesoncross writes a real cross file instead, naming the $PKG_XW wrappers rather than the raw toolchain: the wrappers carry -EL -mnan=2008, and a cross file that reaches past them builds a tree that passes every gate which only reads symbols and is refused at exec() on the printer. pkg_pywheel grew a PKG_PY_PIP_ARGS branch to pass the file as --config-settings, which is the one thing PEP 517 does standardise. The cross file's `python =` is the BUILD python, and that is not a mistake: meson introspects an interpreter by running it and asking sysconfig, and pkg_pytarget has already made that sysconfig answer for mipsel. The old trick does reach meson, just not by its own mechanism. numpy's meson.build hard-errors below gcc 8.4 and ours is 7.2. The gate is the SciPy Toolchain Roadmap's support statement, not a requirement of the code: this toolchain compiles if constexpr, structured bindings, std::optional, std::string_view, and pocketfft_hdronly.h -- 3635 lines of the heaviest template C++ in the tree, and the half np.fft.rfft needs. Probed before the floor was lowered, and lowered rather than removed, behind a guard that fails loudly if upstream moves the check. 19 extension modules, every one at e_flags 0x70001405/0x70001407, 14MB shipped after pruning tests/, f2py/, stubs and static libs. meson-python is self-hosting, so pkg_buildpython runs meson and ninja just to install the backend -- hence ninja-build in the image and PYPKG_HOST_LIST in dependency order rather than alphabetical. And pip puts meson and cython in work/.py-host/bin, which nothing had ever looked in: without that on PATH the backend fails to install with `meson executable "meson" not found` while pip list shows it right there. THE GATE THAT WOULD HAVE CAUGHT ALL OF IT is qa/replica/test_klippy_extras_import.py: walk the real /usr/data/config include graph, map every section to its extra, import each on the printer's own interpreter. It needs no MCU, because config load happens before klippy:mcu_identify. Nothing asked that question before, which is how two comments in this repo came to assert the module guarded its own import. test_numpy.py asks for numeric answers rather than a module object -- linalg.lstsq specifically, because -Dallow-noblas selects the bundled lapack_lite and _r2_sinusoidal_fit calls it every calibration round. And test_install.py's include check read only ff-*.cfg, so FlashForge's four -- printer.vibration.cfg among them -- were never asked about at all. ff-toolchange.cfg wraps the two search commands in _FF_SHAPER_PREP, as SHAPER_CALIBRATE already was. STEPPER_RESONANCE_FACTORY_CALIBRATE is deliberately NOT wrapped: it is a gcode_macro, not a registered command, and same-named sections merge under RawConfigParser(strict=False) -- a wrapper would not wrap it, it would BE it, with rename_existing pointing at itself. It needs none, since its body is two calls to a command that is wrapped. No SAVE_CONFIG in any macro either; it restarts klippy and stays the operator's. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJr2x7aDaY889qwSxbdLt8
This commit is contained in:
1 parent
a10930aa26
commit
28eb20f3da
14 files changed
+880
-86
No files matched your search
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
# numpy -- built for the printer's CPython, into its site-packages.
|
||||
#
|
||||
# THE ONLY meson-python RECIPE IN THE FEED. Every other python-* package here
|
||||
# builds with setuptools, where _PYTHON_SYSCONFIGDATA_NAME alone is enough to
|
||||
# make the build answer for mipsel. Meson has never heard of that variable, so
|
||||
# this one hands it a cross file instead -- see pkg_mesoncross in pkgs/lib.sh
|
||||
# for what is in it and why each line is there.
|
||||
set -euo pipefail
|
||||
. ./bin/common.sh
|
||||
. pkgs/lib.sh
|
||||
|
||||
pkg_begin python-numpy || exit 0
|
||||
pkg_toolchain
|
||||
pkg_deps
|
||||
pkg_buildpython
|
||||
pkg_pytarget
|
||||
pkg_unpack "$(pypkg_tgz numpy)"
|
||||
|
||||
_np=$(pkg_pysrc numpy)
|
||||
|
||||
# numpy's meson.build refuses gcc below 8.4, and ours is 7.2. THE GATE IS
|
||||
# CONSERVATIVE RATHER THAN LOAD-BEARING, and that was probed before it was
|
||||
# lowered: numpy 2.1's requirement is a C++17 compiler, and this toolchain
|
||||
# compiles the features it actually uses -- if constexpr, structured bindings,
|
||||
# std::optional, std::string_view -- as well as pocketfft_hdronly.h, 3635 lines
|
||||
# of the heaviest template C++ in the tree and the half np.fft.rfft needs.
|
||||
# The upstream number comes from the SciPy Toolchain Roadmap, which is a
|
||||
# statement about what the project supports, not about what the code requires.
|
||||
#
|
||||
# The floor is LOWERED, not removed: a genuinely ancient gcc should still be
|
||||
# refused here rather than three screens into a compile log. If this recipe
|
||||
# ever fails with a C++ error rather than a version error, that is the gate
|
||||
# turning out to be real after all, and the fix is a newer cross toolchain --
|
||||
# not a smaller number.
|
||||
if ! grep -q "version_compare('>=8.4')" "$_np/meson.build"; then
|
||||
pkg_die "python-numpy: the gcc version gate in meson.build is not where
|
||||
this recipe patches it -- numpy $(pypkg_version numpy) has moved
|
||||
it, and the comment above needs re-checking against the new one"
|
||||
fi
|
||||
sed -i "s/version_compare('>=8.4')/version_compare('>=7.2')/" "$_np/meson.build"
|
||||
|
||||
# -Dallow-noblas: no BLAS/LAPACK in this feed, so take the bundled lapack_lite.
|
||||
# Without this numpy 2.x fails configure rather than falling back.
|
||||
# -Ddisable-optimization: numpy's SIMD dispatch machinery generates and builds
|
||||
# a matrix of per-feature objects. There is no MIPS path in it, so every one
|
||||
# of them is a baseline build anyway -- this drops the generation step and,
|
||||
# with it, the largest surface for a gcc 7.2 to refuse something.
|
||||
PKG_PY_PIP_ARGS="--config-settings=setup-args=--cross-file=$(pkg_mesoncross)
|
||||
--config-settings=setup-args=-Dallow-noblas=true
|
||||
--config-settings=setup-args=-Ddisable-optimization=true"
|
||||
|
||||
pkg_pywheel numpy
|
||||
|
||||
# PRUNE BEFORE SHIP, and only things nothing on a printer can reach.
|
||||
# tests/ ~8MB of pytest files; pytest is not on this machine.
|
||||
# f2py/ a Fortran wrapper generator, and there is no Fortran here.
|
||||
# *.pyi, py.typed type stubs, read by type checkers and never at runtime.
|
||||
# _core/lib/*.a static libs for BUILDING against numpy's C API, which
|
||||
# nothing on the printer does.
|
||||
# The .so files are not touched here: pkg_ship runs the cross strip over
|
||||
# everything it copies.
|
||||
find "$PKG_PYSP/numpy" -type d -name tests -prune -exec rm -rf {} + 2>/dev/null || true
|
||||
rm -rf "$PKG_PYSP/numpy/f2py"
|
||||
find "$PKG_PYSP/numpy" -name '*.pyi' -delete 2>/dev/null || true
|
||||
find "$PKG_PYSP/numpy" -name 'py.typed' -delete 2>/dev/null || true
|
||||
find "$PKG_PYSP/numpy" -name '*.a' -delete 2>/dev/null || true
|
||||
|
||||
pkg_ship "lib/python$PY_MM/site-packages"
|
||||
|
||||
# A COUNT, AND A HIGH ONE ON PURPOSE. numpy has a pure-python fallback for
|
||||
# nothing -- if the cross build quietly produced no extensions there would be
|
||||
# no import at all, but a partial build that lost _multiarray_umath while
|
||||
# keeping the small ones would import far enough to look installed. Eight is
|
||||
# comfortably below what a whole numpy ships and far above any partial one.
|
||||
pkg_pynative 8
|
||||
pkg_end
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
# anvil-python-numpy -- numpy for the printer's CPython, into its
|
||||
# site-packages.
|
||||
#
|
||||
# THIS IS NOT AN OPTIONAL SCIENTIFIC EXTRA. It is the package klippy cannot
|
||||
# start without. extras/stepper_resonance_tester.py opens with a bare
|
||||
# `import numpy as np`; klippy.py:122 walks EVERY config section through a
|
||||
# load_object that does not catch ImportError; and printer.base.cfg includes
|
||||
# FlashForge's printer.vibration.cfg, which declares [stepper_resonance_tester].
|
||||
# So on a numpy-less install klippy never reaches ready -- it does not merely
|
||||
# lose a feature. anvil-klipper names this package in its Depends for that
|
||||
# reason. docs/notes/44-vfa-calibration.md has the whole chain.
|
||||
#
|
||||
# WHAT IT BUYS BACK, beyond the boot: the VFA (motor torque-ripple) calibration
|
||||
# behind STEPPER_RESONANCE_FACTORY_CALIBRATE, and SHAPER_CALIBRATE /
|
||||
# TEST_RESONANCES, which have been dead for exactly the same reason since
|
||||
# klippy moved to our own CPython 3.13.
|
||||
PKG_NAME=anvil-python-numpy
|
||||
|
||||
# ARCHITECTURE IS THE DEFAULT, mipsel_xburst2, and it is not a formality here
|
||||
# any more than it is for anvil-klipper: this package is mostly compiled code.
|
||||
# An `all` would let it install on a machine whose kernel refuses every .so in
|
||||
# it, and the failure would arrive as an ImportError halfway through a boot.
|
||||
PKG_VERSION="$(pypkg_version numpy)"
|
||||
PKG_RELEASE=1
|
||||
PKG_SECTION=python
|
||||
PKG_EXCLUDE=".version"
|
||||
|
||||
PKG_DEPENDS="anvil-python"
|
||||
|
||||
# python ALONE, and no BLAS: -Dallow-noblas=true below picks numpy's bundled
|
||||
# lapack_lite instead. That is not a corner cut for size -- there is no BLAS in
|
||||
# this feed to link against, and lapack_lite is enough for the one linalg call
|
||||
# the calibration makes (np.linalg.lstsq, in _r2_sinusoidal_fit).
|
||||
PKG_BUILD_DEPENDS="python"
|
||||
|
||||
PKG_DESCRIPTION="numpy for klippy -- the FFT, least-squares and polynomial fitting that extras/stepper_resonance_tester.py and shaper_calibrate.py are written against. Built with meson-python against a cross file, without BLAS."
|
||||
@@ -66,19 +66,23 @@ export LD_LIBRARY_PATH
|
||||
# klippy -- which reaches c_helper.so through _cffi_backend, the reason this
|
||||
# interpreter had to be a glibc build.
|
||||
#
|
||||
# klippy's numpy gap (extras/stepper_resonance_tester.py) is this switch's
|
||||
# problem and it is NOT a smaller item. This comment used to say the module
|
||||
# guards its own import, so the printer runs without it and loses resonance
|
||||
# testing. Both halves are wrong: line 1 of that file is a bare
|
||||
# THE NUMPY GAP WAS THIS SWITCH'S, and it was not the small item this comment
|
||||
# used to call it. The old text said extras/stepper_resonance_tester.py guards
|
||||
# its own import, so the printer runs without numpy and merely loses resonance
|
||||
# testing. Both halves were wrong: line 1 of that file is a bare
|
||||
# `import numpy as np`, and klippy.py:122 loads EVERY config section through a
|
||||
# load_object that does not catch ImportError. printer.base.cfg includes
|
||||
# FlashForge's printer.vibration.cfg, which declares
|
||||
# [stepper_resonance_tester] -- so on this interpreter klippy does not come up
|
||||
# at all, rather than coming up without one feature.
|
||||
# [stepper_resonance_tester] -- so moving klippy to an interpreter without
|
||||
# numpy did not cost a feature, it stopped klippy reaching ready at all.
|
||||
#
|
||||
# See docs/notes/44-vfa-calibration.md for the chain and the options. Nothing
|
||||
# here is fixed by editing this line; it takes either a packaged numpy or a
|
||||
# guarded import in the fork.
|
||||
# CLOSED BY pkgs/3rdparty/python-numpy, which anvil-klipper now names in its
|
||||
# Depends. FlashForge's 3.8.2 had numpy in its rootfs and a 3.8 .so is not
|
||||
# importable from 3.13, so the interpreter switch had to bring its own -- and
|
||||
# it is the reason ninja-build is in docker/Dockerfile.build and
|
||||
# pkgs/lib.sh grew pkg_mesoncross. docs/notes/44-vfa-calibration.md has the
|
||||
# chain, and qa/replica/test_klippy_extras_import.py is the gate that would
|
||||
# have caught it.
|
||||
#
|
||||
# Note what is NOT on PATH below: $MODDIR/bin is prepended and the interpreter
|
||||
# is in there, but it is called python3.13 and only that. bin/payload.sh
|
||||
|
||||
@@ -209,3 +209,50 @@ rename_existing: _FF_MEASURE_AXES_NOISE_BASE
|
||||
gcode:
|
||||
_FF_SHAPER_PREP
|
||||
_FF_MEASURE_AXES_NOISE_BASE {rawparams}
|
||||
|
||||
# VFA (vertical fine artifacts) -- the motor torque-ripple compensation, which
|
||||
# is a DIFFERENT mechanism from the input shaping above and shares only the
|
||||
# accelerometer. The commands come from klippy/extras/stepper_resonance_tester.py;
|
||||
# these wrappers are ours, and exist for the reason the three above do: both
|
||||
# sweep the carriage and read [lis2dw], so an empty carriage measures the wrong
|
||||
# moving mass.
|
||||
#
|
||||
# STEPPER_RESONANCE_FACTORY_CALIBRATE IS DELIBERATELY NOT WRAPPED, and the
|
||||
# reason is worth stating because the obvious edit is wrong. It is not a
|
||||
# Python-registered command like the two below -- it is a [gcode_macro] in
|
||||
# FlashForge's printer.vibration.cfg. Klipper parses with
|
||||
# RawConfigParser(strict=False), so a second section of the same name MERGES
|
||||
# with the first rather than sitting beside it: a
|
||||
# `[gcode_macro STEPPER_RESONANCE_FACTORY_CALIBRATE]` here would not wrap that
|
||||
# macro, it would BE that macro, with a rename_existing pointing at a command
|
||||
# that does not exist yet.
|
||||
#
|
||||
# It needs no wrapper anyway. Its whole body is two
|
||||
# STEPPER_RESONANCE_SEARCH_CALIBRATE calls, and those are wrapped here -- so
|
||||
# the prep happens either way, once, from whichever command is reached first
|
||||
# (_FF_SHAPER_PREP homes only if unhomed and grabs a tool only if none is
|
||||
# mounted, so the second call is a no-op).
|
||||
#
|
||||
# NO SAVE_CONFIG HERE EITHER. The search applies its result live with
|
||||
# MCLIB_SET_RESONANCE_DAMP and stages it with configfile.set, which only
|
||||
# SAVE_CONFIG writes -- so without one the calibration is lost on the next
|
||||
# restart. The stock app had exactly this split: the macro's own SAVE_CONFIG is
|
||||
# commented out, and the app issued one separately at the end of the whole
|
||||
# calibration run. It stays the operator's step because SAVE_CONFIG restarts
|
||||
# klippy, which is not a thing a macro should do to somebody mid-session:
|
||||
#
|
||||
# STEPPER_RESONANCE_FACTORY_CALIBRATE
|
||||
# SAVE_CONFIG
|
||||
#
|
||||
# See docs/notes/44-vfa-calibration.md.
|
||||
[gcode_macro STEPPER_RESONANCE_SEARCH_CALIBRATE]
|
||||
rename_existing: _FF_STEPPER_RESONANCE_SEARCH_CALIBRATE_BASE
|
||||
gcode:
|
||||
_FF_SHAPER_PREP
|
||||
_FF_STEPPER_RESONANCE_SEARCH_CALIBRATE_BASE {rawparams}
|
||||
|
||||
[gcode_macro STEPPER_RESONANCE_REFINE_CALIBRATE]
|
||||
rename_existing: _FF_STEPPER_RESONANCE_REFINE_CALIBRATE_BASE
|
||||
gcode:
|
||||
_FF_SHAPER_PREP
|
||||
_FF_STEPPER_RESONANCE_REFINE_CALIBRATE_BASE {rawparams}
|
||||
+10
-9
@@ -24,14 +24,15 @@ PKG_EXCLUDE=".version"
|
||||
# HERE. python-can is not packaged (no CAN transport on this machine) and it
|
||||
# is import-guarded, so its absence costs nothing.
|
||||
#
|
||||
# NUMPY IS NOT IN THAT CLASS and this comment used to claim it was.
|
||||
# extras/stepper_resonance_tester.py opens with a bare `import numpy as np`,
|
||||
# and klippy.py:122 walks every config section through a load_object that does
|
||||
# not catch ImportError -- so with printer.base.cfg including FlashForge's
|
||||
# printer.vibration.cfg ([stepper_resonance_tester]), a numpy-less install is
|
||||
# a klippy that never reaches ready. It is a Depends this package cannot yet
|
||||
# declare because no anvil-python-numpy exists to name;
|
||||
# docs/notes/44-vfa-calibration.md has the chain and what packaging it takes.
|
||||
# NUMPY IS NOT IN THAT CLASS, and it is the one Depends here whose absence is
|
||||
# not a missing feature but a dead printer. extras/stepper_resonance_tester.py
|
||||
# opens with a bare `import numpy as np`, and klippy.py:122 walks every config
|
||||
# section through a load_object that does not catch ImportError -- so with
|
||||
# printer.base.cfg including FlashForge's printer.vibration.cfg
|
||||
# ([stepper_resonance_tester]), a numpy-less install is a klippy that never
|
||||
# reaches ready. Read the rest of this list as "klippy imports it"; read this
|
||||
# one as "klippy does not start". docs/notes/44-vfa-calibration.md has the
|
||||
# chain.
|
||||
#
|
||||
# markupsafe and setuptools are not named
|
||||
# because anvil-python-jinja2 declares the first and nothing needs the second.
|
||||
@@ -46,7 +47,7 @@ PKG_EXCLUDE=".version"
|
||||
# printer.cfg includes and every other config hangs off it.
|
||||
PKG_DEPENDS="anvil-klipper-config, anvil-python, anvil-python-cffi,
|
||||
anvil-python-greenlet, anvil-python-pyserial,
|
||||
anvil-python-jinja2"
|
||||
anvil-python-jinja2, anvil-python-numpy"
|
||||
PKG_BUILD_DEPENDS=""
|
||||
|
||||
# NO PKG_WHEN. The fork is the only Klipper, and nothing here is optional --
|
||||
|
||||
+105
-2
@@ -197,7 +197,7 @@ pkg_begin() {
|
||||
# its project. See pkg_build.
|
||||
PKG_CONFIGURE='./configure'; PKG_CONFIGURE_AUTO=1
|
||||
PKG_MAKE_TARGET=''; PKG_INSTALL_TARGET='install'; PKG_MAKE_ARGS=''
|
||||
PKG_PY_SETUP_ARGS=''; PKG_CC_SHARED=''
|
||||
PKG_PY_SETUP_ARGS=''; PKG_PY_PIP_ARGS=''; PKG_CC_SHARED=''
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -285,6 +285,25 @@ pkg_buildpython() {
|
||||
HOSTPY="$PKG_HOSTPY_ROOT/bin/python$PY_MM"
|
||||
export HOSTPY
|
||||
|
||||
# THE BUILD-PYTHON'S SCRIPT DIRECTORY GOES ON PATH, because two of the
|
||||
# backends installed below are programs another backend EXECS rather than
|
||||
# modules it imports. meson-python looks for a `meson` executable and
|
||||
# numpy's meson.build does find_program('cython'); pip puts both in
|
||||
# $PKG_HOSTPY_ROOT/bin, which nothing has ever had a reason to look in. The
|
||||
# symptom without this is meson-python failing to install with
|
||||
# `meson executable "meson" not found` while `pip list` shows meson right
|
||||
# there -- installed, importable and unreachable.
|
||||
#
|
||||
# It also puts this python on PATH as python3, which is why it is done HERE
|
||||
# and not in bin/common.sh: build-packages.sh runs each recipe as a child
|
||||
# process, so an export in a recipe cannot reach the one bare `python3` in
|
||||
# the build lane (build-packages.sh's opkg-index call) and cannot change
|
||||
# what that resolves to.
|
||||
case ":$PATH:" in
|
||||
*":$PKG_HOSTPY_ROOT/bin:"*) ;;
|
||||
*) PATH="$PKG_HOSTPY_ROOT/bin:$PATH"; export PATH ;;
|
||||
esac
|
||||
|
||||
_hpstamp="$PY_VERSION"
|
||||
for _p in setuptools $PYPKG_HOST_LIST; do
|
||||
_hpstamp="$_hpstamp $(pypkg_var "$_p" FILE)"
|
||||
@@ -602,6 +621,74 @@ PYEOF
|
||||
pkg_say "$PKG_ID: sysconfig answers for mipsel, headers at $PKG_PYINC"
|
||||
}
|
||||
|
||||
# pkg_mesoncross -- write a meson cross file for this target and echo its path.
|
||||
# After pkg_toolchain and pkg_pytarget. For meson-python packages only; a
|
||||
# setuptools package needs none of this.
|
||||
#
|
||||
# WHY IT EXISTS AT ALL: _PYTHON_SYSCONFIGDATA_NAME is a distutils/setuptools
|
||||
# mechanism. Meson has never heard of it and will not cross-compile without
|
||||
# being told, in this file, what the host machine is.
|
||||
#
|
||||
# THE COMPILERS ARE THE WRAPPERS, NOT THE TOOLCHAIN'S OWN. $PKG_XW/bin holds
|
||||
# three-line shims that add $PKG_CC_FLAGS -- `-EL -mnan=2008` -- and the raw
|
||||
# mips-linux-gnu-gcc beside them does not. A cross file naming the raw binary
|
||||
# produces a tree that builds perfectly, passes every test that only reads
|
||||
# symbols, and is refused at exec() on the printer, which is the failure
|
||||
# pkg_toolchain's own e_flags gate exists to prevent. Reaching past the wrapper
|
||||
# here would walk straight around that gate.
|
||||
#
|
||||
# python = $HOSTPY IS NOT A MISTAKE. Meson's python module introspects an
|
||||
# interpreter by RUNNING it and asking sysconfig, and pkg_pytarget has already
|
||||
# made $HOSTPY's sysconfig answer for mipsel. So the host interpreter reports
|
||||
# the target's EXT_SUFFIX and INCLUDEPY, which is exactly what meson needs and
|
||||
# what pkg_pytarget's closing gate has already proved before we get here.
|
||||
#
|
||||
# longdouble_format IS REQUIRED AND HAS NO DEFAULT. numpy determines it by
|
||||
# compiling and RUNNING a probe, which a cross build cannot do; without this
|
||||
# property the configure step dies with "Cannot determine long double format".
|
||||
# o32 MIPS has a 64-bit long double -- the same representation as double --
|
||||
# which is IEEE_DOUBLE_LE on a little-endian target.
|
||||
pkg_mesoncross() {
|
||||
[ -n "${PKG_XW:-}" ] || pkg_die \
|
||||
"$PKG_ID: pkg_mesoncross needs the toolchain -- call pkg_toolchain first"
|
||||
[ -n "${PKG_PYSP:-}" ] || pkg_die \
|
||||
"$PKG_ID: pkg_mesoncross needs the target environment -- call pkg_pytarget first"
|
||||
|
||||
_xf="$PWD/$PKG_WORK/meson-cross.ini"
|
||||
cat > "$_xf" <<EOF
|
||||
# Generated by pkgs/lib.sh: pkg_mesoncross. Build-time only; never ships.
|
||||
[binaries]
|
||||
c = '$PKG_XW/bin/$PKG_HOST-gcc'
|
||||
cpp = '$PKG_XW/bin/$PKG_HOST-g++'
|
||||
ar = '$PKG_XW/bin/$PKG_HOST-ar'
|
||||
strip = '$PKG_XW/bin/$PKG_HOST-strip'
|
||||
pkg-config = 'pkg-config'
|
||||
python = '$HOSTPY'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'mips'
|
||||
cpu = 'mips32r2'
|
||||
endian = 'little'
|
||||
|
||||
[properties]
|
||||
longdouble_format = 'IEEE_DOUBLE_LE'
|
||||
EOF
|
||||
# Gated here rather than at the far end of a ten-minute compile: a wrapper
|
||||
# that is not executable, or a $PKG_HOST that does not match the toolchain,
|
||||
# is a meson "compiler not found" three screens into a configure log.
|
||||
for _b in gcc g++; do
|
||||
[ -x "$PKG_XW/bin/$PKG_HOST-$_b" ] || pkg_die \
|
||||
"$PKG_ID: pkg_mesoncross names $PKG_XW/bin/$PKG_HOST-$_b, which is not executable"
|
||||
done
|
||||
# >&2 BECAUSE THIS FUNCTION'S STDOUT IS ITS RETURN VALUE. pkg_say prints to
|
||||
# stdout like every other reporter here, and a recipe reads this as
|
||||
# $(pkg_mesoncross) -- so an unredirected line would be captured into the
|
||||
# path and handed to meson as part of a filename.
|
||||
pkg_say "$PKG_ID: meson cross file at $_xf" >&2
|
||||
printf '%s' "$_xf"
|
||||
}
|
||||
|
||||
# pkg_pysrc <list-entry> -- where this package's sdist unpacked to: the file
|
||||
# name with .tar.gz removed, under $PKG_WORK/src.
|
||||
pkg_pysrc() {
|
||||
@@ -615,6 +702,15 @@ pkg_pysrc() {
|
||||
# PKG_PY_SETUP_ARGS drive setup.py build_ext with these and then
|
||||
# bdist_wheel, instead of pip. PEP 517 offers no way to
|
||||
# pass build_ext options, and pillow's --disable-* are.
|
||||
# PKG_PY_PIP_ARGS extra arguments for the pip path, unquoted as a list.
|
||||
# For --config-settings, which is the ONE thing PEP 517
|
||||
# does standardise -- and the only way to hand
|
||||
# meson-python a --cross-file. numpy's are.
|
||||
#
|
||||
# THE TWO OPTIONS ARE NOT ALTERNATIVES TO EACH OTHER. PKG_PY_SETUP_ARGS leaves
|
||||
# the pip path entirely; PKG_PY_PIP_ARGS stays on it. Setting both is a recipe
|
||||
# asking for setuptools and configuring meson, so it is refused below rather
|
||||
# than silently resolved in favour of whichever branch is written first.
|
||||
#
|
||||
# NOTHING HERE TALKS TO A NETWORK: pip runs --no-index against a tree whose
|
||||
# sha256 bin/fetch-assets.sh checked, and --no-binary :all: guards against
|
||||
@@ -630,6 +726,9 @@ pkg_pywheel() {
|
||||
"$PKG_ID: $(pypkg_var "$_pw" FILE) did not unpack to $(basename "$_wdir")"
|
||||
[ -n "${PKG_PYSP:-}" ] || pkg_die \
|
||||
"$PKG_ID: pkg_pywheel needs the target environment -- call pkg_pytarget first"
|
||||
[ -z "${PKG_PY_SETUP_ARGS:-}" ] || [ -z "${PKG_PY_PIP_ARGS:-}" ] || pkg_die \
|
||||
"$PKG_ID: PKG_PY_SETUP_ARGS and PKG_PY_PIP_ARGS are both set, and they
|
||||
drive different build paths -- setup.py or pip, not both"
|
||||
_wheels="$PWD/$PKG_WORK/wheels"
|
||||
rm -rf "$_wheels"; mkdir -p "$_wheels"
|
||||
_wlog="$PKG_LOG/wheel-$_pw.log"
|
||||
@@ -648,8 +747,12 @@ pkg_pywheel() {
|
||||
cp -a "$_wdir"/dist/*.whl "$_wheels/" \
|
||||
|| pkg_die "$PKG_ID: $_pw's setup.py produced no wheel -- see $_wlog"
|
||||
else
|
||||
# Deliberately unquoted: PKG_PY_PIP_ARGS is a list of options, empty
|
||||
# for every recipe that does not set it.
|
||||
# shellcheck disable=SC2086
|
||||
env "$@" "$HOSTPY" -m pip wheel --no-deps --no-build-isolation \
|
||||
--no-index --no-binary :all: --no-cache-dir -w "$_wheels" "$_wdir" \
|
||||
--no-index --no-binary :all: --no-cache-dir \
|
||||
${PKG_PY_PIP_ARGS:-} -w "$_wheels" "$_wdir" \
|
||||
> "$_wlog" 2>&1 || {
|
||||
printf ' !! %s: %s failed to build -- see %s\n' "$PKG_ID" "$_pw" "$_wlog" >&2
|
||||
tail -25 "$_wlog" | sed 's/^/ /' >&2
|
||||
|
||||
Reference in new issue
Block a user