# When this product's build inputs change, mirror them into the `paths:` filter # of .github/workflows/start-wrt.yaml (see root AGENTS.md "Coupled changes"). STARTWRT_DIR := projects/start-wrt STARTWRT_RUST_ARCH := riscv64gc STARTWRT_ARCH := riscv64 STARTWRT_BIN := target/$(STARTWRT_RUST_ARCH)-unknown-linux-musl/$(PROFILE)/startwrt STARTWRT_WEB_DIST := $(STARTWRT_DIR)/web/dist/startwrt/browser/immutable-assets.txt STARTWRT_WEB_CONFIG := $(STARTWRT_DIR)/web/config.json STARTWRT_BINDINGS_DIR := $(STARTWRT_DIR)/web/src/app/services/api STARTWRT_BINDINGS := $(STARTWRT_BINDINGS_DIR)/bindings.ts $(STARTWRT_BINDINGS_DIR)/bindings.schemas.ts $(STARTWRT_BINDINGS_DIR)/events.ts $(STARTWRT_BINDINGS_DIR)/events.schemas.ts STARTWRT_GIT_HASH_FILE := $(STARTWRT_DIR)/build/env/GIT_HASH.txt # Refresh GIT_HASH.txt on every make invocation (parse-time side-effect) so the # stamp tracks HEAD; the file is then a prereq of config.json below, forcing a # re-stamp whenever HEAD moves. (check-git-hash.sh rewrites the file only when # the hash actually changes, so this is a no-op when HEAD is unchanged.) _ := $(shell ./$(STARTWRT_DIR)/build/env/check-git-hash.sh) STARTWRT_RUST_SRC := $(call ls-files, $(STARTWRT_DIR)/backend) # Shared crates the backend path-depends on (see backend/ctrl/Cargo.toml): # start-core (aliased `startos`, covered with patch-db by CORE_SRC from # build/common.mk), plus rpc-toolkit and imbl-value. Without these prereqs a # shared-crate edit leaves `make start-wrt`/`start-wrt-update` with a stale binary. STARTWRT_SHARED_RUST_SRC := $(CORE_SRC) STARTWRT_WEB_SRC := $(call ls-files, $(STARTWRT_DIR)/web) STARTWRT_OPENWRT := $(STARTWRT_DIR)/openwrt STARTWRT_IMAGE_DIR := $(STARTWRT_OPENWRT)/bin/targets/spacemit # Release-asset basename, following the startos convention from # build/env/basename.sh (--_) — composed # here from start-wrt's own stamps rather than by calling basename.sh, which # reads StartOS's PLATFORM/ENVIRONMENT/GIT_HASH build state and a manifest path # that doesn't exist for start-wrt. The version sed matches the "Determine # version" step in .github/workflows/start-wrt.yaml (same manifest, same # anchored pattern); the hash comes from the parse-time-refreshed stamp above # (truncation to 7 chars drops any -modified marker, as basename.sh does). STARTWRT_VERSION := $(shell sed -n 's/^version = "\([^"]*\)".*/\1/p' $(STARTWRT_DIR)/backend/ctrl/Cargo.toml | head -1) STARTWRT_SHORT_HASH := $(shell head -c 7 $(STARTWRT_GIT_HASH_FILE)) STARTWRT_BASENAME := startwrt-$(STARTWRT_VERSION)-$(STARTWRT_SHORT_HASH)_spacemit-k1 # OpenWrt's own output names (what `make -C openwrt` produces)… STARTWRT_SDCARD_SRC := openwrt-spacemit-k1-sbc-bananapi-f3-squashfs-sdcard.img STARTWRT_SYSUPGRADE_SRC := openwrt-spacemit-k1-sbc-bananapi-f3-squashfs-sysupgrade.img.gz # …renamed on copy into results/ to the release-asset names, gzipping the sdcard # image on the way (OpenWrt gzips the sysupgrade image itself, but leaves the # sdcard image raw — CONFIG_TARGET_IMAGES_GZIP is off). Keep the # -sdcard.img.gz / -sysupgrade.img.gz endings: the top-level # scripts/manage-release.sh `wrt` kind (release_files + the slot-inference # hardlinks in cmd_register) matches on those suffixes. STARTWRT_SDCARD_NAME := $(STARTWRT_BASENAME)-sdcard.img.gz STARTWRT_SYSUPGRADE_NAME := $(STARTWRT_BASENAME)-sysupgrade.img.gz STARTWRT_IMAGES := results/$(STARTWRT_SDCARD_NAME) results/$(STARTWRT_SYSUPGRADE_NAME) # Remote deploy target (binary only — web UI is embedded in the binary). STARTWRT_REMOTE ?= root@192.168.0.1 .PHONY: start-wrt start-wrt: $(STARTWRT_BIN) $(STARTWRT_BIN): $(STARTWRT_RUST_SRC) $(STARTWRT_SHARED_RUST_SRC) Cargo.toml Cargo.lock $(STARTWRT_WEB_DIST) \ $(addprefix $(STARTWRT_DIR)/build/,build-rust.sh builder-alias.sh zigcc-k1.sh zigcxx-k1.sh verify-isa.sh) ARCH=$(STARTWRT_ARCH) RUST_ARCH=$(STARTWRT_RUST_ARCH) PROFILE=$(PROFILE) ./$(STARTWRT_DIR)/build/build-rust.sh @touch $(STARTWRT_BIN) define STARTWRT_GENERATE_BINDINGS bash $(STARTWRT_DIR)/build/generate-bindings.sh $(STARTWRT_BINDINGS) npm exec -- prettier --config .prettierrc.json -w $(STARTWRT_BINDINGS) endef .PHONY: start-wrt-rpc-bindings start-wrt-rpc-bindings-check start-wrt-rpc-bindings: node_modules/.package-lock.json $(STARTWRT_GENERATE_BINDINGS) start-wrt-rpc-bindings-check: node_modules/.package-lock.json $(STARTWRT_GENERATE_BINDINGS) @if [ -n "$$(git status --porcelain -- $(STARTWRT_BINDINGS))" ]; then \ echo "StartWRT bindings are out of date — run 'make start-wrt-rpc-bindings' and commit the result:"; \ git --no-pager diff --stat -- $(STARTWRT_BINDINGS); git status --porcelain -- $(STARTWRT_BINDINGS); \ exit 1; \ fi $(STARTWRT_WEB_DIST): $(STARTWRT_WEB_SRC) $(STARTWRT_BINDINGS) $(WEB_SHARED_SRC) $(IMMUTABLE_ASSETS_GENERATOR) .angular/.updated $(STARTWRT_WEB_CONFIG) npm --prefix . run build:wrt touch $(STARTWRT_WEB_DIST) # Prod config: useMocks=false + gitHash stamped from the product's own # build/env/GIT_HASH.txt (independent of the monorepo-root stamp). GIT_HASH.txt # is a prereq so config.json is re-stamped whenever HEAD moves; it's refreshed # at parse time via the $(shell ...) above. $(STARTWRT_WEB_CONFIG): $(STARTWRT_GIT_HASH_FILE) $(STARTWRT_DIR)/web/config-sample.json $(STARTWRT_DIR)/web/update-config.sh ./$(STARTWRT_DIR)/web/update-config.sh # Run start-wrt's Rust unit tests (startwrt-core + uciedit), package-scoped and # containerized — mirrors start-core-test. See build/run-tests.sh. .PHONY: start-wrt-test start-wrt-test: $(STARTWRT_RUST_SRC) $(ENVIRONMENT_FILE) ./$(STARTWRT_DIR)/build/run-tests.sh # --- OpenWrt image (HEAVY) --- # Tree prep + feeds/config/download. openwrt/ is a disposable, gitignored # build workspace (no submodule, no git repo inside): openwrt-setup.sh rebuilds # it from the sha256-pinned upstream release tarball (build/openwrt-version), # applies the Start9 delta (openwrt-patches/ + openwrt-overlay/), then runs # feeds/config/download. Re-runs whenever the pin, patches, overlay, feeds, or # diffconfig change. .PHONY: start-wrt-openwrt-setup start-wrt-openwrt-setup: $(STARTWRT_OPENWRT)/.config $(STARTWRT_OPENWRT)/.config: $(STARTWRT_DIR)/build/openwrt.diffconfig $(STARTWRT_DIR)/build/feeds.conf \ $(STARTWRT_DIR)/build/openwrt-version $(STARTWRT_DIR)/build/openwrt-setup.sh \ $(call ls-files, $(STARTWRT_DIR)/openwrt-patches) $(call ls-files, $(STARTWRT_DIR)/openwrt-overlay) ./$(STARTWRT_DIR)/build/openwrt-setup.sh # Stage the binary + UCI configs + init scripts into openwrt/files/. .PHONY: start-wrt-stage start-wrt-stage: $(STARTWRT_OPENWRT)/files/.staged $(STARTWRT_OPENWRT)/files/.staged: $(STARTWRT_BIN) $(call ls-files, $(STARTWRT_DIR)/backend/firstboot_config) \ $(call ls-files, $(STARTWRT_DIR)/backend/hotplug) $(call ls-files, $(STARTWRT_DIR)/backend/nftables) \ $(STARTWRT_DIR)/build/stage-files.sh ARCH=$(STARTWRT_ARCH) RUST_ARCH=$(STARTWRT_RUST_ARCH) PROFILE=$(PROFILE) ./$(STARTWRT_DIR)/build/stage-files.sh touch $(STARTWRT_OPENWRT)/files/.staged # Full flashable image. Delegates the OpenWrt build to make -C openwrt; this is # the multi-hour step. Resource fencing (memory-aware -j, cgroup) from the old # standalone Makefile can be ported here if host stability requires it. .PHONY: start-wrt-image start-wrt-image: $(STARTWRT_IMAGES) $(STARTWRT_IMAGES) &: $(STARTWRT_OPENWRT)/.config $(STARTWRT_OPENWRT)/files/.staged $(MAKE) -C $(STARTWRT_OPENWRT) V=s -j$(shell nproc) mkdir -p results gzip -9nc $(STARTWRT_IMAGE_DIR)/$(STARTWRT_SDCARD_SRC) > results/$(STARTWRT_SDCARD_NAME) cp $(STARTWRT_IMAGE_DIR)/$(STARTWRT_SYSUPGRADE_SRC) results/$(STARTWRT_SYSUPGRADE_NAME) # Deploy binary + restart daemon over SSH (atomic temp -> sync -> rename). .PHONY: start-wrt-update start-wrt-update: $(STARTWRT_BIN) cat $(STARTWRT_BIN) | \ ssh $(STARTWRT_REMOTE) 'set -e; \ trap "rm -f /usr/bin/.startwrt.new" EXIT; \ cat > /usr/bin/.startwrt.new; \ chmod +x /usr/bin/.startwrt.new; \ sync; \ mv /usr/bin/.startwrt.new /usr/bin/startwrt; \ ln -sf startwrt /usr/bin/startwrt-ctrld; \ ln -sf startwrt /usr/bin/startwrt-cli; \ /etc/init.d/startwrt restart' .PHONY: start-wrt-clean start-wrt-clean: rm -f results/$(STARTWRT_SDCARD_NAME) results/$(STARTWRT_SYSUPGRADE_NAME) rm -rf $(STARTWRT_DIR)/web/dist rm -rf $(STARTWRT_OPENWRT)/files rm -rf $(STARTWRT_OPENWRT)/build_dir $(STARTWRT_OPENWRT)/staging_dir $(STARTWRT_OPENWRT)/tmp $(STARTWRT_OPENWRT)/bin rm -f $(STARTWRT_OPENWRT)/.config # The web app is part of the root Angular workspace; its prettier formatting runs # through `web-format`/`web-format-check`. This target is just the Rust crate. .PHONY: start-wrt-format start-wrt-format-check start-wrt-format: $(FMT) cargo fmt -p startwrt-core -p uciedit -p uciedit_macros start-wrt-format-check: $(FMT) cargo fmt --check -p startwrt-core -p uciedit -p uciedit_macros