#!/usr/bin/make -f

include /usr/share/dpkg/architecture.mk

export DH_VERBOSE = 1
# genimage otherwise trips lintian hardening-no-bindnow.
export DEB_BUILD_MAINT_OPTIONS = hardening=+bindnow

# Upstream has no build system of its own: the tree is bash, Python and YAML
# data, installed verbatim under /usr/share/rpi-image-gen. What it does have
# is "package/", a set of recipes that fetch and compile host helper tools on
# the user's machine, on first use, into their work directory. That is what
# this package replaces. Three of those recipes - bdebstrap, genimage and
# erofs-utils - arrive here as supplementary orig tarballs and are built at
# package build time; the fourth, zstd, is taken from Debian instead. Patch
# 0007 stops the engine building any of them and drops the toolchain from
# upstream's dependency manifest.

# These must match what upstream pins in package/. Editing them does not
# update a component: re-import the tarball, then edit them. The build stops
# if the two disagree.
BDEBSTRAP_VERSION := 0.7.0
BDEBSTRAP_SHA256 := c8675f637af16a4471c8f61627895d21e56ef5d4bd13fa2a18cd01513395a009
GENIMAGE_VERSION := 20
GENIMAGE_SHA256 := 4cadce884f920a4663c59652f1b87787772628ee4e2867a48e94c69f122fae57
EROFS_UTILS_VERSION := 1.9.4
EROFS_UTILS_SHA256 := 7d135aa2550326a5acf20f53c518aea5a8900015ce50700044e40f818c31dd80

# mkfs.erofs caps the block size it will accept at compile time, and with
# MAX_BLOCK_SIZE unset erofs-utils takes the build machine's page size
# (configure.ac, "Detect maximum block size if necessary"). Debian's build
# hosts are 4K, so the archive binary rejects "-b 16384" outright - and the
# ab_userdata layout defaults rootfs_type to erofs and passes
# -b ${IGconf_linux_page_size}, which layer/rpi/device/arm64/linux-image-2712
# forces to 16384. An erofs root on a 2712 device therefore needs this build.
# Upstream pins the same value, so this is checked against it below.
EROFS_MAX_BLOCK_SIZE := 16384

# Private to rpi-image-gen, and deliberately not on anything else's PATH.
HOSTPREFIX := /usr/lib/rpi-image-gen/host

BUILDDIR := debian/build
BDEBSTRAP_SRC := $(BUILDDIR)/bdebstrap
GENIMAGE_SRC := $(BUILDDIR)/genimage
EROFS_UTILS_SRC := $(BUILDDIR)/erofs-utils
DEST := $(BUILDDIR)/dest

%:
	dh $@

# Upstream's own suite is not run here: it needs python3-yaml and
# python3-jsonschema, which are runtime dependencies rather than
# Build-Depends. debian/tests/upstream-testsuite runs it against the
# installed tree instead.
#
# What does run is the erofs block size check. The cap is baked into the
# binary at compile time, so prove it now rather than discover it at image
# build time; Debian's erofs-utils answers "<E> erofs: invalid block size
# 16384" here. This target is its home because under compat 13 dh omits the
# whole override for DEB_BUILD_OPTIONS=nocheck, and hoists the nocheck build
# profile into that variable first. The cross guard is this file's job,
# though - dh only warns there - and the check runs a host-architecture
# binary, which a cross builder cannot execute.
override_dh_auto_test:
ifeq ($(DEB_BUILD_ARCH),$(DEB_HOST_ARCH))
	mkdir -p $(BUILDDIR)/blocksize.d
	$(EROFS_UTILS_SRC)/mkfs/mkfs.erofs -b $(EROFS_MAX_BLOCK_SIZE) \
	   $(BUILDDIR)/blocksize.erofs $(BUILDDIR)/blocksize.d
else
	@echo "cross build ($(DEB_BUILD_ARCH) -> $(DEB_HOST_ARCH)):" \
	   "skipping the mkfs.erofs block size check"
endif

override_dh_auto_configure:
	# Stop if upstream's pins have moved. Quietly shipping a superseded
	# component is the failure this exists to prevent, so it is an error.
	set -e; \
	pinned=$$(sed -n 's/^PKG_VER *:= *//p' package/bdebstrap/Makefile); \
	test "$$pinned" = "$(BDEBSTRAP_VERSION)" || { \
	   echo "upstream pins bdebstrap $$pinned, component is $(BDEBSTRAP_VERSION)" >&2; exit 1; }; \
	grep -q 'sha256:$(BDEBSTRAP_SHA256)' package/bdebstrap/bdebstrap-$(BDEBSTRAP_VERSION).meta || { \
	   echo "package/bdebstrap no longer pins sha256:$(BDEBSTRAP_SHA256)" >&2; exit 1; }; \
	grep -q 'version="$(BDEBSTRAP_VERSION)"' bdebstrap/setup.py || { \
	   echo "component tarball is not bdebstrap $(BDEBSTRAP_VERSION)" >&2; exit 1; }; \
	pinned=$$(sed -n 's/^GENIMAGE_VER *?*= *//p' package/genimage/Makefile); \
	test "$$pinned" = "$(GENIMAGE_VERSION)" || { \
	   echo "upstream pins genimage $$pinned, component is $(GENIMAGE_VERSION)" >&2; exit 1; }; \
	grep -q 'sha256:$(GENIMAGE_SHA256)' package/genimage/genimage-$(GENIMAGE_VERSION).meta || { \
	   echo "package/genimage no longer pins sha256:$(GENIMAGE_SHA256)" >&2; exit 1; }; \
	grep -q '\[$(GENIMAGE_VERSION)\]' genimage/configure.ac || { \
	   echo "component tarball is not genimage $(GENIMAGE_VERSION)" >&2; exit 1; }; \
	pinned=$$(sed -n 's/^EROFS_UTILS_VER *?*= *//p' package/erofs-utils/Makefile); \
	test "$$pinned" = "$(EROFS_UTILS_VERSION)" || { \
	   echo "upstream pins erofs-utils $$pinned, component is $(EROFS_UTILS_VERSION)" >&2; exit 1; }; \
	grep -q 'sha256:$(EROFS_UTILS_SHA256)' package/erofs-utils/erofs-utils-$(EROFS_UTILS_VERSION).meta || { \
	   echo "package/erofs-utils no longer pins sha256:$(EROFS_UTILS_SHA256)" >&2; exit 1; }; \
	grep -q 'MAX_BLOCK_SIZE=$(EROFS_MAX_BLOCK_SIZE)' package/erofs-utils/Makefile || { \
	   echo "upstream no longer pins MAX_BLOCK_SIZE=$(EROFS_MAX_BLOCK_SIZE)" >&2; exit 1; }; \
	test "$$(head -n1 erofs-utils/VERSION)" = "$(EROFS_UTILS_VERSION)" || { \
	   echo "component tarball is not erofs-utils $(EROFS_UTILS_VERSION)" >&2; exit 1; }
	# Each is built from a copy with upstream's own patch series applied, so
	# a patch added there is picked up rather than silently skipped.
	rm -rf $(BUILDDIR)
	mkdir -p $(BUILDDIR)
	cp -a bdebstrap $(BDEBSTRAP_SRC)
	cp -a genimage $(GENIMAGE_SRC)
	cp -a erofs-utils $(EROFS_UTILS_SRC)
	set -e; for p in package/bdebstrap/patches/$(BDEBSTRAP_VERSION)/*.patch; do \
	   patch -d $(BDEBSTRAP_SRC) -p1 --no-backup-if-mismatch < "$$p"; \
	done
	set -e; for p in package/genimage/patches/$(GENIMAGE_VERSION)/*.patch; do \
	   patch -d $(GENIMAGE_SRC) -p1 --no-backup-if-mismatch < "$$p"; \
	done
	# Upstream keeps one series per version, so the glob may not match; a
	# series added later is picked up with no edit here.
	set -e; for p in package/erofs-utils/patches/$(EROFS_UTILS_VERSION)/*.patch; do \
	   test -e "$$p" || continue; \
	   patch -d $(EROFS_UTILS_SRC) -p1 --no-backup-if-mismatch < "$$p"; \
	done
	# Neither GitHub archive carries a configure script.
	cd $(GENIMAGE_SRC) && autoreconf --install --force
	dh_auto_configure -D $(GENIMAGE_SRC) -- \
	   --prefix=$(HOSTPREFIX) --disable-static --disable-dependency-tracking
	cd $(EROFS_UTILS_SRC) && autoreconf --install --force
	# Debian's erofs-utils enables lz4, lzma, zlib, libdeflate, zstd and
	# xxhash, so this build does too: fs_erofs_mkfs_args is a documented
	# variable, and "-z lz4" must not fail here when it would work against
	# the archive binary. Every optional dependency that autodetects is named
	# rather than left to configure.ac to find - that would make the shipped
	# feature set a function of whatever was in the build chroot, and the
	# named form errors out instead of quietly dropping a compressor.
	# selinux and erofsfuse stay off as upstream's recipe has them; nothing
	# in rpi-image-gen refers to either, and erofsfuse is not shipped.
	dh_auto_configure -D $(EROFS_UTILS_SRC) -- \
	   --prefix=$(HOSTPREFIX) \
	   --enable-lz4 \
	   --enable-lzma \
	   --with-zlib \
	   --with-libdeflate \
	   --with-libzstd \
	   --with-xxhash \
	   --with-uuid \
	   --without-libcurl \
	   --without-openssl \
	   --without-libxml2 \
	   --without-json-c \
	   --without-libnl3 \
	   --without-selinux \
	   --disable-fuse \
	   --enable-multithreading \
	   --disable-static \
	   --disable-dependency-tracking \
	   MAX_BLOCK_SIZE=$(EROFS_MAX_BLOCK_SIZE)

override_dh_auto_build:
	dh_auto_build -D $(GENIMAGE_SRC)
	dh_auto_build -D $(EROFS_UTILS_SRC)

override_dh_auto_install:
	dh_auto_install -D $(GENIMAGE_SRC) --destdir=$(CURDIR)/$(DEST)
	dh_auto_install -D $(EROFS_UTILS_SRC) --destdir=$(CURDIR)/$(DEST)
	# bdebstrap is one self-contained script, and finds its hooks relative to
	# its own location, so a private prefix needs no patching.
	install -D -m755 $(BDEBSTRAP_SRC)/bdebstrap $(DEST)$(HOSTPREFIX)/bin/bdebstrap
	install -d $(DEST)$(HOSTPREFIX)/share/bdebstrap/hooks
	install -m755 $(BDEBSTRAP_SRC)/hooks/* $(DEST)$(HOSTPREFIX)/share/bdebstrap/hooks/

# contrib ships a prebuilt rpi-preseed .deb for the CM5 programming jig
# example. Its source is not in this tree, so it cannot be shipped; patch 0005
# points the example at the archive copy instead. Exclude the directory rather
# than the filename, or a version bump upstream silently reinstates it.
override_dh_install:
	dh_install \
	   -X'cm5-programming-jig/pkgs/' \
	   -X'.gitignore' \
	   -X'docs/layer/.empty'

# The documentation and examples are read as data by the tool and are
# cross-referenced by relative path, so they must not be gzipped.
override_dh_compress:
	dh_compress -Xdocs -Xexamples -Xcontrib -X.adoc -X.md

override_dh_clean:
	rm -rf $(BUILDDIR)
	dh_clean
