mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-23 05:42:17 -05:00
The probe profile was a bring-up aid. It set BUILD_APPLY=0, reinstalled the stock component byte-for-byte and wrote a report to the stick, so you could prove the update chain worked on your own machine -- the filename glob, the DES3 key, the md5 gate, run.sh execution -- before flashing anything that changed a file. That rehearsal has served its purpose. With it gone there was exactly one profile left, so the whole PROFILE indirection goes too: profiles/ is deleted and its six BUILD_* flags are plain defaults in bin/common.sh, which also means config.env now overrides them instead of being silently overridden. make default folds into make build; all-profiles and RECOVERY_PROFILE are gone with it. What is NOT gone is the undo button: flashing the stock FlashForge package still restores every file the mod touches, and case-recovery.sh still proves it. What is gone is the dry run. Note the loss: PROG_MB/DATA_MB used to come out of the probe report. The docs now point at df -h over ssh, which you only have after a successful flash.
257 lines
11 KiB
Makefile
257 lines
11 KiB
Makefile
# creator5-custom-firmware
|
|
#
|
|
# Nothing runs on your machine except Docker. Every target below executes
|
|
# inside the pinned build image (docker/Dockerfile.build); the docker socket
|
|
# is mounted through so the simulation targets can start sibling containers.
|
|
#
|
|
# make build build the firmware package
|
|
# make test full brick-safety suite
|
|
# make shell interactive shell in the build container
|
|
#
|
|
# Escape hatch: LOCAL=1 make <target> runs the scripts directly on the host.
|
|
|
|
# Packages carry only the software component by default: the stock installer
|
|
# skips absent components, so the kernel and the MCU/board firmware are left
|
|
# alone. FULL=1 carries all four (and reflashes the MCU).
|
|
FULL ?=
|
|
PACKARGS = $(if $(FULL),--full,)
|
|
DOCKER ?= docker
|
|
IMAGE ?= creator5-fw-build
|
|
LOCAL ?=
|
|
|
|
DOCKER_SOCK := /var/run/docker.sock
|
|
|
|
# The repo is mounted AT ITS REAL HOST PATH, not at /src. The test targets
|
|
# start sibling containers through the mounted docker socket, and those are
|
|
# created by the host daemon -- which resolves -v paths on the HOST. If the
|
|
# build container saw the repo as /src it would ask the daemon to mount a
|
|
# /src that does not exist there, and the sibling would get empty
|
|
# directories. Keeping the path identical on both sides avoids that entirely.
|
|
# config.env usually points at a stock package OUTSIDE this repo, so the
|
|
# directory holding it must be mounted too. Override when yours lives
|
|
# elsewhere: make ASSET_ROOT=/path/to/parent build
|
|
ASSET_ROOT ?= $(firstword $(wildcard /mnt/c /Users /home))
|
|
|
|
# Two runners, because the two lanes need different things:
|
|
#
|
|
# RUN builds the thing you flash. No docker socket, no replica settings.
|
|
# RUNSIM runs the test replica. It starts SIBLING containers through the
|
|
# mounted socket, so it needs that plus the replica's own knobs.
|
|
#
|
|
# Keeping them apart is the point of the split: a build cannot reach the docker
|
|
# daemon, and test-only variables never enter a build.
|
|
DOCKER_BASE = $(DOCKER) run --rm -i \
|
|
-v "$(CURDIR)":"$(CURDIR)" -w "$(CURDIR)" \
|
|
$(if $(ASSET_ROOT),-v "$(ASSET_ROOT)":"$(ASSET_ROOT)",) \
|
|
-e MODEL -e TARGET_MACHINE -e CONFIG_ENV -e ALLOW_STALE_CHELPER
|
|
|
|
ifeq ($(LOCAL),)
|
|
RUN = $(DOCKER_BASE) $(IMAGE)
|
|
RUNSIM = $(DOCKER_BASE) \
|
|
-v $(DOCKER_SOCK):$(DOCKER_SOCK) \
|
|
-e TEST_ENV -e PRINTER_IMAGE -e REAL_PKG -e SIM_IMAGE \
|
|
-e SIM_VERBOSE -e PROG_MB -e DATA_MB -e PROG_DUMP -e REQUIRE_PRINTER_SIM \
|
|
$(IMAGE)
|
|
RUNTTY = $(subst --rm -i,--rm -it,$(RUNSIM))
|
|
else
|
|
RUN =
|
|
RUNSIM =
|
|
RUNTTY =
|
|
endif
|
|
|
|
.DEFAULT_GOAL := help
|
|
.PHONY: help image shell build vendor \
|
|
rootfs verify test test-lint test-install test-applets \
|
|
printer-image printer-image-push \
|
|
test-recovery test-ui test-mcu test-ash test-abi test-chelper test-macros test-chamber test-basecfg test-model release clean distclean
|
|
|
|
help:
|
|
@echo 'creator5-custom-firmware -- everything runs in Docker'
|
|
@echo
|
|
@echo 'Build (see docs/hardware-testing.md before you flash):'
|
|
@echo ' make build the firmware Klipper fork, toolchanger, Mainsail,'
|
|
@echo ' ssh and HelixScreen'
|
|
@echo ' make release build BOTH models into dist/'
|
|
@echo
|
|
@echo 'Models: packages are model-specific and refuse to install on the'
|
|
@echo 'other one. MODEL=Creator5 make build builds the non-Pro variant.'
|
|
@echo
|
|
@echo 'Recovery: keep a copy of the STOCK FlashForge .tgz on a spare stick.'
|
|
@echo 'Flashing it restores every file the mod touches (see make test-recovery).'
|
|
@echo
|
|
@echo 'Test:'
|
|
@echo ' make test everything below'
|
|
@echo ' make test-lint brick-risk lint'
|
|
@echo ' make test-install end-to-end: USB stick -> update -> reboot'
|
|
@echo ' make test-recovery install mod -> flash stock -> back to stock'
|
|
@echo ' make test-ui UI startup, crash protection, SAFE-MODE'
|
|
@echo ' make test-mcu ff-mcu-bringup.py runs on the printer own python'
|
|
@echo ' make test-model both models gated + firmware correct'
|
|
@echo ' make test-applets every command the payload uses exists on the printer'
|
|
@echo ' make test-ash parse the payload with the printer own busybox'
|
|
@echo ' make test-abi MIPS ELF ABI checks'
|
|
@echo ' make test-chelper c_helper.so exports everything klippy declares'
|
|
@echo ' make test-macros the ff-*.cfg gcode macros parse as Jinja'
|
|
@echo ' make test-chamber the chamber heater is off on the Creator 5'
|
|
@echo ' make test-basecfg our printer.base.cfg still matches the stock one'
|
|
@echo
|
|
@echo 'test-install, test-recovery, test-ui, test-mcu and test-ash run inside'
|
|
@echo 'a replica of the printer: the real rootfs.squashfs under qemu-mipsel, with'
|
|
@echo '/usr/prog installed by FlashForge own updater. test-install goes the'
|
|
@echo 'whole way -- the package sits on a real FAT filesystem at /dev/sda1'
|
|
@echo 'and the printer own app_startup.sh finds it, installs it, and boots.'
|
|
@echo 'They need make rootfs first (or PRINTER_IMAGE), which needs the'
|
|
@echo 'stock package.'
|
|
@echo
|
|
@echo 'Other:'
|
|
@echo ' make vendor download Mainsail + HelixScreen into vendor/'
|
|
@echo ' make rootfs extract the real printer rootfs (enables test-ash)'
|
|
@echo ' make image build the build container'
|
|
@echo ' make shell shell inside it'
|
|
@echo ' make clean | distclean'
|
|
@echo
|
|
@echo 'Packages carry only the software component; the kernel and MCU are'
|
|
@echo 'left untouched. FULL=1 make <target> carries all four components.'
|
|
@echo
|
|
@echo 'Config: config.env is the BUILD config (what ships). test.env holds'
|
|
@echo 'the replica settings, which never reach a printer. Copy the .example'
|
|
@echo 'of each. LOCAL=1 make <target> runs on the host instead of in Docker.'
|
|
|
|
image:
|
|
@$(DOCKER) build -q -t $(IMAGE) -f docker/Dockerfile.build docker >/dev/null && echo "image $(IMAGE) ready"
|
|
|
|
config.env:
|
|
@echo 'no config.env -- copy the example and edit the paths:'; \
|
|
echo ' cp config.env.example config.env'; exit 1
|
|
|
|
shell: image
|
|
@$(RUNTTY) bash
|
|
|
|
# ===========================================================================
|
|
# BUILD LANE -- produces the package you flash. Reads config.env, ships
|
|
# payload/ and assets/, and touches nothing under test/.
|
|
# ===========================================================================
|
|
|
|
# Mainsail and HelixScreen are not vendored in the repo. bin/build.sh fetches
|
|
# what the build needs; this target pre-fetches everything, and is a
|
|
# no-op once vendor/ holds files with the sha256 that versions.env pins.
|
|
vendor: image config.env
|
|
@$(RUN) ./bin/fetch-assets.sh --all
|
|
|
|
build: image config.env
|
|
@$(RUN) ./bin/build.sh $(PACKARGS)
|
|
|
|
# One package per model, collected in dist/. They cannot share content: the
|
|
# two stock packages ship different firmwareExe binaries.
|
|
release: image config.env
|
|
@rm -rf dist && mkdir -p dist
|
|
@for m in Creator5Pro Creator5; do \
|
|
echo "=== $$m ==="; \
|
|
MODEL=$$m $(RUN) ./bin/build.sh $(PACKARGS) || exit 1; \
|
|
MODEL=$$m $(RUN) ./bin/verify.sh || exit 1; \
|
|
cp work/out/$$m-*.tgz dist/ || exit 1; \
|
|
done
|
|
@echo; echo "dist/:"; ls -lh dist | awk 'NR>1{print " "$$9" "$$5}'
|
|
@echo; echo "Each file installs ONLY on the model in its name."
|
|
|
|
verify: image
|
|
@$(RUN) ./bin/verify.sh
|
|
|
|
# ===========================================================================
|
|
# TEST LANE -- never ships. Reads test.env for the replica settings; the only
|
|
# targets allowed to reach the docker daemon ($(RUNSIM)).
|
|
# ===========================================================================
|
|
|
|
# The replica needs this: rootfs.squashfs is the printer's real userland and
|
|
# it only exists inside the stock package's kernel component.
|
|
rootfs: image config.env
|
|
@$(RUN) ./bin/unpack.sh >/dev/null
|
|
@$(RUN) ./test/extract-rootfs.sh
|
|
|
|
test: image
|
|
@$(RUNSIM) ./test/run-tests.sh
|
|
|
|
# A Docker image that IS the printer: real rootfs, real /usr/prog and
|
|
# /usr/data, with the stock package already installed on top of them.
|
|
#
|
|
# Both of those are per-run costs it removes. Measured on this repo:
|
|
#
|
|
# unpacking the 182MB factory image 22s every run
|
|
# installing the stock package under qemu 37s every run
|
|
# with the image 0.7s once, at build time
|
|
#
|
|
# make printer-image build (one image serves both models)
|
|
# make printer-image-push build and push to Docker Hub
|
|
#
|
|
# Point PRINTER_IMAGE in test.env at it to use it.
|
|
#
|
|
# The image contains proprietary FlashForge firmware.
|
|
printer-image: image
|
|
@$(RUNSIM) ./test/build-printer-image.sh
|
|
|
|
printer-image-push: image
|
|
@$(RUNSIM) ./test/build-printer-image.sh --push
|
|
|
|
test-lint: image
|
|
@$(RUN) ./test/lint-danger.sh payload payload/init.d
|
|
|
|
test-model: image
|
|
@$(RUN) ./test/test-model-gate.sh
|
|
|
|
test-ash: image
|
|
@$(RUN) ./test/test-ash-conformance.sh
|
|
|
|
test-abi: image
|
|
@$(RUN) ./test/test-abi.sh
|
|
|
|
test-chelper: image
|
|
@$(RUN) python3 ./test/test-chelper.py
|
|
|
|
test-macros: image
|
|
@$(RUN) python3 ./test/test-macros.py
|
|
|
|
test-chamber: image
|
|
@$(RUN) python3 ./test/test-chamber.py
|
|
|
|
test-basecfg: image
|
|
@$(RUN) python3 ./test/test-base-cfg.py
|
|
|
|
test-applets: image
|
|
@$(RUN) python3 ./test/test-applets.py
|
|
|
|
test-ui: image
|
|
@$(RUNSIM) ./test/sim-ui-fallback.sh
|
|
|
|
test-mcu: image
|
|
@$(RUNSIM) ./test/sim-mcu-bringup.sh
|
|
|
|
# Packages land in dist/ after `make release` and in work/out after a single
|
|
# build (pack.sh clears work/out each run, so only the last model survives
|
|
# there). Look in both.
|
|
test-install: image
|
|
@$(RUNSIM) bash -c 'pkg=$$(ls -1 dist/$(or $(MODEL),Creator5Pro)-*.tgz work/out/$(or $(MODEL),Creator5Pro)-*.tgz 2>/dev/null | head -1); \
|
|
[ -n "$$pkg" ] || { echo "build a package first: make build (or make release)"; exit 1; }; \
|
|
echo "package: $$pkg"; ./test/sim-install.sh "$$pkg"'
|
|
|
|
# Recovery = flash the stock package you already have. This proves it works.
|
|
#
|
|
# It builds its own package rather than reusing whatever is lying around: the
|
|
# test is only meaningful against a package that really does replace the UI,
|
|
# and whatever is in work/out may be anything.
|
|
test-recovery: image config.env
|
|
@MODEL=$(or $(MODEL),Creator5Pro) $(RUNSIM) bash -c '. ./bin/common.sh; \
|
|
./bin/build.sh $(PACKARGS) >/dev/null || exit 1; \
|
|
m=$$(ls -1 work/out/$$TARGET_MACHINE-*.tgz 2>/dev/null | head -1); \
|
|
[ -n "$$m" ] || { echo "no package built for $$TARGET_MACHINE"; exit 1; }; \
|
|
[ -f "$$STOCK_TGZ" ] || { echo "no stock package for $$TARGET_MACHINE"; exit 1; }; \
|
|
echo "mod: $$m"; echo "stock: $$STOCK_TGZ"; \
|
|
./test/sim-roundtrip.sh "$$m" "$$STOCK_TGZ"'
|
|
|
|
clean:
|
|
@rm -rf work/stage work/out work/uninst work/uninst-sw work/modpayload
|
|
@echo cleaned
|
|
|
|
distclean:
|
|
@rm -rf work
|
|
@echo "removed work/ (including the extracted rootfs)"
|