Files
Oleksandr ShyshatskyiandClaude Opus 5 f67e7a269f ls pkg/ was thirty-eight entries and four of them mattered
pkg/ -> pkgs/, and the thirty-four recipes that build a pinned tarball and
carry no files of this repo move down a level into pkgs/3rdparty/. What is
left at the top is the four components a person actually edits: anvil-core,
klipper, moonraker, helixscreen.

THE LINE IS MECHANICAL, NOT EDITORIAL, and that is why it can be a directory
rather than a field in pkg.conf. "Do we actively modify it" drifts -- the day
somebody patches zlib nobody would agree which side it belongs on, and the
answer would be a rename touching CI and docs decided by taste. "Does it carry
files of ours" is a fact about the tree: it is exactly whether the recipe has
a payload/, prog/ or seed/, checkable in one assertion, and
test_recipe_layout.py now demands the move in both directions -- a 3rdparty
recipe that grows one of the three must come up, and a top-level recipe with
none of them must go down, or the top level slowly refills and the split stops
meaning anything.

ONE FUNCTION KNOWS THE TWO DEPTHS. pkgs/lib.sh's pkg_dir resolves a recipe id
to its directory and nothing else spells either path -- not a recipe, not
bin/build-packages.sh, not a test. Names stay unique across both levels
because pkg_out, pkg_stamp and the .ipk filename are all keyed by the bare
name; a duplicate would resolve to whichever level is searched first and
build the wrong thing silently, so that is a test too.

Recipes now source `. ./bin/common.sh` instead of counting `..` from $0.
Depth-counting would have needed two spellings for two levels, and it was
never buying anything: `. pkg/lib.sh` on the next line already required the
working directory to be the repo root.

A SECOND SILENT-SHRINK BUG, and this one was live. qa/static's _files()
expanded a list of globs and returned whatever matched, so "pkgs/*/build.sh"
quietly stopped covering thirty-four recipes the moment they moved -- the lane
stayed green, and the only visible sign was a test count dropping by 34 in a
run nobody was counting. _files() now refuses a pattern that matches nothing.
That is the same failure the ash-compatibility check had a guard for and the
syntax check did not, which is why the guard reads the way it does.

AND ONE PACKAGE WAS SHIPPING PYTHON BYTECODE. anvil-core stages a directory of
.py helpers wholesale, so any test that imported one left a __pycache__ beside
it -- gitignored, invisible in a diff, copied by cp -a like anything else. The
package's contents depended on whether pytest had been run on the machine that
built it: two builds of one commit, different sha256, cause nowhere in the
tree. What it shipped was worthless as well as unstable, compiled by the build
image's python 3.11 for a printer running the 3.13 this repo cross-builds. The
sweep is in pkg_ship now, once, and the two hand-written copies in
pkgs/klipper and pkgs/moonraker are deleted -- the trap is set for any recipe
that stages a tree of .py files, and the two recipes that had hit it had each
solved it locally while the third, which had not, was the one shipping.

Measured:
  * the rename changes no package bytes. Same cached build trees, feed built
    with the diff stashed and unstashed: all 41 .ipk match.
  * with the bytecode sweep, anvil-core returns to exactly the bytes the
    previous commit produced.
  * no package in the feed contains a .pyc or a __pycache__.
  * make qa-static: 247 passed (236 before this work + 11 layout tests).
  * make test: 8 passed, 0 failed, including unpack/patch/pack/verify on the
    synthetic stock package. make test-py: 181 passed.

Not explained: anvil-python-dev produced two different sha256 from an
UNCHANGED work/pkg/python at two points today, under code that was identical
both times -- so it is not reproducible from a cached tree, and it is not this
commit's doing (the stashed and unstashed builds above agree on it). Worth a
look; the dev split in bin/build-packages.sh is where to start.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 20:04:20 +03:00

29 lines
1.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# sqlite -- cross-compiled for the printer, as a build dependency of CPython.
#
# THE REASON THE INTERPRETER EXISTS. FlashForge built python 3.8.2 without _sqlite3 and shipped no libsqlite3 anywhere on the image, so every Moonraker from v0.9.0 on -- the release that moved the database from lmdb to sqlite -- dies at startup with ModuleNotFoundError. This library is what closes that.
#
# NOTHING INSTALLS THIS ON A PRINTER. It is a static library: it ends up inside
# the interpreter, and there is no .so to ship or to find. The package exists
# so that CPython builds against something with a version and a checksum
# instead of against a directory somebody filled in earlier.
set -euo pipefail
. ./bin/common.sh
. pkgs/lib.sh
pkg_begin sqlite || exit 0
pkg_toolchain
pkg_unpack "$SQLITE_TGZ"
# -fPIC because these are linked into extension modules, which are shared
# objects; -D_FILE_OFFSET_BITS=64 for the reason every cross-build in this tree
# carries it (32-bit build, 64-bit inodes -- see versions.env).
pkg_build "sqlite-autoconf-$SQLITE_VERSION" \
--build="$(uname -m)-linux-gnu" \
--disable-shared --enable-static --with-pic \
--disable-readline --disable-editline \
CFLAGS="-O2 -fPIC -D_FILE_OFFSET_BITS=64"
pkg_ship "include/sqlite3.h" "include/sqlite3ext.h" "lib/libsqlite3.a" "lib/pkgconfig/sqlite3.pc"
pkg_end