# creator5-fw-builder — build configuration # Edit paths to match your machine, then run `make build`. # ---- identity of the package you are building ------------------------------- MOD_NAME=anvil # goes into the .tgz filename MOD_VER="" # empty = today's UTC date, e.g. 20260823. # Pin it to rebuild an old release, or for a # second release on the same day (20260823b). # ---- which printer is this for? -------------------------------------------- # Creator5Pro / 0029 or Creator5 / 0028 # Find it on the printer: Settings -> About, or in # /usr/data/firmwareRes/config/general.json ("machineName"). # # This MUST match the model the stock package was built for. A package's # runFirmwareExe.sh carries its own MACHINE=/PID= gate and refuses to install # on the other model, so a Pro cannot be recovered or modded with a non-Pro # package (and vice versa). TARGET_MACHINE=Creator5Pro # Override for one command: MODEL=Creator5 make build # Build both at once: make release # ---- inputs ----------------------------------------------------------------- # THERE ARE NO PATHS TO EDIT HERE ANY MORE. Every source this build reads is # downloaded into vendor/ by bin/fetch-assets.sh, pinned by name and sha256 in # versions.env -- the stock FlashForge OTA package included, which used to be # the one file you had to go and find yourself. `make build` fetches what it # needs; `make vendor` fetches the lot. # # The stock packages are ONE PER MODEL and not interchangeable: each carries a # different firmwareExe and refuses to install on the other model. The one # matching TARGET_MACHINE (or MODEL=) is selected automatically. # # Set one of these ONLY to build against firmware you downloaded yourself. # Unlike HELIX_TGZ below, a path you put here is never checksummed and never # overwritten -- it is 93MB you fetched by hand, and this build will not # replace it with one you did not ask for. That also means nothing verifies it: # it is your file and your problem. #STOCK_TGZ_CREATOR5PRO="/path/to/Creator5Pro-1.9.7-1.2.9-20260810.tgz" #STOCK_TGZ_CREATOR5="/path/to/Creator5-1.9.7-1.2.9-20260810.tgz" # Set this only to force one specific package regardless of model. It does not # suppress the download above; point the per-model variable at your file # instead if that is what you want. STOCK_TGZ="" # KLIPPER_FORK USED TO BE HERE and pointed the build at a local checkout of # the fork. It is gone: the Klipper build is pkg/klipper now, and a recipe # names its source exactly once -- a checkout beside the pinned tarball is the # second source that rule forbids, and the one that let a release ship a tree # nobody had built. To build your own fork, put its tarball in vendor/ and # re-pin KLIPPER_VERSION and KLIPPER_SHA256 in versions.env; the sha is then # the same guarantee every other source in this repo carries. # The toolchanger mod (klippy-extras + configs + helixscreen db entry) used to # be a TOOLCHANGE= path to a creator5-toolchange checkout. It now lives in this # repo under payload/klipper/, so there is nothing to set. BUILD_TOOLCHANGE=0 # here still turns it off. # Mainsail, Fluidd, the HelixScreen build for the Creator 5 (MIPS static) and # Moonraker are NOT set here. They are downloaded on demand into vendor/ by # bin/fetch-assets.sh, pinned by version and sha256 in versions.env, so the # repo carries no binaries. Set any of these ONLY to build against your own # local copy. # NOTE: the path is still checksummed against versions.env, and on a mismatch # fetch-assets.sh OVERWRITES it with the pinned release -- SKIP does not save # you, it re-downloads too. To build against your own file, also put ITS # sha256 in versions.env; only an exact match is left alone ("cached"): #HELIX_TGZ="/path/to/helixscreen-creator5-v0.99.118.tar.gz" #MAINSAIL_ZIP="/path/to/mainsail.zip" #FLUIDD_ZIP="/path/to/fluidd.zip" #MOONRAKER_TGZ="/path/to/moonraker-v0.9.3.tar.gz" # ---- optional extras -- leave empty to skip that feature --------------------- # The ONE input with no pinned source, because it has no source at all: a # busybox someone built elsewhere, for the applets FlashForge left out. Nothing # needs it (the printer's own busybox works), so `make vendor` has nothing to # fetch and an empty value simply leaves the package out of the feed. See # pkgs/3rdparty/busybox/build.sh. BUSYBOX_BIN="" # The private key the package feed is signed with, or empty for an unsigned # feed. A PATH, never a key: config.env is gitignored and this points outside # the repo, so the key is never a thing the repository can leak. # # ./bin/apk-keygen.sh ~/.anvil/anvil.rsa makes the pair # APK_SIGN_KEY="/home/you/.anvil/anvil.rsa" # # EMPTY IS A WORKING CONFIGURATION, deliberately: `make packages` has to run on # a bare checkout with no secrets, which is what keeps the packaging lane a # gate in CI. An unsigned feed installs with --allow-untrusted, exactly as it # does today; a signed one does not need the flag and refuses a package whose # signature does not match. RSA or Ed25519 only -- ECDSA signatures are # randomised and two builds of one tree would stop being byte-identical. # # The PUBLIC half is generated beside the private one and ships in anvil-core, # so a printer can verify what it is offered. Losing the private key means # printers stop accepting new packages until one is reflashed by .tgz. # # The DIRECTORY holding the key is bind-mounted read-only into the build # container by the Makefile, which is what lets this point outside the # checkout at all. Both halves must live in it, named as apk-keygen.sh leaves # them, and it must be a path docker is allowed to mount. # # In CI the same value comes from a repository secret rather than from here: # see the signing section of docs/notes/85-packaging.md. APK_SIGN_KEY="" # Where that feed is SERVED, and the URL every printer this build produces will # ask for updates. It ships inside anvil-core as $MODDIR/etc/apk/repositories, # so it is baked into the .tgz a printer installs and cannot be changed later # except by installing an anvil-core that names somewhere else. # # LEAVE IT UNSET unless you are running your own feed. The default is # Reforge's own host, and a printer only accepts packages signed with the key # whose public half is in the same build -- so pointing a build at somebody # else's URL produces a printer that fetches packages it will then refuse. # Change this and APK_SIGN_KEY together or neither. # # The layout it names is what ./bin/publish-feed.sh writes: # $FEED_URL//anvil.adb the index # $FEED_URL//-.apk #FEED_URL="http://reforge.8941973.xyz/apk" # ---- what the installed image does at boot ---------------------------------- # NOTHING, from here. There is no build-time knob for boot behaviour any more, # and no runtime config file on the printer either: /usr/data/anvil/anvil.conf # is gone. Every component that is installed runs, and the settings that used # to live in that file -- the splash, the startup wait and its timeout, the # first-boot import, the camera resolution, the nice values -- are now stated # once each, in the service that uses them, under # pkgs/anvil-core/payload/etc/s6-rc/source/. # # A printer that should not run a component does not have it: leave it out of # the build with the BUILD_* flags, or `apk del` it on the printer. What # there is no longer a way to ask for is a component that is installed and # switched off -- a half-installed mod nobody chose on purpose, that everything # downstream had to keep a second answer for. # # The BUILD_* flags that decide what goes INTO a package (BUILD_TOOLCHANGE, # BUILD_MAINSAIL, BUILD_FLUIDD, BUILD_MOONRAKER, BUILD_HELIX) are not set # here: bin/common.sh defaults them to the full firmware, and setting one in # this file overrides that. Only touch them if you want a piece left out. # ---- root login shipped in the image --------------------------------------- # This is the whole "enable ssh" feature. The stock rootfs already runs # dropbear from /etc/init.d/S50dropbear, so port 22 is ALREADY open on a # stock printer -- there is simply no published root password. # # Empty = the INSTALLER picks a random password on the printer -- on the # FIRST install only, updates keep the one the machine already has -- and # writes it to anvil-password.txt on the USB stick you flashed from. Every # machine gets a different one, which a hash baked into a shared package # never could. # Set one here to choose your own: make passwd # (it prompts, and runs inside the build image -- the same python everywhere, # where a host openssl may lack `passwd -6` entirely) ROOT_PW_HASH="" # ---- crypto (from /usr/prog/bin/unTar on the printer) ----------------------- FF_KEY='FFP0331&*%root' # ---- the printer replica ----------------------------------------------------- # Nothing here. The replica's settings -- the factory image, the partition # sizes, a prebuilt printer image -- live in test.env, because they exist only # for the tests and must never reach a printer: # # cp test.env.example test.env