mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-22 21:32:16 -05:00
The software component existed to give the mod one exec hook. It is not needed for that any more, so a release now carries our installer and our payload and nothing else: 26MB smaller, 21MB of which was FlashForge's own firmwareExe travelling back to the partition it was already on, along with their klippy tree, their wifi module and their configs. WHAT IT GIVES BACK. /usr/prog/PROGRAM/software is no longer rewritten, so the version directory there stays FlashForge's with their genuine firmwareExe inside it -- and app_startup.sh's five-second watchdog, which copies one out of that directory when nothing by that name is running, has something to copy again. A printer whose payload fails to install now comes up on the stock UI instead of a blank screen. That recovery has been broken since we started deleting their binary out of a component we shipped; docs/how-it-works.md claimed it worked throughout. THE ROOT PASSWORD moves with it, because it used to ride in the component's shadow file. bin/pack.sh bakes ROOT_PW_HASH into the installer, single-quoted -- an unquoted $6$... would have the printer's shell expand $6 as a positional parameter and ship a truncated hash -- and the installer writes it to /usr/prog/etc/shadow. The random-password path asks one question instead of four: FlashForge ship the same root hash on every machine, so a live shadow still carrying it means nobody has set a password and it is ours to set. The .prev-root-hash recording, the shipped-vs-live comparison and the restore-it- afterwards step were all machinery for surviving a file that nothing overwrites any more, and are gone. pack.sh checks the hardcoded constant against the stock package it built from, because getting it wrong is silent and total: every printer would read as "already set" and none would ever get a password. bin/patch.sh is bin/payload.sh. It patched nothing any more -- no splice, no shadow edit, no firmwareExe deletion -- and what is left is the payload: the feed installed by the printer's own opkg, the seeded config, the manifest. Its sections are renumbered 1-5 with no gaps, and the five tombstone comments marking where removed sections used to be are gone with them. test_recipe_layout.py loses six of its nine tests. Each compared the tree against a description of the tree -- no fourth directory kind, each kind still used, 3rdparty carries no files of ours, installer/ holds exactly two named files -- and none could go red for a reason a printer would notice, while all six went red the moment the layout legitimately changed. The two that bite are kept: a payload/ path escaping $MODDIR, and a recipe name at both levels, which makes pkg_dir silently build the wrong package. SW_VER is deleted from config.env.example and both workflows: it stamped a component that is not built. Gates: 112 static tests pass. The generated installer is verified after substitution -- all four lines present, and `sh -n` over the result, because a hash with a stray character in it would otherwise reach a printer as a syntax error whose only symptom is a package that installs nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CH7Yb4wuPhnppHAB25UX7e
62 lines
3.5 KiB
INI
62 lines
3.5 KiB
INI
# The only thing that runs on your machine is Docker itself.
|
|
#
|
|
# Every make target executes inside this image: the build scripts, the tests,
|
|
# and the install simulations. The docker CLI is included so the simulation
|
|
# targets can start sibling containers through the mounted socket, and
|
|
# qemu-user-static so the printer's real MIPS userland can be executed.
|
|
#
|
|
# A HOST C compiler is in here as well, which looks redundant next to two
|
|
# cross-toolchains that arrive as pinned tarballs. It is not: cross-building
|
|
# CPython needs a build-python of exactly the same version to freeze modules
|
|
# and byte-compile the stdlib, so bin/payload.sh builds an x86-64 3.13 out of
|
|
# the same source tarball first, and that one needs the host's own gcc.
|
|
# pkg-config and perl are for the same section -- CPython's configure probes
|
|
# libffi through pkg-config, and OpenSSL's Configure is a perl program.
|
|
#
|
|
# zlib1g-dev is for THE HOST HALF of that build and nothing else, which is why
|
|
# it looks out of place beside two cross-toolchains: the build-python needs a
|
|
# working zlib module. Every wheel the package step produces is a zip, and so
|
|
# is the pip that produces them -- ensurepip installs pip out of a bundled
|
|
# .whl, and a build-python without zlib cannot even unpack it ("can't
|
|
# decompress data; zlib not available"). CPython records the module as missing
|
|
# and carries on, so the symptom lands three steps later as "No module named
|
|
# pip". The TARGET's zlib is nothing to do with this: that one is the static
|
|
# -fPIC libz.a bin/payload.sh cross-builds from the pinned tarball.
|
|
#
|
|
# `patch` is in the list above for one package: lmdb's setup.py shells out to
|
|
# /usr/bin/patch BY ABSOLUTE PATH to apply its own env-copy-txn.patch to the
|
|
# bundled liblmdb before compiling it, and raises "Applying patch failed" when
|
|
# that is not there -- which is a build failure with nothing in it to say that
|
|
# a two-hundred-kilobyte utility is what is missing. lmdb is Moonraker's
|
|
# database at the pinned commit, so this is not an optional package.
|
|
#
|
|
# The alternative was a container of its own, the way tools/supervisor and
|
|
# tools/python build for measurement. The build lane deliberately gets no
|
|
# docker socket (only the test lane does), so there is no daemon to ask.
|
|
#
|
|
# libarchive-dev IS DEBIAN'S, DELIBERATELY, AND IS THE ONE EXCEPTION TO
|
|
# versions.env. pkgs/lib.sh's pkg_buildopkg builds an x86-64 opkg from the
|
|
# pinned opkg tarball to assemble the payload, and opkg requires libarchive
|
|
# (configure.ac: "Require libarchive"). That opkg is a BUILD TOOL: it runs
|
|
# here, in this container, and never leaves it. The pin-and-hash rule governs
|
|
# what reaches the printer, and the printer's opkg is a different binary --
|
|
# pkgs/3rdparty/opkg, cross-compiled against the libarchive OUR feed built.
|
|
# Taking Debian's for the host tool is the same call already made for gcc,
|
|
# which pkg_buildpython uses to build the x86-64 build-python.
|
|
FROM debian:bookworm-slim
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
RUN echo 'Acquire::Retries "3";' > /etc/apt/apt.conf.d/80-retries \
|
|
&& apt-get update && apt-get install -y --no-install-recommends \
|
|
bash coreutils tar xz-utils gzip openssl unzip curl ca-certificates \
|
|
python3 python3-jinja2 python3-pytest python3-pyflakes \
|
|
python3-pytest-xdist \
|
|
binutils file findutils grep sed gawk make git diffutils patch procps \
|
|
squashfs-tools qemu-user-static docker.io shellcheck \
|
|
gcc g++ libc6-dev zlib1g-dev pkg-config perl \
|
|
libarchive-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /src
|
|
CMD ["bash"]
|