# Pinned third-party payload pieces. Not vendored: bin/fetch-assets.sh fetches # them into vendor/ and refuses anything whose sha256 does not match. To bump: # edit the version (and the FILE, if it carries one), set the sha256 to SKIP, # run `make vendor`, paste back the hash it prints. # The stock FlashForge package -- the one input the build cannot synthesise, # and the only pin here that is not a payload piece. ONE PER MODEL, and they # are not interchangeable: each carries its own firmwareExe and refuses to # install on the other, so bin/common.sh picks by TARGET_MACHINE. # # Nothing proprietary is redistributed from this repo. ghzserg/FF is the public # archive docs/support.md already sends printer owners to for the undo button, # and the sha256 is what makes building from somebody else's mirror safe: the # archive can change under us and the build stops instead of quietly producing # a package diffed against firmware nobody checked. # # THE TAG IS A ROLLING `R` holding every FlashForge model at once, so there is # no per-release tag to move to -- the pin is the FILENAME plus the sha256, and # the filename carries the version. A withdrawn asset breaks the fetch loudly. # # To build against firmware you downloaded yourself, set STOCK_TGZ_CREATOR5PRO # (or _CREATOR5) in config.env. Unlike HELIX_TGZ that path is never overwritten # -- see the note in bin/fetch-assets.sh for why this one is the exception. STOCK_URL_BASE="https://github.com/ghzserg/FF/releases/download/R" STOCK_VERSION="1.9.7-1.2.9-20260810" STOCK_FILE_CREATOR5PRO="Creator5Pro-$STOCK_VERSION.tgz" STOCK_SHA256_CREATOR5PRO="1f3252feaae6d8fc72d7b0fd1ba832cc63d369659f8b2d2896efcf7adab2976b" STOCK_FILE_CREATOR5="Creator5-$STOCK_VERSION.tgz" STOCK_SHA256_CREATOR5="72009be183e74a4562050a927787ba686c6b558a075f00958892197ac52659cc" MAINSAIL_VERSION="v2.19.0" MAINSAIL_SHA256="c4d9d96f89851c6ae0709c2f20725447f3fe8c57cf193869b0083441bd93378a" FLUIDD_VERSION="v1.37.5" FLUIDD_SHA256="d61d2f3a2ec69f1e6dd330dca17ba77700d4001cf5c4568dc192934691e3f33f" # Klipper: Klipper4FlashForge's creator5 HEAD, so a COMMIT. The only klipper # source -- pkg/klipper builds c_helper.so from this same tree. KLIPPER_VERSION="f51aab7a843a3852c808e28d694be8b59bbbc130" KLIPPER_SHA256="ed501bcbaa8b4b9398318b424889c7ed451b89411c54fc3f5d02ea991e86bd55" # The only toolchain with this printer's ABI (mips32r2, LE, o32, nan2008). MIPS_TOOLCHAIN_VERSION="1.0.0" MIPS_TOOLCHAIN_FILE="mips-gcc720-glibc229.tar.gz" MIPS_TOOLCHAIN_SHA256="c0415a857c6b384820ec61b8a30c89e528585f3ef07d580fc856e80313c9d2e8" HELIX_VERSION="v0.99.118-creator5" # The same release as a PACKAGE version, typed out rather than derived: the # upstream tag is not a version any package manager can parse, and apk's # grammar in particular allows only a closed set of suffixes (see # pkg_version_ok in pkgs/lib.sh), so a platform suffix such as `.creator5.5` # is rejected. A numbered platform revision uses apk's `_pN` slot; this tag # has no numbered revision, so the package version is the upstream version. # # ADJACENT TO THE TAG ON PURPOSE: these two move together, and a bump that # edited one and not the other would ship a package labelled with the version # before it. That is the failure the two lines being neighbours prevents. HELIX_PKG_VERSION="0.99.118" HELIX_FILE="helixscreen-creator5-v0.99.118.tar.gz" HELIX_SHA256="87bc2de17f4f557f4af78af4b9cade90287df71e4ab8391276b0f7499d9d3007" # Moonraker: a RELEASE TAG, not a commit. The old pin was the last commit # before 80c7620 moved the database from lmdb to sqlite, because 3.8.2 has no # _sqlite3 -- and this repo now builds and ships its own CPython, which does. # # /archive/ takes the tag, but GitHub strips the leading "v" from the # directory inside the tarball, which is why pkgs/moonraker/build.sh reaches # for moonraker-${MOONRAKER_VERSION#v}. # # LMDB STILL SHIPS. Moonraker converts an existing data.mdb to sqlite on first # start and imports lmdb to read it; with the module missing it tries to pip # install one, which on a printer with no index means the old database is # silently dropped. It is the upgrade path, not a runtime dependency. # # Nothing on the printer falls back to a stock build, so gate a bump on # `make qa-replica`. MOONRAKER_VERSION="v0.11.0" MOONRAKER_SHA256="bba9042e9fc904b30cd46690320fec2bffe27c4458b539db65560582c6318ab3" # s6: a matched set that will not build across generations, so all four bump # together. Three load-bearing build flags -- tools/supervisor/README.md. SKALIBS_VERSION="2.15.1.0" SKALIBS_SHA256="f9c905e74935c6fe911c7e344e3e89d5fbd2014c1a04650b524b15ce9b5635d1" S6_VERSION="2.15.1.0" S6_SHA256="eab9c46e22b66b16135f9a05ec68a0ea287d9060b84d10defaaa2caad158ab52" EXECLINE_VERSION="2.9.9.2" EXECLINE_SHA256="908ed4db3a6b3a23a205d8fd4cf2a71089156f2aeae0f54656045aafad2dee32" S6RC_VERSION="0.7.0.0" S6RC_SHA256="bf5b8ce0da5a4ee70d642b818b61d9916a7a9b64a457595f388113e54a188688" # CPython: a second interpreter, cross-built here and SHIPPED -- $FF_PYTHON # names it, so Moonraker and klippy run on it. Exists because 3.8.2 has no # _sqlite3. "Bump to latest" is wrong for four of these: # PY_VERSION configure needs a build python of the SAME version, which # payload.sh builds from this same tarball. # OPENSSL_VERSION 3.0.x: no-docs postdates it, and linux-mips32's -mips2 # needs -mips32r2 after it. 3.5 means re-deriving the flags. # SQLITE_* amalgamation tarball; its URL carries SQLITE_YEAR. # XZ_VERSION not 5.6.x -- 5.6.0/5.6.1 are CVE-2024-3094. # EXPAT_TAG libexpat tags with underscores; both spellings in the URL. PY_VERSION="3.13.7" PY_SHA256="6c9d80839cfa20024f34d9a6dd31ae2a9cd97ff5e980e969209746037a5153b2" OPENSSL_VERSION="3.0.15" OPENSSL_SHA256="23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533" SQLITE_VERSION="3460100" SQLITE_YEAR="2024" SQLITE_SHA256="67d3fe6d268e6eaddcae3727fce58fcc8e9c53869bdd07a0c61e38ddf2965071" ZLIB_VERSION="1.3.1" ZLIB_SHA256="9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23" LIBFFI_VERSION="3.4.6" LIBFFI_SHA256="b0dea9df23c863a7a50e825440f3ebffabd65df1497108e5d437747843895a4e" XZ_VERSION="5.4.7" XZ_SHA256="8db6664c48ca07908b92baedcfe7f3ba23f49ef2476864518ab5db6723836e71" BZIP2_VERSION="1.0.8" BZIP2_SHA256="ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269" EXPAT_VERSION="2.6.4" EXPAT_TAG="R_2_6_4" EXPAT_SHA256="fd03b7172b3bd7427a3e7a812063f74754f24542429b634e0db6511b53fb2278" # site-packages: the closure of what the ENABLED Moonraker components and # klippy import, not moonraker-requirements.txt. Sdists only -- a manylinux # wheel is somebody else's x86-64 build. The FILE carries the version. PYPKG_LIST="distro inotify-simple libnacl dbus-fast preprocess-cancellation pyserial pycparser smart-open jinja2 setuptools zipp importlib-metadata tornado markupsafe cffi greenlet lmdb streaming-form-data pillow numpy" PYPKG_DISTRO_FILE="distro-1.9.0.tar.gz" PYPKG_DISTRO_SHA256="2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed" # STAYS AT 1.3.5 though Moonraker 0.11.0 pins ==2.0.1: 2.0.1 declares its # licence the PEP 639 way and needs setuptools>=77 to build, and the # setuptools below is 75.6.0 and pinned for its own reasons. 1.3.5 carries # every name 0.11.0 imports -- INotify(nonblocking=), fileno, add_watch, # rm_watch, read(timeout=), Event, and each flag in WATCH_FLAGS. Nothing on # this printer even reaches them: moonraker.conf sets # `file_system_observer: none`, so the import is all that is asked of it. PYPKG_INOTIFY_SIMPLE_FILE="inotify_simple-1.3.5.tar.gz" PYPKG_INOTIFY_SIMPLE_SHA256="8440ffe49c4ae81a8df57c1ae1eb4b6bfa7acb830099bfb3e305b383005cc128" # reaches libsodium through ctypes, so it is tied to SODIUM_VERSION below PYPKG_LIBNACL_FILE="libnacl-2.1.0.tar.gz" PYPKG_LIBNACL_SHA256="f3418da7df29e6d9b11fd7d990289d16397dc1020e4e35192e11aee826922860" # replaced dbus-next in Moonraker 0.11.0. The recipe sets SKIP_CYTHON=1: the # sdist would otherwise cythonise nine of its modules for speed, and the # python those were generated from ships instead, which keeps this ARCH all PYPKG_DBUS_FAST_FILE="dbus_fast-5.0.22.tar.gz" PYPKG_DBUS_FAST_SHA256="34dc67d7d21a12399828dd13e63b352750580beea54ea7c729e708f2d2905fef" # no [build-system] and no setup.py; pkg/ copies its one file into site-packages PYPKG_PREPROCESS_CANCELLATION_FILE="preprocess_cancellation-0.2.1.tar.gz" PYPKG_PREPROCESS_CANCELLATION_SHA256="e2f1224e1ba1603bdfdbf6937caaf91082dc849e5122e80a5328aa999433ce79" PYPKG_PYSERIAL_FILE="pyserial-3.4.tar.gz" PYPKG_PYSERIAL_SHA256="6e2d401fdee0eab996cf734e67773a0143b932772ca8b42451440cfed942c627" PYPKG_PYCPARSER_FILE="pycparser-2.22.tar.gz" # cffi's only runtime dep PYPKG_PYCPARSER_SHA256="491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6" # imported at module scope by streaming-form-data; not optional PYPKG_SMART_OPEN_FILE="smart_open-6.4.0.tar.gz" PYPKG_SMART_OPEN_SHA256="be3c92c246fbe80ebce8fbacb180494a481a77fcdcb7c1aadb2ea5b9c2bee8b9" PYPKG_JINJA2_FILE="jinja2-3.1.6.tar.gz" PYPKG_JINJA2_SHA256="0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d" # keeps lmdb off its cffi path; also the backend pkg_buildpython installs PYPKG_SETUPTOOLS_FILE="setuptools-75.6.0.tar.gz" PYPKG_SETUPTOOLS_SHA256="8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6" # moonraker/utils/source_info.py imports it at module scope. The backport and # not the 3.13 stdlib importlib.metadata, because that is what upstream writes; # zipp is its one runtime dependency. Both build through setuptools_scm, which # is why PYPKG_HOST_LIST below grew two entries. PYPKG_IMPORTLIB_METADATA_FILE="importlib_metadata-8.7.0.tar.gz" PYPKG_IMPORTLIB_METADATA_SHA256="d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000" PYPKG_ZIPP_FILE="zipp-3.21.0.tar.gz" PYPKG_ZIPP_SHA256="2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4" PYPKG_TORNADO_FILE="tornado-6.4.tar.gz" PYPKG_TORNADO_SHA256="72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee" PYPKG_MARKUPSAFE_FILE="MarkupSafe-2.1.5.tar.gz" PYPKG_MARKUPSAFE_SHA256="d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b" PYPKG_CFFI_FILE="cffi-1.17.1.tar.gz" PYPKG_CFFI_SHA256="1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824" # gcc 7.2 refuses 3.x's designated initializers: pkg/ runs fill-designators.py PYPKG_GREENLET_FILE="greenlet-3.1.1.tar.gz" PYPKG_GREENLET_SHA256="4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467" # LMDB_FORCE_CPYTHON=1; setup.py tests presence, so FORCE_CFFI=0 selects cffi PYPKG_LMDB_FILE="lmdb-1.4.1.tar.gz" PYPKG_LMDB_SHA256="1f4c76af24e907593487c904ef5eba1993beb38ed385af82adb25a858f2d658d" # not 1.13.0: its pregenerated _parser.c calls the pre-3.13 _PyLong_AsByteArray PYPKG_STREAMING_FORM_DATA_FILE="streaming_form_data-1.19.1.tar.gz" PYPKG_STREAMING_FORM_DATA_SHA256="8172dd509a42ac0d1033deb1d13acb68f0cbae7e1492257d13af0922bdc4dd9b" # not 10.3.0: its setup.py cannot be built by any 3.13 (PEP 667 broke it) PYPKG_PILLOW_FILE="pillow-11.0.0.tar.gz" PYPKG_PILLOW_SHA256="72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739" # THE ONE PACKAGE HERE KLIPPY CANNOT START WITHOUT, which is not what a reader # expects of numpy. 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]. # Without this package that is a klippy which never reaches ready -- not a # missing feature. See docs/notes/44-vfa-calibration.md. # # 2.1.3 AND NOT THE NEWEST. 2.1 is the first release with CPython 3.13 support, # so there is no going below it; staying at the bottom of that range is # deliberate, because every release since adds SIMD dispatch machinery that has # no MIPS path and only more ways for a gcc 7.2 to refuse. Cython below is held # at 3.0.x for the matching reason. # # It also builds with meson-python rather than setuptools, which is why # PYPKG_HOST_LIST grew four entries and pkgs/lib.sh grew pkg_mesoncross. PYPKG_NUMPY_FILE="numpy-2.1.3.tar.gz" PYPKG_NUMPY_SHA256="aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761" # Host-side PEP 517 backends. THESE NEVER SHIP: pkg_pywheel builds with # --no-build-isolation, so each must already be in work/.py-host. # ORDER IS INSTALL ORDER: pkg_buildpython pip-installs each with --no-deps # against no index, so a backend must come after whatever builds it. flit-core # builds packaging; setuptools_scm imports packaging at build time. PYPKG_HOST_LIST="flit-core poetry-core packaging setuptools-scm meson pyproject-metadata meson-python cython" PYPKG_FLIT_CORE_FILE="flit_core-3.10.1.tar.gz" # jinja2's backend PYPKG_FLIT_CORE_SHA256="66e5b87874a0d6e39691f0e22f09306736b633548670ad3c09ec9db03c5662f7" PYPKG_POETRY_CORE_FILE="poetry_core-1.9.1.tar.gz" # libnacl's, dbus-fast's PYPKG_POETRY_CORE_SHA256="7a2d49214bf58b4f17f99d6891d947a9836c9899a67a5069f52d7b67217f61b8" PYPKG_PACKAGING_FILE="packaging-24.2.tar.gz" # setuptools_scm's dep PYPKG_PACKAGING_SHA256="c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" PYPKG_SETUPTOOLS_SCM_FILE="setuptools_scm-8.1.0.tar.gz" # zipp's, importlib's PYPKG_SETUPTOOLS_SCM_SHA256="42dea1b65771cba93b7a515d65a65d8246e560768a66b9106a592c8e7f26c8a7" # --- numpy's four, and the order among them is not alphabetical by accident. # # meson-python IS SELF-HOSTING: its pyproject declares backend-path = ['.'] and # builds itself with the mesonpy in its own tree, so installing it RUNS meson # and ninja. That is why ninja-build is in docker/Dockerfile.build and why # these three must precede it -- meson because mesonpy execs it, # pyproject-metadata and packaging because mesonpy imports them. Reorder this # and pkg_buildpython fails on a backend that cannot build itself, which reads # as a network problem and is not one. # # meson FROM PyPI AND NOT FROM apt, unlike ninja. Debian bookworm ships 1.0.1 # and numpy's meson.build asks for >=1.2.99, so the distro's is simply too old # -- and a vendored sdist is a pinned hash where an apt package is a moving # target. ninja earns the exception the way libarchive-dev does: it is a # program meson execs, not a module anything imports, and no pin of ours would # change what it emits. PYPKG_MESON_FILE="meson-1.7.0.tar.gz" PYPKG_MESON_SHA256="08efbe84803eed07f863b05092d653a9d348f7038761d900412fddf56deb0284" PYPKG_PYPROJECT_METADATA_FILE="pyproject_metadata-0.9.0.tar.gz" PYPKG_PYPROJECT_METADATA_SHA256="8511c00a4cad96686af6a6b4143433298beb96105a9379afdc9b0328f4f260c9" PYPKG_MESON_PYTHON_FILE="meson_python-0.17.1.tar.gz" PYPKG_MESON_PYTHON_SHA256="efb91f69f2e19eef7bc9a471ed2a4e730088cc6b39eacaf3e49fc4f930eb5f83" # HELD AT 3.0.x DELIBERATELY: Cython 3.1 does not build numpy below 2.2, and # numpy is pinned at 2.1.3 above. numpy's meson.build wants >= 3.0.6. PYPKG_CYTHON_FILE="cython-3.0.11.tar.gz" PYPKG_CYTHON_SHA256="7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff" # dlopened by libnacl, so it must be shared -- our one .so in $MODDIR/lib. SODIUM_VERSION="1.0.20" SODIUM_SHA256="ebb65ef6ca439333c2bb41a0c1990587288da07f6c7fd07cb3a18cc18d30ce19" # sntpd -- the NTP client. THE PRINTER HAS NO RTC AND NO BATTERY, so every # boot starts at whatever the kernel calls zero and stays there until # something asks the network. Nothing on the stock rootfs can ask: its busybox # is v1.31.1 built WITHOUT the ntpd applet (measured -- it has date, hwclock, # rdate and crond, and rdate is RFC 868, not NTP). # # sntpd rather than ntpd/chrony/OpenNTPd: it is a fork of Larry Doolittle's # ntpclient, one small daemon with no privsep user, no chroot and no runtime # config file to ship -- and it keeps running with the network down instead of # exiting, which is the only behaviour that matters on a machine whose wifi # comes up minutes after the service does. SNTPD_VERSION="3.2" SNTPD_SHA256="15852f86b319c52134e5ffbfa43d38fa0b755a9a8ab18e3b17dfa3e84e000763" # moonraker-timelapse. A COMMIT, and the head of main as of 2026-08-30: the # one tag upstream ever cut is v0.0.1 of Oct 2021, two years OLDER than this, # so pinning "the latest release" would drop hyperlapse, the configurable # delayed_gcode interval and the webcam-database lookup the component needs. TIMELAPSE_VERSION="c7fff11e542b95e0e15b8bb1443cea8159ac0274" TIMELAPSE_DATE="2023-12-16" TIMELAPSE_SHA256="efbf24ac24309440761425c9e873772882727e5f7513c6a3fc6d04601d02ea76" # x264 and ffmpeg, ours, for the timelapse render. FlashForge ships both, but # its ffmpeg is --disable-everything with no hflip/vflip/transpose/rotate, so # every rotated or flipped webcam fails to render -- see pkgs/3rdparty/ffmpeg. # # x264 is a SNAPSHOT because upstream cuts no releases; this is the last # "stable" one download.videolan.org carries. X264_BUILD 157. X264_VERSION="snapshot-20191217-2245-stable" X264_SHA256="b2495c8f2930167d470994b1ce02b0f4bfb24b3317ba36ba7f112e9809264160" # ffmpeg 4.x, not 5/6/7: gcc 7.2 is what this printer's ABI has a toolchain # for, and the newer branches assume a newer compiler. 4.4.5 is the last 4.4. FFMPEG_VERSION="4.4.5" FFMPEG_SHA256="f9514e0d3515aee5a271283df71636e1d1ff7274b15853bcd84e144be416ab07" # --- apk-tools: the package manager, and the packager (85-packaging.md). # BY COMMIT: the upstream forge regenerates tag archives, so a .tar.gz sha256 # is not stable enough to pin against. The sha of the tree is -- which is also # what lets bin/fetch-assets.sh clone this from a mirror rather than from # gitlab.alpinelinux.org, a host that refuses CI runners. # # CARRIED PATCH, and the standing cost of this choice: apk resolves its # database, world file and config RELATIVE TO --root, # and on this printer / is a read-only squashfs (measured -- /lib/apk and # /etc/apk cannot be created). pkgs/3rdparty/apk-tools/prefix.patch makes the # database root default to $MODDIR while files still extract at /, which is # what opkg got from a compile-time VARDIR for free. APK_TOOLS_VERSION="3.0.7" APK_TOOLS_COMMIT="522171e05c72c8a0dd2a9392f053c89196fbdb9b"