profile := dev target = $(shell rustc -vV | grep host | awk '{print $$2}') channel := unstable # Config: Directories & Locations ############################################## # Cargo outputs dev profile to 'debug' directory, not 'dev' prefix := /usr/local ifeq ($(profile),dev) output_dir := debug else output_dir := $(profile) endif flatpak_cargo_generator := $(HOME)/projects/vendor/flatpak-builder-tools/cargo # Config: Packaging Config ##################################################### linuxdeploy_url := https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$(shell uname -m).AppImage linuxdeploy := .cache/linuxdeploy.AppImage pkgver := $(shell grep '^pkgver=' build-aux/PKGBUILD | cut -d= -f2) pkgrel := $(shell grep '^pkgrel=' build-aux/PKGBUILD | cut -d= -f2) # Filename format: map-aarch64-unstable.flatpak or map-aarch64-unstable-fedora43.rpm filename = $(app_name)-$(arch)-$(channel) # Config: Naming ############################################################### arch = $(firstword $(subst -, ,$(target))) app_name := map # Config: Container Images ##################################################### fedora_versions := fedora42 fedora43 fedora-rawhide debian_versions := trixie forky all_containers := arch $(fedora_versions) $(debian_versions) container_image_prefix := map-build clean_images := 0 # Config: Release Location ##################################################### deploy_host := deploy@build.r.bdr.sh deploy_path := /srv/http/build.r.bdr.sh/$(app_name)-linux define sign_and_deploy @./scripts/sign.sh "$(1)" "$(channel)" "$(arch)" rsync -avz $(1) $(deploy_host):$(deploy_path) rsync -avz $(1).minisig $(deploy_host):$(deploy_path) endef default: build set_rust: rustup default stable prepare: ifneq ($(skip_prepare),1) rustup target add $(target) endif # Build ######################################################################## build: compile_translations prepare cargo build --profile $(profile) --target $(target) # Code Quality ################################################################# test: cargo test coverage: cargo tarpaulin format: cargo fmt && cargo clippy --fix lint: cargo fmt -- --check && cargo clippy # Internationalization / Localization ########################################## find_translatable_files: @find ./ -not -path '*/.*' -type f -name "*.rs" -exec grep -l "tr!(\"\|gettext" {} \; | sort > po/POTFILES extract_strings: find_translatable_files @xgettext --files-from=po/POTFILES --output=po/systems.tranquil.Map.pot --from-code=UTF-8 --add-comments --keyword='tr!' po_files := $(wildcard po/*.po) mo_files := $(patsubst po/%.po,po/%/LC_MESSAGES/systems.tranquil.Map.mo,$(po_files)) compile_translations: $(mo_files) po/%/LC_MESSAGES/systems.tranquil.Map.mo: po/%.po @mkdir -p $(dir $@) msgfmt $< -o $@ # Container Images ############################################################# build-container-%: ifeq ($(clean_images),1) podman system prune -af endif @echo "=== Building container image: $(container_image_prefix):$* ===" podman build -t $(container_image_prefix):$* build-containers/$* build-containers: $(addprefix build-container-,$(all_containers)) # Packaging #################################################################### # Generic packages # These run directly on the host machine, since the assumption is that it # shouldn't affect the outcome. update_flatpak_dependencies: cd $(flatpak_cargo_generator) && `poetry env activate` && python3 flatpak-cargo-generator.py $(CURDIR)/Cargo.lock -o $(CURDIR)/build-aux/cargo-sources.json && deactivate package-tar: build @$(eval staging := $(shell mktemp -d)) @install -Dm0755 target/$(target)/$(output_dir)/$(app_name) $(staging)/usr/bin/$(app_name) @install -Dm0644 resources/logo.svg $(staging)/usr/share/icons/hicolor/scalable/apps/systems.tranquil.Map.svg @install -Dm0644 resources/systems.tranquil.Map.desktop $(staging)/usr/share/applications/systems.tranquil.Map.desktop @install -Dm0644 resources/systems.tranquil.Map.metainfo.xml $(staging)/usr/share/metainfo/systems.tranquil.Map.metainfo.xml @install -Dm0644 resources/systems.tranquil.Map.service $(staging)/usr/share/dbus-1/services/systems.tranquil.Map.service @install -Dm0644 resources/wmap.lang $(staging)/usr/share/gtksourceview-5/language-specs/wmap.lang @for po_file in po/*.po; do \ locale=$$(basename "$$po_file" .po); \ install -Dm0644 po/$$locale/LC_MESSAGES/systems.tranquil.Map.mo $(staging)/usr/share/locale/$$locale/LC_MESSAGES/systems.tranquil.Map.mo; \ done tar -czvf $(filename).tar.gz -C $(staging) usr @rm -rf $(staging) package-flatpak: update_flatpak_dependencies flatpak-builder --force-clean --user --install-deps-from=flathub --repo=repo --install builddir ./build-aux/systems.tranquil.Map.yml flatpak build-bundle repo $(filename).flatpak systems.tranquil.Map $(linuxdeploy): @mkdir -p .cache curl -L -o $(linuxdeploy) $(linuxdeploy_url) chmod +x $(linuxdeploy) package-appimage: build $(linuxdeploy) ifeq ($(findstring linux,$(target)),linux) @rm -f *.AppImage @$(eval appdir := $(shell mktemp -d)) @install -Dm0755 target/$(target)/$(output_dir)/$(app_name) $(appdir)/usr/bin/$(app_name) @install -Dm0644 resources/logo.svg $(appdir)/usr/share/icons/hicolor/scalable/apps/systems.tranquil.Map.svg @install -Dm0644 resources/systems.tranquil.Map.desktop $(appdir)/usr/share/applications/systems.tranquil.Map.desktop @install -Dm0644 resources/systems.tranquil.Map.metainfo.xml $(appdir)/usr/share/metainfo/systems.tranquil.Map.metainfo.xml @install -Dm0644 resources/systems.tranquil.Map.service $(appdir)/usr/share/dbus-1/services/systems.tranquil.Map.service @install -Dm0644 resources/wmap.lang $(appdir)/usr/share/gtksourceview-5/language-specs/wmap.lang @for po_file in po/*.po; do \ locale=$$(basename "$$po_file" .po); \ install -Dm0644 po/$$locale/LC_MESSAGES/systems.tranquil.Map.mo $(appdir)/usr/share/locale/$$locale/LC_MESSAGES/systems.tranquil.Map.mo; \ done APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=true $(linuxdeploy) --appdir=$(appdir) --output=appimage --desktop-file=resources/systems.tranquil.Map.desktop --icon-file=resources/logo.svg mv *.AppImage $(filename).AppImage @rm -rf $(appdir) endif # Distro-specific packages # These run inside containers, as we want to make sure they're built with the # libraries available in that particular distribution. # Internal target: runs inside arch container package-pacman: @$(eval staging := $(shell mktemp -d)) rsync -a --filter=':- .gitignore' --exclude='.git' . $(staging)/src cp build-aux/PKGBUILD $(staging)/ cd $(staging) && PKGEXT='.pkg.tar.gz' makepkg -f mv $(staging)/$(app_name)-$(pkgver)-$(pkgrel)-$(arch).pkg.tar.gz $(app_name)-$(arch)-$(channel)-arch.pkg.tar.gz @rm -rf $(staging) # Internal target: runs inside fedora container package-rpm: build ifeq ($(findstring linux,$(target)),linux) cargo generate-rpm --profile $(profile) --target $(target) mv target/$(target)/generate-rpm/*.rpm $(filename)-$(distro).rpm endif # Internal target: runs inside debian container package-deb: build ifeq ($(findstring linux,$(target)),linux) cargo deb --profile $(profile) --target $(target) mv target/$(target)/debian/*.deb $(filename)-$(distro).deb endif # # Podman wrappers for distro-specific builds # package-pacman-podman: build-container-arch @echo "=== Building Arch package for $(arch) ===" podman run --rm -v $(CURDIR):/src:Z -w /src $(container_image_prefix):arch bash -c '\ staging=$$(mktemp -d) && \ cp -r /src/. $$staging/ && \ chown -R builder:builder $$staging && \ su builder -c "cd $$staging && make -e profile=$(profile) -e channel=$(channel) -e target=$(target) package-pacman" && \ cp $$staging/$(app_name)-$(arch)-$(channel)-arch.pkg.tar.gz /src/' ifeq ($(clean_images),1) podman rmi $(container_image_prefix):arch endif package-rpm-podman: ifndef distro $(error distro is required, e.g., make package-rpm-podman distro=fedora43) endif $(MAKE) build-container-$(distro) @echo "=== Building RPM for $(distro) ($(arch)) ===" podman run --rm -v $(CURDIR):/src:Z -w /src $(container_image_prefix):$(distro) \ make profile=$(profile) channel=$(channel) target=$(target) distro=$(distro) package-rpm ifeq ($(clean_images),1) podman rmi $(container_image_prefix):$(distro) endif package-deb-podman: ifndef distro $(error distro is required, e.g., make package-deb-podman distro=bookworm) endif $(MAKE) build-container-$(distro) @echo "=== Building DEB for $(distro) ($(arch)) ===" podman run --rm -v $(CURDIR):/src:Z -w /src $(container_image_prefix):$(distro) \ make profile=$(profile) channel=$(channel) target=$(target) distro=$(distro) package-deb ifeq ($(clean_images),1) podman rmi $(container_image_prefix):$(distro) endif package-rpm-all: @for v in $(fedora_versions); do \ $(MAKE) distro=$$v package-rpm-podman; \ done package-deb-all: @for v in $(debian_versions); do \ $(MAKE) distro=$$v package-deb-podman; \ done package: package-tar package-flatpak package-appimage package-pacman-podman package-rpm-all package-deb-all # Distribution ################################################################# distribute-tar: @$(call sign_and_deploy,$(filename).tar.gz) distribute-flatpak: @$(call sign_and_deploy,$(filename).flatpak) distribute-appimage: @$(call sign_and_deploy,$(filename).AppImage) distribute-pacman: @$(call sign_and_deploy,$(app_name)-$(arch)-$(channel)-arch.pkg.tar.gz) distribute-rpm: @for v in $(fedora_versions); do \ ./scripts/sign.sh "$(filename)-$$v.rpm" "$(channel)" "$(arch)" && \ rsync -avz $(filename)-$$v.rpm $(deploy_host):$(deploy_path) && \ rsync -avz $(filename)-$$v.rpm.minisig $(deploy_host):$(deploy_path); \ done distribute-deb: @for v in $(debian_versions); do \ ./scripts/sign.sh "$(filename)-$$v.deb" "$(channel)" "$(arch)" && \ rsync -avz $(filename)-$$v.deb $(deploy_host):$(deploy_path) && \ rsync -avz $(filename)-$$v.deb.minisig $(deploy_host):$(deploy_path); \ done distribute: distribute-tar distribute-flatpak distribute-appimage distribute-pacman distribute-rpm distribute-deb # Release ###################################################################### release: $(MAKE) profile=release package distribute # Installation ################################################################# install: build install -Dm0755 target/$(target)/$(output_dir)/$(app_name) $(prefix)/bin/$(app_name) install -Dm0644 resources/logo.svg $(prefix)/share/icons/hicolor/scalable/apps/systems.tranquil.Map.svg install -Dm0644 resources/systems.tranquil.Map.desktop $(prefix)/share/applications/systems.tranquil.Map.desktop install -Dm0644 resources/systems.tranquil.Map.metainfo.xml $(prefix)/share/metainfo/systems.tranquil.Map.metainfo.xml install -Dm0644 resources/systems.tranquil.Map.service $(prefix)/share/dbus-1/services/systems.tranquil.Map.service install -Dm0644 resources/wmap.lang $(prefix)/share/gtksourceview-5/language-specs/wmap.lang @for po_file in po/*.po; do \ locale=$$(basename "$$po_file" .po); \ install -Dm0644 po/$$locale/LC_MESSAGES/systems.tranquil.Map.mo $(prefix)/share/locale/$$locale/LC_MESSAGES/systems.tranquil.Map.mo; \ done uninstall: rm -f $(prefix)/bin/$(app_name) rm -f $(prefix)/share/icons/hicolor/scalable/apps/systems.tranquil.Map.svg rm -f $(prefix)/share/applications/systems.tranquil.Map.desktop rm -f $(prefix)/share/metainfo/systems.tranquil.Map.metainfo.xml rm -f $(prefix)/share/dbus-1/services/systems.tranquil.Map.service rm -f $(prefix)/share/gtksourceview-5/language-specs/wmap.lang @for po_file in po/*.po; do \ locale=$$(basename "$$po_file" .po); \ rm -f $(prefix)/share/locale/$$locale/LC_MESSAGES/systems.tranquil.Map.mo; \ done ci: lint # Installation ################################################################# ifeq ($(GIT_REF),refs/heads/main) $(MAKE) -e channel=unstable release else ifneq (,$(findstring refs/tags/,$(GIT_REF))) $(MAKE) -e channel=$(subst refs/tags/,,$(GIT_REF)) release else @echo "Not in CI environment." endif .PHONY: default build test coverage format lint \ find_translatable_files extract_strings compile_translations \ update_flatpak_dependencies \ package-tar package-flatpak package-appimage \ package-pacman package-rpm package-deb \ package-pacman-podman package-rpm-podman package-deb-podman \ package-rpm-all package-deb-all package \ distribute-tar distribute-flatpak distribute-appimage distribute-pacman distribute-rpm distribute-deb distribute \ release install uninstall set_rust prepare \ build-containers