aboutsummaryrefslogtreecommitdiff
path: root/Makefile
blob: 3d5e2de5e1c240842dae769aa350c31af0cea543 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
profile := release
target = $(shell rustc -vV | grep host | awk '{print $$2}')
channel := unstable

# Cargo outputs dev profile to 'debug' directory, not 'dev'
ifeq ($(profile),dev)
output_dir := debug
else
output_dir := $(profile)
endif

# Extract just the architecture (first component of target triple)
arch = $(firstword $(subst -, ,$(target)))
app_name := map
deploy_host := deploy@build.r.bdr.sh
deploy_path := /srv/http/build.r.bdr.sh/$(app_name)-linux
prefix := /usr/local
flatpak_cargo_generator := $(HOME)/projects/vendor/flatpak-builder-tools/cargo
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)

# Podman images for distro-specific builds
fedora_versions := fedora42 fedora43 fedora-rawhide
debian_versions := bookworm trixie bullseye
fedora_image_fedora42 := fedora:42
fedora_image_fedora43 := fedora:43
fedora_image_fedora-rawhide := fedora:rawhide
debian_image_bookworm := debian:bookworm
debian_image_trixie := debian:trixie
debian_image_bullseye := debian:bullseye
# lopsided/archlinux provides multi-arch images (amd64, arm64, etc.)
arch_image := lopsided/archlinux:latest

# Filename format: map-aarch64-unstable.flatpak or map-aarch64-unstable-fedora43.rpm
filename = $(app_name)-$(arch)-$(channel)

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 $@

# Packaging ####################################################################
#
# Generic packages (run on bare metal)
#

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 (run inside podman containers)
#

# 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:
	@echo "=== Building Arch package for $(arch) ==="
	podman run --rm -v $(CURDIR):/src:Z -w /src $(arch_image) bash -c '\
		pacman -Syu --noconfirm make clang lld curl tar gzip gettext gtk4 libadwaita gtksourceview5 fakeroot rsync && \
		curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
		source $$HOME/.cargo/env && \
		useradd -m builder && \
		chown -R builder:builder /src && \
		su builder -c "cd /src && make -e profile=$(profile) -e channel=$(channel) -e target=$(target) package-pacman"'

package-rpm-podman:
ifndef distro
	$(error distro is required, e.g., make package-rpm-podman distro=fedora43)
endif
	@echo "=== Building RPM for $(distro) ($(arch)) ==="
	podman run --rm -v $(CURDIR):/src:Z -w /src $(fedora_image_$(distro)) bash -c '\
		dnf install -y make clang lld curl tar gzip gettext gtk4-devel libadwaita-devel gtksourceview5-devel pkg-config && \
		curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
		source $$HOME/.cargo/env && \
		curl -L --proto "=https" --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash && \
		cargo binstall cargo-generate-rpm --no-confirm && \
		make -e profile=$(profile) -e channel=$(channel) -e target=$(target) -e distro=$(distro) package-rpm'

package-deb-podman:
ifndef distro
	$(error distro is required, e.g., make package-deb-podman distro=bookworm)
endif
	@echo "=== Building DEB for $(distro) ($(arch)) ==="
	podman run --rm -v $(CURDIR):/src:Z -w /src $(debian_image_$(distro)) bash -c '\
		apt-get update && \
		apt-get install -y make clang lld curl tar gzip gettext libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev pkg-config && \
		curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
		source $$HOME/.cargo/env && \
		curl -L --proto "=https" --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash && \
		cargo binstall cargo-deb --no-confirm && \
		make -e profile=$(profile) -e channel=$(channel) -e target=$(target) -e distro=$(distro) package-deb'

package-rpm-all:
	@for v in $(fedora_versions); do \
		$(MAKE) -e profile=$(profile) -e channel=$(channel) -e target=$(target) -e distro=$$v package-rpm-podman; \
	done

package-deb-all:
	@for v in $(debian_versions); do \
		$(MAKE) -e profile=$(profile) -e channel=$(channel) -e target=$(target) -e 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 \
		$(call sign_and_deploy,$(filename)-$$v.rpm); \
	done

distribute-deb:
	@for v in $(debian_versions); do \
		$(call sign_and_deploy,$(filename)-$$v.deb); \
	done

distribute: distribute-tar distribute-flatpak distribute-appimage distribute-pacman distribute-rpm distribute-deb

# Release ######################################################################

release: lint 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

.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