aboutsummaryrefslogtreecommitdiff
path: root/Makefile
blob: 587d164a1c567fbfc3fdd8dabe4ea6c29b55651d (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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
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
# Note: bullseye excluded - no GTK4/libadwaita packages available
debian_versions := bookworm 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-%:
	@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 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 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