CC=gcc

## The tray icon needs Ayatana AppIndicator3 (StatusNotifierItem). Fail early
## with a useful message instead of a wall of "unknown type name" errors.
PKGS := gtk+-3.0 ayatana-appindicator3-0.1
ifneq ($(shell pkg-config --exists $(PKGS) && echo ok),ok)
$(error missing development packages, need: $(PKGS) \
  (Debian: libgtk-3-dev libayatana-appindicator3-dev, \
   Fedora: gtk3-devel libayatana-appindicator-gtk3-devel, \
   Arch: gtk3 libayatana-appindicator))
endif

CFLAGS := $(shell pkg-config --cflags $(PKGS))
LIBS   := $(shell pkg-config --libs $(PKGS))
BUILDFLAGS = -std=c99 -O3 -Wall -Werror

## Build time customization, all are include files in src/ and all are set
## per target below, so a value from the environment cannot leak into another
## build. Passing them on the command line still works, for example:
##   make ministart BUTTONS_FILE=some-buttons.c
##
## BUTTONS_FILE      : the buttons compiled into the binary
## CONFIG_LOGIC_FILE : the build specific configuration logic, see main.c
## CONFIG_DIALOG_FILE: the configuration dialog behind the Config button, see
##                     main.c; empty: no dialog and no Config button
## MANUAL_FILE       : the manual shown by --manual, see main.c; empty: none
BUTTONS_SRC       = src/$(if $(BUTTONS_FILE),$(BUTTONS_FILE),default-buttons.c)
CONFIG_LOGIC_SRC  = src/$(if $(CONFIG_LOGIC_FILE),$(CONFIG_LOGIC_FILE),default-config-logic.c)
CONFIG_DIALOG_SRC = $(if $(CONFIG_DIALOG_FILE),src/$(CONFIG_DIALOG_FILE) src/gnupg-config-write.c src/gnupg-config-template.h)
MANUAL_SRC        = $(if $(MANUAL_FILE),src/$(MANUAL_FILE))

BUILD_DEFS = $(if $(BUTTONS_FILE),-DBUTTONS_FILE='"$(BUTTONS_FILE)"') \
	$(if $(CONFIG_LOGIC_FILE),-DCONFIG_LOGIC_FILE='"$(CONFIG_LOGIC_FILE)"') \
	$(if $(CONFIG_DIALOG_FILE),-DCONFIG_DIALOG_FILE='"$(CONFIG_DIALOG_FILE)"') \
	$(if $(MANUAL_FILE),-DMANUAL_FILE='"$(MANUAL_FILE)"')

## "make install" destinations. TARGET picks which binary gets installed
## ("ministart" or "gnupg/ministart"), the *DIR variables where it and its
## icons/config go. Override on the command line, for example:
##   make TARGET=gnupg/ministart BINDIR=$(APPDIR)/usr/bin \
##        ICONSDIR=$(APPDIR)/usr/share/icons CONFIGDIR=$(APPDIR)/usr/etc install
TARGET    ?= ministart
PREFIX    ?= /usr/local
BINDIR    ?= $(DESTDIR)$(PREFIX)/bin
ICONSDIR  ?= $(DESTDIR)$(PREFIX)/share/icons
CONFIGDIR ?= $(DESTDIR)$(PREFIX)/etc

.PHONY: all clean archive gnupg test-appimage test-appimage-desktop \
	test-appimage-gpg4linux test-appimage-help help install vars BEHIND \
	test-appimage-manual

.DEFAULT_GOAL := help

help:
	@echo "Available targets:"
	@echo "  help                show this help message"
	@echo "  ministart           build the standard Linux binary"
	@echo "  gnupg               build the GnuPG binary (shorthand for gnupg/ministart)"
	@echo "  all                 build both ministart and gnupg"
	@echo "  test-appimage            build+run gnupg/ministart as VS-Desktop, with APPDIR and VERSION file"
	@echo "  test-appimage-desktop    same, as the GnuPG Desktop flavor"
	@echo "  test-appimage-gpg4linux  same, as the Gpg4linux flavor"
	@echo "  test-appimage-help       build+run gnupg/ministart and show --help"
	@echo "  archive             create a source tarball via git archive"
	@echo "  clean               remove build artifacts"
	@echo "  install             install binary, icons and config."
	@echo ""
	@echo "Example Installation:"
	@echo "      make DESTDIR=/usr/local/ install"
	@echo "  or"
	@echo "      make TARGET=gnupg/ministart BINDIR=/usr/local/bin \\"
	@echo "           ICONSDIR=/usr/local/share/icons \\"
	@echo "           CONFIGDIR=/usr/local/etc  install"

## -- build targets --

## "ministart" is the standard Linux build, "gnupg/ministart" the build for
## the GnuPG AppImages. One binary serves all GnuPG flavors: VS-Desktop,
## Desktop and Gpg4linux are told apart at runtime, see src/gnupg-config.c.

ministart: BUTTONS_FILE       =
ministart: CONFIG_LOGIC_FILE  =
ministart: CONFIG_DIALOG_FILE =
ministart: MANUAL_FILE        =

gnupg/ministart: BUTTONS_FILE       = gnupg-buttons.c
gnupg/ministart: CONFIG_LOGIC_FILE  = gnupg-config.c
gnupg/ministart: CONFIG_DIALOG_FILE = gnupg-config-dialog.c
gnupg/ministart: MANUAL_FILE        = gnupg-manual.h

BEHIND:
	./git-behind.sh

## The template of the configuration dialog is built into the binary as one C
## string, one string literal per line.
src/gnupg-config-template.h: config_template/ministart.config_dialog_template
	{ echo '/* Generated from $<, do not edit. */'; \
	  echo 'static const char config_template_text[] ='; \
	  sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/  "/' -e 's/$$/\\n"/' $<; \
	  echo '  ;'; } > $@

## The manuals of the GnuPG AppImages are built into the binary the same way,
## one C string per language, shown by --manual.
src/gnupg-manual.h: GnuPG_Appimage_Starter_Manual_EN.md GnuPG_Appimage_Starter_Manual_DE.md
	{ echo '/* Generated from $^, do not edit. */'; \
	  echo 'static const char manual_text_en[] ='; \
	  sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/  "/' -e 's/$$/\\n"/' GnuPG_Appimage_Starter_Manual_EN.md; \
	  echo '  ;'; \
	  echo 'static const char manual_text_de[] ='; \
	  sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/  "/' -e 's/$$/\\n"/' GnuPG_Appimage_Starter_Manual_DE.md; \
	  echo '  ;'; } > $@

src/version.h: VERSION BEHIND
	printf '%s\n' "#define VERSION \"$(shell cat VERSION)$(shell cat BEHIND)\"" > $@

## The include files are prerequisites too, so a change to them rebuilds.
## They depend on the target specific variables above, hence the second
## expansion.
.SECONDEXPANSION:
ministart gnupg/ministart: src/main.c src/info.c src/version.h $$(BUTTONS_SRC) $$(CONFIG_LOGIC_SRC) $$(CONFIG_DIALOG_SRC) $$(MANUAL_SRC) vars
	@mkdir -p $(@D)
	$(CC) $(BUILDFLAGS) -o $@ src/main.c $(CFLAGS) $(LIBS) $(BUILD_DEFS)

## Shorthand, so "make gnupg" works instead of "make gnupg/ministart".
gnupg: gnupg/ministart
	@:

all: ministart gnupg

## --- helper targets --

vars:
	@echo "** Build Variables **"
	@echo "CFLAGS            : $(CFLAGS)"
	@echo "LIBS              : $(LIBS)"
	@echo "BUILDFLAGS        : $(BUILDFLAGS)"
	@echo "BUTTONS_FILE      : $(BUTTONS_FILE)"
	@echo "CONFIG_LOGIC_FILE : $(CONFIG_LOGIC_FILE)"
	@echo "CONFIG_DIALOG_FILE: $(CONFIG_DIALOG_FILE)"
	@echo "MANUAL_FILE       : $(MANUAL_FILE)"
	@echo "TARGET            : $(TARGET)"
	@echo "PREFIX            : $(PREFIX)"
	@echo "BINDIR            : $(BINDIR)"
	@echo "ICONSDIR          : $(ICONSDIR)"
	@echo "CONFIGDIR         : $(CONFIGDIR)"
	@echo "TARGET            : $(TARGET)"

## test-appimage, test-appimage-desktop and test-appimage-gpg4linux run the
## gnupg build in a fake AppDir with just that flavor's VERSION file, so
## each GnuPG flavor can be checked without a real AppImage build. The
## AppDir is recreated every time, so a stale VERSION file of another
## flavor never lingers.
test-appimage:           VERSION_FILE = GnuPG-VS-Desktop-VERSION
test-appimage-desktop:   VERSION_FILE = GnuPG-Desktop-VERSION
test-appimage-gpg4linux: VERSION_FILE = Gpg4linux-VERSION

test-appimage test-appimage-desktop test-appimage-gpg4linux: gnupg/ministart
	@echo "** with APPDIR=/tmp/ministart-appdir and $(VERSION_FILE) file"
	rm -rf /tmp/ministart-appdir
	mkdir -p /tmp/ministart-appdir
	echo "Test-Virt-GPG-AppImage" > /tmp/ministart-appdir/$(VERSION_FILE)
	mkdir -p /tmp/ministart-appdir/usr/share
	ln -sfn $(CURDIR)/config_template/icons /tmp/ministart-appdir/usr/share/icons
	mkdir -p /tmp/ministart-appdir/usr/etc
	cp $(CURDIR)/config_template/ministart.config_template /tmp/ministart-appdir/usr/etc/ministart.config
	cp $(CURDIR)/config_template/ministart-late.config_template /tmp/ministart-appdir/usr/etc/ministart-late.config
	APPDIR=/tmp/ministart-appdir ./$< -v -v --verbose

test-appimage-help: gnupg/ministart
	@echo "** with APPDIR=/tmp/ministart-appdir"
	mkdir -p /tmp/ministart-appdir
	APPDIR=/tmp/ministart-appdir ./$< --help
	@echo "** with GnuPG-VS-Desktop-VERSION file:"
	touch /tmp/ministart-appdir/GnuPG-VS-Desktop-VERSION
	APPDIR=/tmp/ministart-appdir ./$< --help
	@echo "** without APPDIR **"
	./$< --help
#	APPDIR=/tmp/ministart-appdir ./$< --help | \
#	grep -E 'Current icons path:[[:space:]]+/tmp/ministart-appdir/usr/share/icons'

test-appimage-manual: gnupg/ministart
	mkdir -p /tmp/ministart-appdir
	touch /tmp/ministart-appdir/GnuPG-Desktop-VERSION
	APPDIR=/tmp/ministart-appdir ./$< --manual

archive: all
	git archive --format=tar.gz -o ../ministart-$(shell cat VERSION).tar.gz --prefix=ministart/ HEAD

clean:
	rm -f ministart src/version.h src/gnupg-config-template.h src/gnupg-manual.h
	rm -rf gnupg

install: $(TARGET)
	mkdir -p $(BINDIR) $(ICONSDIR) $(CONFIGDIR)
	cp $(TARGET) $(BINDIR)/ministart
	cp -r config_template/icons/* $(ICONSDIR)/
	cp config_template/ministart.config_template $(CONFIGDIR)/ministart.config
	cp config_template/ministart-late.config_template $(CONFIGDIR)/ministart-late.config
	cp config_template/ministart.config_admin_template $(CONFIGDIR)/ministart.config_admin_template
	cp config_template/ministart-late.config_admin_template $(CONFIGDIR)/ministart-late.config_admin_template

# EOF
