jw-pkg/make/pkg-dist.mk
Jan Lindemann f738951642
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 5m28s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m34s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 5m12s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m22s
CI / Packaging test (push) Successful in 0s
calculate_hash(): Derive hash from VCS file ids
The source hash is an md5sum over all versioned files in the working tree.
md5sum follows symlinks, so a project with links to files outside the tree
may produce different hashes depending on files outside the repo.

Compute the hash over the VCS file ids instead. Add a -s option to scm.sh
ls-files that lists each versioned file together with its content id. The
listing is sorted by path rather than by id, so an entry keeps its position
when its content changes.

For Git repos, git ls-tree -r HEAD reports the blob of a symlink's target
string and the pinned commit of a submodule, so the resulting hash depends
only on the committed tree, never on the working tree or on the machine.

calculate_hash() and the HASH variable in make/pkg-dist.mk feed the id
listing, minus the release metadata files, directly to md5sum.

calculate_hash() fails loudly when the pipeline fails, with its callers
refusing to proceed on an empty result.

The scheme change invalidates the stored HASH values, so every project
gets one more release the first time it runs against the new code, and the
hashes are stable again afterwards.

Signed-off-by: Jan Lindemann <jan@janware.com>
Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.85.1
2026-09-16 14:44:59 +02:00

335 lines
11 KiB
Makefile

PKG_PROJECT ?= $(FLAVOUR_PREFIX)$(PROJECT)
ifeq ($(filter pkg-%,$(MAKECMDGOALS)),)
# also to be used from proj.mk, typically
BUILD_PROJECT_PACKAGE = false
endif
PKG_VERSION ?= $(DIST_VERSION)
ifneq ($(BUILD_PROJECT_PACKAGE),false)
UPLOAD_SH = $(JWB_SCRIPT_DIR)/upload.sh
LOCAL_MKSPEC_SH ?= $(TOPDIR)/make/mkspec.sh
MKSPEC_SH ?= $(JWB_SCRIPT_DIR)/mkspec-wrapper.sh $(LOCAL_MKSPEC_SH)
FTP_SRC_GROUP ?= $(shell id -g)
FTP_SRC_USER ?= $(shell whoami)
FTP_RUN_GROUP ?= $(shell id -g)
FTP_RUN_USER ?= $(shell whoami)
FTP_DEV_GROUP ?= $(shell id -g)
FTP_DEV_USER ?= $(shell whoami)
FTP_HOST ?= pkg.janware.com
FTP_FILE_MODE ?= 644
FTP_DIR_MODE ?= 755
FTP_HOST_LOGIN ?= root
RELEASES_FILE = $(TOPDIR)/RELEASES$(FLAVOUR_SUFFIX)
RELEASES ?= $(shell $(PKG_SH_EXE) version \
-p $(OS_NAME_VERSION)/$(PKG_ARCH) $(RELEASES_FILE) read | $(SED) 's/-dev//')
PKG_CHECK_VCS_SYNC_BEFORE_RELEASE ?= true
HASH = $(shell $(cvs_files) -s -z | \
grep -vz "CHANGES\|VERSION\|HASH\|MD5SUMS\|RELEASES" | \
md5sum | $(SED) 's/ .*//')
LOCAL_REPO ?= /srv/dav/pub/local/packages/suse/$(OS_NAME_VERSION)
PACKAGE_VCS_FILES ?= false
ifeq ($(PACKAGE_VCS_FILES),true)
PKG_SH_BUILD_OPTS += --include-vcs-files
endif
include $(JWBDIR)/make/tag-defs.mk
DIST_DIR = dist
DIST_SRC_DIR = $(DIST_DIR)/src/$(PKG_PROJECT)-$(PKG_VERSION)
DIST_PCKG_DIR = $(DIST_DIR)/pckg
UPLOAD_SRC_DIR = $(DIST_PCKG_DIR)
PCKG_TAR ?= $(PKG_PROJECT)-$(PKG_VERSION).tar.gz
ifeq ($(PKG_FORMAT),debian)
# too bad: debian Requires: somepkg = 1.2.3 isn't satisfied by somepkg-1.2.3-5
PROJ_QUERY_PKG_REQUIRES_EXTRA_ARGS = --syntax debian
PKG_RUN_X86 ?= $(PKG_PROJECT)-run_$(PKG_VERSION)_$(PKG_ARCH).deb
ifeq ($(CREATE_DEVEL),true)
PKG_DEVEL_X86 ?= $(PKG_PROJECT)-devel_$(PKG_VERSION)_$(PKG_ARCH).deb
endif
else
PKG_RUN_X86 ?= $(PKG_PROJECT)-run-$(PKG_VERSION).$(PKG_ARCH).rpm
ifeq ($(CREATE_DEVEL),true)
PKG_DEVEL_X86 ?= $(PKG_PROJECT)-devel-$(PKG_VERSION).$(PKG_ARCH).rpm
endif
endif
DIST_FILES = $(shell echo $(REMOTE_TARGETS) | $(SED) 's/\b.*\///g; s/:.*\b//g')
GENERATED = $(sort $(shell find . -name '*.in' | \
$(SED) "s/\.in$$//; s%$(DIST_SRC_DIR)%%; s%^[./]*%%"))
ifeq ($(PKG_FORMAT),debian)
PKG_DIR_BINARY = $(TOPDIR)/dist/src
else
ifeq ($(BUILD_USER),root)
PKG_DIR_BUILD = /usr/src/packages
else
PKG_DIR_BUILD = $(HOME)/rpmbuild
endif
PKG_DIR_BINARY = $(PKG_DIR_BUILD)/RPMS/$(PKG_ARCH)
endif
DIST_DIRS = $(DIST_SRC_DIR) $(DIST_PCKG_DIR)
BINARY_PKG = $(DIST_PCKG_DIR)/$(PKG_RUN_X86)
ifeq ($(CREATE_DEVEL),true)
BINARY_PKG += $(DIST_PCKG_DIR)/$(PKG_DEVEL_X86)
endif
PKG_REQUIRES_BUILD += $(call proj_query, pkg-requires $(PROJ_QUERY_PKG_REQUIRES_EXTRA_ARGS) build $(PROJECT))
PKG_REQUIRES_RUN += $(call proj_query, pkg-requires $(PROJ_QUERY_PKG_REQUIRES_EXTRA_ARGS) run $(PROJECT))
PKG_REQUIRES_DEVEL += $(call proj_query, pkg-requires $(PROJ_QUERY_PKG_REQUIRES_EXTRA_ARGS) devel $(PROJECT))
PKG_CONFLICTS_RUN += $(call proj_query, pkg-conflicts $(PROJ_QUERY_PKG_CONFLICTS_EXTRA_ARGS) run $(PROJECT))
PKG_CONFLICTS_DEVEL += $(call proj_query, pkg-conflicts $(PROJ_QUERY_PKG_CONFLICTS_EXTRA_ARGS) devel $(PROJECT))
PKG_PROVIDES_RUN += $(call proj_query, pkg-provides $(PROJ_QUERY_PKG_PROVIDES_EXTRA_ARGS) run $(PROJECT))
PKG_PROVIDES_DEVEL += $(call proj_query, pkg-provides $(PROJ_QUERY_PKG_PROVIDES_EXTRA_ARGS) devel $(PROJECT))
PKG_UPLOAD_OS_NAME = $(shell echo $(OS_NAME_VERSION) | sed 's/-.*//')
PKG_UPLOAD_OS_VERSION = $(shell echo $(OS_NAME_VERSION) | sed 's/[^-]\+-//')
PKG_UPLOAD_URLPREFIX ?= rsync_ssh://root@pkg.janware.com:/srv/dav/pub/packages/linux/$(PKG_UPLOAD_OS_NAME)/$(PKG_UPLOAD_OS_VERSION)
PKG_UPLOAD_USER ?= $(shell id -un)
PKG_UPLOAD_GROUP ?= $(shell id -gn)
PKG_UPLOAD_FILE_ATTRIB ?= 644:755:$(PKG_UPLOAD_USER).$(PKG_UPLOAD_GROUP)
unexport PKG_VERSION VERSION DIST_SRC_DIR
include $(JWBDIR)/make/tag-rules.mk
include $(JWBDIR)/make/upload-rules.mk
PKG_SH = $(PKG_SH_EXE) \
-N $(PKG_PROJECT) -P $(PROJECT) \
-R "$(PKG_REQUIRES_RUN)" -D "$(PKG_REQUIRES_DEVEL)" \
-X "$(PKG_CONFLICTS_RUN)" -Y "$(PKG_CONFLICTS_DEVEL)" \
--provides-run "$(PKG_PROVIDES_RUN)" --provides-devel "$(PKG_PROVIDES_DEVEL)" \
-m $(JWB_SCRIPT_DIR) -a $(PKG_ARCH) -p $(DIST_PCKG_DIR) -F $(PKG_FORMAT) \
-B $(PKG_UPLOAD_URLPREFIX) -A $(PKG_UPLOAD_FILE_ATTRIB)
all:
install:
clean: pkg-clean
distclean: pkg-clean
pkg-tgz: $(DIST_PCKG_DIR)/$(PCKG_TAR)
ftag: ftag.dist
pkg-upload-stable: pkg-upload-STABLE.dist
pkg-upload-rc: pkg-upload-RC.dist
pkg-clean: clean.rpm
pkg-uninstall: config pkguninstall.dist
pkg-build: pkg-build.dist
pkg-install: config pkg-build pkginstall.dist
pkg-build-install: pkg-build pkg-install
pkg-reinstall: pkg-uninstall pkg-install
pkg-rebuild: pkg-clean pkg-build
pkg-update: pkgupdate.dist
pkg-upload-local: pkg-upload-local.dist
clean.rpm:
$(RM) -rf $(DIST_DIR) *.dist
pkg-build.dist: $(VERSION_FILE)
$(PKG_SH) build $(PKG_SH_BUILD_OPTS)
touch $@
pkg-update-local-repo:
for a in src i386 i586 i686 x86_64; do \
if ls dist/*/*.$$a.rpm >/dev/null 2>&1; then \
sudo install -m 644 dist/pckg/*.$$a.rpm $(LOCAL_REPO)/rpm/$$a/ ;\
fi ;\
done
sudo sh $(LOCAL_REPO)/update.sh
src-dir.dist:
mkdir -p $(DIST_SRC_DIR)
touch $@
pkginstall.dist: pkg-build.dist
$(Q)set -e; for p in $(BINARY_PKG); do \
if ! $(RPM) -q `basename $$p | $(SED) "s/[._]$(PKG_ARCH)\.$(PKG_SUFFIX)//; s/_\([0-9.-]\+\)$$/-\1/"` > /dev/null 2>&1 ; then \
echo + installing $$p ;\
sudo $(RPM) -U $$(realpath $$p); \
fi; \
done
touch $@
pkguninstall.dist:
$(Q)set -e; for s in devel run; do \
if $(RPM) -q $(PKG_PROJECT)-$$s > /dev/null 2>&1 ; then \
echo + removing $(PKG_PROJECT)-$$s ;\
sudo $(RPM) -e $(PKG_PROJECT)-$$s --nodeps --allmatches; \
fi; \
done
$(RM) -f pkginstall.dist
upload-%.dist: %_$(PROJECT_CAPNAME)_RPM_RUN_I386
cvs commit $<
$(UPLOAD_SH) $< $(REMOTE_TARGET_PREFIX)$(PCKG_ROOT)/$<:640:750:$(FTP_RUN_USER).$(FTP_RUN_GROUP)
touch $@
update-repo.dist: upload.dist
$(CVS_RSH) -l root $(FTP_HOST) $(UPDATE_REPO_SH)
touch $@
# ------ hash stuff
ifeq ($(wildcard $(TOPDIR)/.git),)
SCM_COMMIT = cvs commit
SCM_ADD = cvs add
SCM_PUSH =
SCM_PULL = cvs update -dP
define check_scm_sync
echo + checking cvs ;\
$(SCM_PULL) ;\
cvs status > cvs_status.tmp 2>&1 ;\
if [ $$? != 0 ]; then \
$(CAT) cvs_status.tmp ;\
echo -e "\n======== cvs status failed, giving up." >&2 ;\
exit 1 ;\
fi ;\
if grep -qi "locally modified" cvs_status.tmp; then \
echo + cvs copy has locally modified files, giving up >&2 ;\
exit 1 ;\
fi ;\
if grep -qi "needs" cvs_status.tmp; then \
echo + cvs copy is out-of-date, giving up >&2 ;\
exit 1 ;\
fi
endef
else
SCM_COMMIT = git commit
SCM_ADD = git add
SCM_PUSH = git push
SCM_PULL = make git-get-maintainer
define check_scm_sync
echo + checking git ;\
$(SCM_PULL) || {\
echo "$(SCM_PULL) failed, giving up" ;\
exit 1 ;\
} ;\
git status -s > git_status.tmp 2>&1 ;\
if [ $$? != 0 ]; then \
$(CAT) git_status.tmp ;\
echo -e "\n======== git status failed, giving up." >&2 ;\
exit 1 ;\
fi ;\
if grep -qi "^ *M " git_status.tmp; then \
echo + git copy has locally modified files, giving up >&2 ;\
exit 1 ;\
fi
endef
endif
define increase_build_number
if [ "$(PKG_CHECK_VCS_SYNC_BEFORE_RELEASE)" = true ]; then \
$(check_scm_sync) ;\
fi ;\
if [ "$(RELEASES)" != "$(PKG_VERSION)" ]; then \
echo "+ no need to increase build number of $(PKG_VERSION), last rpm has $(RELEASES)" ;\
exit 0 ;\
fi ;\
echo -n "+ increasing build number to " ;\
echo $(MAJOR_MINOR_RELEASE)-$(shell expr $(BUILD_NUMBER) + 1)-dev | tee VERSION ;\
echo $(HASH) > HASH ;\
if ! /bin/bash $(JWB_SCRIPT_DIR)/scm.sh ls-files | grep -q '^HASH$$'; then \
$(SCM_ADD) HASH ;\
fi ;\
$(SCM_COMMIT) -m "$(MAJOR_MINOR_RELEASE)-$(shell expr $(BUILD_NUMBER) + 1)-dev" HASH VERSION
$(SCM_PUSH)
endef
define check_reinstall_old
(true $(addprefix && test -f ,$(DIST_PCKG_RPM)) && make pkg-uninstall && make pkg-install)
endef
md5:
echo $(HASH) > HASH
pkg-next-build:
$(Q)$(increase_build_number)
try-reinstall:
$(check_reinstall_old)
pkg-update-release:
$(Q)if [ "`$(CAT) HASH`" != "$(HASH)" ]; then \
echo + source was modified ;\
$(increase_build_number) ;\
elif ! $(check_reinstall_old); then \
echo "+ old rpm is uninstallable" ;\
$(increase_build_number) ;\
fi
pkg-check-release:
$(Q)if [ "`$(CAT) HASH`" != "$(HASH)" ]; then \
echo + source was modified ;\
else \
echo + source is unmodified ;\
fi
pkg-release: pkg-release-reinstall
pkg-rebuild-reinstall: pkg-clean pkg-build pkg-reinstall
pkg-release-update-version:
$(PKG_SH) update-version
pkg-release-reinstall: get-maintainer get-official get-pub pkg-release-update-version
$(PKG_SH) release $(PKG_SH_BUILD_OPTS)
ifneq ($(TARGET_HOST),)
pkg-remote-install:
scp $(addprefix dist/pckg/,$(PKG_RUN_X86) $(PKG_DEVEL_X86)) root@$(TARGET_HOST):/tmp/
ssh -l root $(TARGET_HOST) rpm -U --force $(addprefix /tmp/,$(PKG_RUN_X86) $(PKG_DEVEL_X86))
pkg-remote-install-run:
scp $(addprefix dist/pckg/,$(PKG_RUN_X86)) root@$(TARGET_HOST):/tmp/
ssh -l root $(TARGET_HOST) rpm -U --force $(addprefix /tmp/,$(PKG_RUN_X86))
ssh-remote:
ssh -l root $(TARGET_HOST)
endif
pkg-requires:
@echo "PKG_REQUIRES_BUILD = $(PKG_REQUIRES_BUILD)"
@echo "PKG_REQUIRES_RUN = $(PKG_REQUIRES_RUN)"
@echo "PKG_REQUIRES_DEVEL = $(PKG_REQUIRES_DEVEL)"
@echo "PKG_CONFLICTS_RUN = $(PKG_CONFLICTS_RUN)"
@echo "PKG_CONFLICTS_DEVEL = $(PKG_CONFLICTS_DEVEL)"
@echo "PKG_PROVIDES_RUN = $(PKG_PROVIDES_RUN)"
@echo "PKG_PROVIDES_DEVEL = $(PKG_PROVIDES_DEVEL)"
else # ifneq ($(BUILD_PROJECT_PACKAGE),false)
pkg-build \
pkg-check-release \
pkg-clean \
pkg-install \
pkg-next-build \
pkg-rebuild \
pkg-rebuild-reinstall \
pkg-reinstall \
pkg-release \
pkg-release-reinstall \
pkg-remote-install \
pkg-remote-install-run \
pkg-uninstall \
pkg-update \
pkg-update-local-repo \
pkg-update-release \
pkg-upload-local \
pkg-upload-local.dist \
pkg-upload-rc \
pkg-upload-stable:
@echo "This project doesn't support building packages, ignoring request to $(patsubst pkg-%,%,$@)."
endif # ifneq ($(BUILD_PROJECT_PACKAGE),false)
echo: echo-pkg
echo-dist:
@echo "TARGET_HOST = $(TARGET_HOST)"