Simple Makefile for elementary OS Apps
Can't remember all the commands for initializing, building, translating and linting elementary OS Apps? Me neither!
I have a terrible time trying to remember all the various commands for setting up a Flatpak application for development on a clean system, building a Flatpak application, generating updated translations files, AND running the Vala linter. I’d much prefer to remember one basic command. Thank goodness for makefiles!
Before pointing out some of the little features, here’s the Makefile that I use in most of my projects - only needing to change the APP_ID
at the top:
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
SHELL := /bin/bash
APP_ID := com.github.avojak.warble
FLATPAK_REMOTE_URL := https://flatpak.elementary.io/repo.flatpakrepo
FLATPAK_REMOTE_NAME := appcenter
PLATFORM_VERSION := 7
BUILD_DIR := build
NINJA_BUILD_FILE := $(BUILD_DIR)/build.ninja
FLATPAK_BUILDER_FLAGS := --user --install --force-clean
ifdef OFFLINE_BUILD
FLATPAK_BUILDER_FLAGS += --disable-download
endif
# Check for executables which are assumed to already be present on the system
EXECUTABLES = flatpak flatpak-builder
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH")))
.DEFAULT_GOAL := flatpak
.PHONY: all
all: translations flatpak
.PHONY: flatpak-init
flatpak-init:
flatpak remote-add --if-not-exists --system $(FLATPAK_REMOTE_NAME) $(FLATPAK_REMOTE_URL)
flatpak install -y --user $(FLATPAK_REMOTE_NAME) io.elementary.Platform//$(PLATFORM_VERSION)
flatpak install -y --user $(FLATPAK_REMOTE_NAME) io.elementary.Sdk//$(PLATFORM_VERSION)
.PHONY: init
init: flatpak-init
.PHONY: flatpak
flatpak:
flatpak-builder build $(APP_ID).yml $(FLATPAK_BUILDER_FLAGS)
.PHONY: lint
lint:
io.elementary.vala-lint ./src
$(NINJA_BUILD_FILE):
meson build --prefix=/user
.PHONY: translations
translations: $(NINJA_BUILD_FILE)
ninja -C build $(APP_ID)-pot
ninja -C build $(APP_ID)-update-po
.PHONY: clean
clean:
rm -rf ./.flatpak-builder/
rm -rf ./build/
rm -rf ./builddir/
With that in place, building an app is as simple as:
1
2
$ make init # Only once!
$ make
Features
The most significant feature here for me was adding the OFFLINE_BUILD
option. Periodically I’ve run into scenarios where pulling something from gitlab.gnome.org
will fail for 15+ minutes at a time. That’s no good, so being able to easily build entirely from the local cache is a big plus!
1
$ make OFFLINE_BUILD=
Including the linter is a nice touch as well. Often I would defer linter checks until I pushed code and waited for a GitHub action to send me an angry email. No more!
1
$ make lint
Drawbacks
I wouldn’t say that there are many drawbacks to this approach, however some people may say that this isn’t really doing things the make
way, since almost every rule is PHONY
. And to that I’d say I don’t really care - it makes my life easier!
Due to the way that Flatpak creates the build output I haven’t found a better way to optimize this Makefile. Plus, the Flatpak build itself handles a lot of caching to prevent repeat builds of dependencies.
Bonus: “Run” Script!
As an added bonus, here’s a little script that most of my projects use as well to simplify running apps in various modes:
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
EXTRA_ARGS=
if [[ "$1" == "--debug" ]]; then
EXTRA_ARGS="--env=GTK_DEBUG=interactive"
fi
if [[ "$1" == "--inspect" ]]; then
EXTRA_ARGS="--command=sh --devel"
fi
flatpak run --env=G_MESSAGES_DEBUG=all $EXTRA_ARGS com.github.avojak.warble ${@:2}
After using a simple make
to build the app, I can then just call: ./run
- 99% of the time I want to see all the debug messages anyway, so I no longer need to remember to type all that out!
- Want to debug some GTK stuff? Use:
./run --debug
- Some files not quite right in the sandbox? Check them out with:
./run --inspect
Other arguments/options can be tacked on as well thanks to the bit of BASH magic at the end: ${@:2}