mk: deprecate BSD make in favor of GNU make

Being portable between BSD and GNU make is a nightmare. It restricts
features to a very minimal surface and in turn requires a lot of code
duplication and manual updating of file lists.

Worse, aerc's makefile relies on the shell assignment operator (!=)
which has been supported by BSD make 2.2 since 1997 but GNU make 4.0
since 2013. Unfortunately, MacOS runs GNU make 3.8 which does not have
that feature. Reducing the feature set even more.

Stop that nonsense and remove BSD make compatibility. The majority of
aerc's users either run a GNU Linux distribution or MacOS. For those who
run any *BSD variant, it is easy for them to install GNU make (gmake) if
they don't have it installed already.

Use GNU make constructs to generate build and install rules dynamically
based on source files discovery.

GNU make will use "GNUmakefile" in priority over "Makefile" if possible.
Leverage this to display an explicit message when other flavours of make
are used. Leave a "Makefile" with a .DEFAULT: target and rename the
actual file to "GNUmakefile".

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
This commit is contained in:
Robin Jarry
2023-08-02 21:37:25 +02:00
parent 2788078187
commit d725defa07
5 changed files with 218 additions and 224 deletions

View File

@@ -1,8 +1,10 @@
--- ---
image: openbsd/latest image: openbsd/latest
packages: packages:
- go - base64
- gmake
- gnupg - gnupg
- go
- scdoc - scdoc
sources: sources:
- "https://git.sr.ht/~rjarry/aerc" - "https://git.sr.ht/~rjarry/aerc"
@@ -11,8 +13,8 @@ environment:
tasks: tasks:
- build: | - build: |
cd aerc cd aerc
make gmake
- install: | - install: |
cd aerc cd aerc
make install gmake install
make checkinstall gmake checkinstall

View File

@@ -43,6 +43,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `:export-mbox` only exports marked messages, if any. Otherwise it exports - `:export-mbox` only exports marked messages, if any. Otherwise it exports
everything, as usual. everything, as usual.
### Deprecated
- Aerc can no longer be compiled and installed with BSD make. GNU make must be
used instead.
## [0.15.2](https://git.sr.ht/~rjarry/aerc/refs/0.15.2) - 2023-05-11 ## [0.15.2](https://git.sr.ht/~rjarry/aerc/refs/0.15.2) - 2023-05-11
### Fixed ### Fixed

199
GNUmakefile Normal file
View File

@@ -0,0 +1,199 @@
# variables that can be changed by users
#
VERSION ?= `git describe --long --abbrev=12 --tags --dirty 2>/dev/null || echo 0.15.2`
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
SHAREDIR ?= $(PREFIX)/share/aerc
LIBEXECDIR ?= $(PREFIX)/libexec/aerc
MANDIR ?= $(PREFIX)/share/man
GO ?= go
GOFLAGS ?= `contrib/goflags.sh`
BUILD_OPTS ?= -trimpath
GO_LDFLAGS :=
GO_LDFLAGS += -X main.Version=$(VERSION)
GO_LDFLAGS += -X main.Flags=$$(echo -- $(GOFLAGS) | base64 | tr -d '\r\n')
GO_LDFLAGS += -X git.sr.ht/~rjarry/aerc/config.shareDir=$(SHAREDIR)
GO_LDFLAGS += -X git.sr.ht/~rjarry/aerc/config.libexecDir=$(LIBEXECDIR)
GO_LDFLAGS += $(GO_EXTRA_LDFLAGS)
CC ?= cc
CFLAGS ?= -O2 -g
# internal variables used for automatic rules generation with macros
gosrc = $(shell find * -type f -name '*.go') go.mod go.sum
man1 = $(subst .scd,,$(notdir $(wildcard doc/*.1.scd)))
man5 = $(subst .scd,,$(notdir $(wildcard doc/*.5.scd)))
man7 = $(subst .scd,,$(notdir $(wildcard doc/*.7.scd)))
docs = $(man1) $(man5) $(man7)
cfilters = $(subst .c,,$(notdir $(wildcard filters/*.c)))
filters = $(filter-out filters/vectors filters/test.sh filters/%.c,$(wildcard filters/*))
gofumpt_tag = v0.5.0
# Dependencies are added dynamically to the "all" rule with macros
.PHONY: all
all: aerc
@:
aerc: $(gosrc)
$(GO) build $(BUILD_OPTS) $(GOFLAGS) -ldflags "$(GO_LDFLAGS)" -o aerc
.PHONY: dev
dev:
$(RM) aerc
$(MAKE) --no-print-directory aerc BUILD_OPTS="-trimpath -race"
GORACE="log_path=race.log strip_path_prefix=git.sr.ht/~rjarry/aerc/" ./aerc
.PHONY: fmt
fmt:
$(GO) run mvdan.cc/gofumpt@$(gofumpt_tag) -w .
linters.so: contrib/linters.go
$(GO) build -buildmode=plugin -o linters.so contrib/linters.go
.PHONY: lint
lint: linters.so
@contrib/check-whitespace `git ls-files ':!:filters/vectors'` && \
echo white space ok.
@$(GO) run mvdan.cc/gofumpt@$(gofumpt_tag) -d . | grep ^ \
&& echo The above files need to be formatted, please run make fmt && exit 1 \
|| echo all files formatted.
$(GO) run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.2 run \
$$(echo $(GOFLAGS) | sed s/-tags=/--build-tags=/)
.PHONY: vulncheck
vulncheck:
$(GO) run golang.org/x/vuln/cmd/govulncheck@latest ./...
.PHONY: tests
tests: $(cfilters)
$(GO) test $(GOFLAGS) ./...
filters/test.sh
.PHONY: debug
debug: aerc.debug
@echo 'Run `./aerc.debug` and use this command in another terminal to attach a debugger:'
@echo ' dlv attach $$(pidof aerc.debug)'
aerc.debug: $(gosrc)
$(GO) build $(GOFLAGS) -gcflags=*=-N -gcflags=*=-l -ldflags="$(GO_LDFLAGS)" -o aerc.debug
.PHONY: doc
doc: $(docs)
@:
.PHONY: clean
clean:
$(RM) $(docs) aerc $(cfilters)
# Dependencies are added dynamically to the "install" rule with macros
.PHONY: install
install:
@:
.PHONY: checkinstall
checkinstall:
$(DESTDIR)$(BINDIR)/aerc -v
for m in $(man1); do test -e $(DESTDIR)$(MANDIR)/man1/$$m || exit; done
for m in $(man5); do test -e $(DESTDIR)$(MANDIR)/man5/$$m || exit; done
for m in $(man7); do test -e $(DESTDIR)$(MANDIR)/man7/$$m || exit; done
.PHONY: uninstall
uninstall:
@echo $(installed) | tr ' ' '\n' | sort -ru | while read -r f; do \
echo rm -f $$f && rm -f $$f || exit; \
done
@echo $(dirs) | tr ' ' '\n' | sort -ru | while read -r d; do \
if [ -d $$d ] && ! ls -Aq1 $$d | grep -q .; then \
echo rm $$d && rmdir $$d || exit; \
fi; \
done
.PHONY: gitconfig
gitconfig:
git config format.subjectPrefix "PATCH aerc"
git config sendemail.to "~rjarry/aerc-devel@lists.sr.ht"
@mkdir -p .git/hooks
@rm -f .git/hooks/sendemail-validate*
@if grep -q GIT_SENDEMAIL_FILE_COUNTER `git --exec-path`/git-send-email 2>/dev/null; then \
ln -svf ../../contrib/sendemail-validate .git/hooks/sendemail-validate && \
git config sendemail.validate true; \
fi
.PHONY: check-patches
check-patches:
@contrib/check-patches origin/master..
# Generate build and install rules for one man page
#
# $1: man page name (e.g: aerc.1)
#
define install_man
$1: doc/$1.scd
scdoc < $$< > $$@
$1_section = $$(subst .,,$$(suffix $1))
$1_install_dir = $$(DESTDIR)$$(MANDIR)/man$$($1_section)
dirs += $$($1_install_dir)
installed += $$($1_install_dir)/$1
$$($1_install_dir)/$1: $1 | $$($1_install_dir)
install -m644 $$< $$@
all: $1
install: $$($1_install_dir)/$1
endef
# Generate build and install rules for one filter
#
# $1: filter source path or name
#
define install_filter
ifneq ($(wildcard filters/$1.c),)
$1: filters/$1.c
$$(CC) $$(CFLAGS) $$(LDFLAGS) -o $$@ $$<
all: $1
endif
$1_install_dir = $$(DESTDIR)$$(LIBEXECDIR)/filters
dirs += $$($1_install_dir)
installed += $$($1_install_dir)/$$(notdir $1)
$$($1_install_dir)/$$(notdir $1): $1 | $$($1_install_dir)
install -m755 $$< $$@
install: $$($1_install_dir)/$$(notdir $1)
endef
# Generate install rules for any file
#
# $1: source file
# $2: mode
# $3: target dir
#
define install_file
dirs += $3
installed += $3/$$(notdir $1)
$3/$$(notdir $1): $1 | $3
install -m$2 $$< $$@
install: $3/$$(notdir $1)
endef
# Call macros to generate build and install rules
$(foreach m,$(docs),\
$(eval $(call install_man,$m)))
$(foreach f,$(filters) $(cfilters),\
$(eval $(call install_filter,$f)))
$(foreach f,$(wildcard config/*.conf),\
$(eval $(call install_file,$f,644,$(DESTDIR)$(SHAREDIR))))
$(foreach s,$(wildcard stylesets/*),\
$(eval $(call install_file,$s,644,$(DESTDIR)$(SHAREDIR)/stylesets)))
$(foreach t,$(wildcard templates/*),\
$(eval $(call install_file,$t,644,$(DESTDIR)$(SHAREDIR)/templates)))
$(eval $(call install_file,contrib/aerc.desktop,644,$(DESTDIR)$(PREFIX)/share/applications))
$(eval $(call install_file,aerc,755,$(DESTDIR)$(BINDIR)))
$(eval $(call install_file,contrib/carddav-query,755,$(DESTDIR)$(BINDIR)))
$(sort $(dirs)):
mkdir -p $@

227
Makefile
View File

@@ -1,220 +1,7 @@
.POSIX: # This file is only left here for explicit error about GNU make requirement
.SUFFIXES: # when building with other make flavours.
.SUFFIXES: .1 .5 .7 .1.scd .5.scd .7.scd #
# Do not edit this file. Edit GNUmakefile instead.
VERSION?=`git describe --long --abbrev=12 --tags --dirty 2>/dev/null || echo 0.15.2` .PHONY: all
VPATH=doc all .DEFAULT:
PREFIX?=/usr/local @echo "Please build and install using GNU make (gmake)"; exit 1
BINDIR?=$(PREFIX)/bin
SHAREDIR?=$(PREFIX)/share/aerc
LIBEXECDIR?=$(PREFIX)/libexec/aerc
MANDIR?=$(PREFIX)/share/man
GO?=go
GOFLAGS?=`contrib/goflags.sh`
BUILD_OPTS?=-trimpath
# ignore environment variable
GO_LDFLAGS:=
GO_LDFLAGS+=-X main.Version=$(VERSION)
GO_LDFLAGS+=-X main.Flags=$$(echo -- $(GOFLAGS) | base64 | tr -d '\r\n')
GO_LDFLAGS+=-X git.sr.ht/~rjarry/aerc/config.shareDir=$(SHAREDIR)
GO_LDFLAGS+=-X git.sr.ht/~rjarry/aerc/config.libexecDir=$(LIBEXECDIR)
GO_LDFLAGS+=$(GO_EXTRA_LDFLAGS)
GOSRC!=find * -type f -name '*.go'
GOSRC+=go.mod go.sum
DOCS := \
aerc.1 \
aerc-search.1 \
aerc-accounts.5 \
aerc-binds.5 \
aerc-config.5 \
aerc-imap.5 \
aerc-jmap.5 \
aerc-maildir.5 \
aerc-sendmail.5 \
aerc-notmuch.5 \
aerc-smtp.5 \
aerc-tutorial.7 \
aerc-templates.7 \
aerc-stylesets.7 \
carddav-query.1
all: aerc wrap colorize $(DOCS)
aerc: $(GOSRC)
$(GO) build $(BUILD_OPTS) $(GOFLAGS) -ldflags "$(GO_LDFLAGS)" -o aerc
CC?=cc
CFLAGS?=-O2 -g
wrap: filters/wrap.c
$(CC) $(CFLAGS) $(LDFLAGS) -o wrap filters/wrap.c
colorize: filters/colorize.c
$(CC) $(CFLAGS) $(LDFLAGS) -o colorize filters/colorize.c
.PHONY: dev
dev:
$(MAKE) aerc BUILD_OPTS="-trimpath -race"
GORACE="log_path=race.log strip_path_prefix=git.sr.ht/~rjarry/aerc/" ./aerc
gofumpt_tag = v0.5.0
.PHONY: fmt
fmt:
$(GO) run mvdan.cc/gofumpt@$(gofumpt_tag) -w .
linters.so: contrib/linters.go
$(GO) build -buildmode=plugin -o linters.so contrib/linters.go
.PHONY: lint
lint: linters.so
@contrib/check-whitespace `git ls-files ':!:filters/vectors'` && \
echo white space ok.
@$(GO) run mvdan.cc/gofumpt@$(gofumpt_tag) -d . | grep ^ \
&& echo The above files need to be formatted, please run make fmt && exit 1 \
|| echo all files formatted.
$(GO) run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.2 run \
$$(echo $(GOFLAGS) | sed s/-tags=/--build-tags=/)
.PHONY: vulncheck
vulncheck:
$(GO) run golang.org/x/vuln/cmd/govulncheck@latest ./...
.PHONY: tests
tests: wrap colorize
$(GO) test $(GOFLAGS) ./...
filters/test.sh
.PHONY: debug
debug: aerc.debug
@echo 'Run `./aerc.debug` and use this command in another terminal to attach a debugger:'
@echo ' dlv attach $$(pidof aerc.debug)'
aerc.debug: $(GOSRC)
$(GO) build $(GOFLAGS) -gcflags=*=-N -gcflags=*=-l -ldflags="$(GO_LDFLAGS)" -o aerc.debug
.1.scd.1:
scdoc < $< > $@
.5.scd.5:
scdoc < $< > $@
.7.scd.7:
scdoc < $< > $@
doc: $(DOCS)
# Exists in GNUMake but not in NetBSD make and others.
RM?=rm -f
clean:
$(RM) $(DOCS) aerc wrap colorize
install: $(DOCS) aerc wrap colorize
@# `install -D` is not supported on all platforms (macos install(1)
@# dates back to the middle ages and does not have this flag).
@# The folders must be created manually first.
mkdir -m755 -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1 $(DESTDIR)$(MANDIR)/man5 $(DESTDIR)$(MANDIR)/man7 \
$(DESTDIR)$(SHAREDIR)/templates $(DESTDIR)$(SHAREDIR)/stylesets \
$(DESTDIR)$(PREFIX)/share/applications $(DESTDIR)$(LIBEXECDIR)/filters
install -m755 aerc $(DESTDIR)$(BINDIR)/aerc
install -m755 contrib/carddav-query $(DESTDIR)$(BINDIR)/carddav-query
install -m644 aerc.1 $(DESTDIR)$(MANDIR)/man1/aerc.1
install -m644 carddav-query.1 $(DESTDIR)$(MANDIR)/man1/carddav-query.1
install -m644 aerc-search.1 $(DESTDIR)$(MANDIR)/man1/aerc-search.1
install -m644 aerc-accounts.5 $(DESTDIR)$(MANDIR)/man5/aerc-accounts.5
install -m644 aerc-binds.5 $(DESTDIR)$(MANDIR)/man5/aerc-binds.5
install -m644 aerc-config.5 $(DESTDIR)$(MANDIR)/man5/aerc-config.5
install -m644 aerc-imap.5 $(DESTDIR)$(MANDIR)/man5/aerc-imap.5
install -m644 aerc-jmap.5 $(DESTDIR)$(MANDIR)/man5/aerc-jmap.5
install -m644 aerc-maildir.5 $(DESTDIR)$(MANDIR)/man5/aerc-maildir.5
install -m644 aerc-sendmail.5 $(DESTDIR)$(MANDIR)/man5/aerc-sendmail.5
install -m644 aerc-notmuch.5 $(DESTDIR)$(MANDIR)/man5/aerc-notmuch.5
install -m644 aerc-smtp.5 $(DESTDIR)$(MANDIR)/man5/aerc-smtp.5
install -m644 aerc-tutorial.7 $(DESTDIR)$(MANDIR)/man7/aerc-tutorial.7
install -m644 aerc-templates.7 $(DESTDIR)$(MANDIR)/man7/aerc-templates.7
install -m644 aerc-stylesets.7 $(DESTDIR)$(MANDIR)/man7/aerc-stylesets.7
install -m644 config/accounts.conf $(DESTDIR)$(SHAREDIR)/accounts.conf
install -m644 config/aerc.conf $(DESTDIR)$(SHAREDIR)/aerc.conf
install -m644 config/binds.conf $(DESTDIR)$(SHAREDIR)/binds.conf
install -m755 filters/calendar $(DESTDIR)$(LIBEXECDIR)/filters/calendar
install -m755 filters/hldiff $(DESTDIR)$(LIBEXECDIR)/filters/hldiff
install -m755 filters/html $(DESTDIR)$(LIBEXECDIR)/filters/html
install -m755 filters/html-unsafe $(DESTDIR)$(LIBEXECDIR)/filters/html-unsafe
install -m755 filters/plaintext $(DESTDIR)$(LIBEXECDIR)/filters/plaintext
install -m755 filters/show-ics-details.py $(DESTDIR)$(LIBEXECDIR)/filters/show-ics-details.py
install -m755 colorize $(DESTDIR)$(LIBEXECDIR)/filters/colorize
install -m755 wrap $(DESTDIR)$(LIBEXECDIR)/filters/wrap
install -m644 templates/new_message $(DESTDIR)$(SHAREDIR)/templates/new_message
install -m644 templates/quoted_reply $(DESTDIR)$(SHAREDIR)/templates/quoted_reply
install -m644 templates/forward_as_body $(DESTDIR)$(SHAREDIR)/templates/forward_as_body
install -m644 stylesets/default $(DESTDIR)$(SHAREDIR)/stylesets/default
install -m644 stylesets/dracula $(DESTDIR)$(SHAREDIR)/stylesets/dracula
install -m644 stylesets/nord $(DESTDIR)$(SHAREDIR)/stylesets/nord
install -m644 stylesets/pink $(DESTDIR)$(SHAREDIR)/stylesets/pink
install -m644 stylesets/blue $(DESTDIR)$(SHAREDIR)/stylesets/blue
install -m644 stylesets/solarized $(DESTDIR)$(SHAREDIR)/stylesets/solarized
install -m644 contrib/aerc.desktop $(DESTDIR)$(PREFIX)/share/applications/aerc.desktop
.PHONY: checkinstall
checkinstall:
$(DESTDIR)$(BINDIR)/aerc -v
test -e $(DESTDIR)$(MANDIR)/man1/aerc.1
test -e $(DESTDIR)$(MANDIR)/man5/aerc-accounts.5
test -e $(DESTDIR)$(MANDIR)/man5/aerc-binds.5
test -e $(DESTDIR)$(MANDIR)/man5/aerc-config.5
test -e $(DESTDIR)$(MANDIR)/man5/aerc-imap.5
test -e $(DESTDIR)$(MANDIR)/man5/aerc-jmap.5
test -e $(DESTDIR)$(MANDIR)/man5/aerc-notmuch.5
test -e $(DESTDIR)$(MANDIR)/man5/aerc-sendmail.5
test -e $(DESTDIR)$(MANDIR)/man5/aerc-smtp.5
test -e $(DESTDIR)$(MANDIR)/man7/aerc-tutorial.7
test -e $(DESTDIR)$(MANDIR)/man7/aerc-templates.7
RMDIR_IF_EMPTY:=sh -c '! [ -d $$0 ] || ls -1qA $$0 | grep -q . || rmdir $$0'
uninstall:
$(RM) $(DESTDIR)$(BINDIR)/aerc
$(RM) $(DESTDIR)$(BINDIR)/carddav-query
$(RM) $(DESTDIR)$(MANDIR)/man1/aerc.1
$(RM) $(DESTDIR)$(MANDIR)/man1/aerc-search.1
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-accounts.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-binds.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-config.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-imap.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-jmap.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-maildir.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-sendmail.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-notmuch.5
$(RM) $(DESTDIR)$(MANDIR)/man5/aerc-smtp.5
$(RM) $(DESTDIR)$(MANDIR)/man7/aerc-tutorial.7
$(RM) $(DESTDIR)$(MANDIR)/man7/aerc-templates.7
$(RM) $(DESTDIR)$(MANDIR)/man7/aerc-stylesets.7
$(RM) -r $(DESTDIR)$(SHAREDIR)
$(RM) -r $(DESTDIR)$(LIBEXECDIR)
${RMDIR_IF_EMPTY} $(DESTDIR)$(BINDIR)
$(RMDIR_IF_EMPTY) $(DESTDIR)$(MANDIR)/man1
$(RMDIR_IF_EMPTY) $(DESTDIR)$(MANDIR)/man5
$(RMDIR_IF_EMPTY) $(DESTDIR)$(MANDIR)/man7
$(RMDIR_IF_EMPTY) $(DESTDIR)$(MANDIR)
$(RM) $(DESTDIR)$(PREFIX)/share/applications/aerc.desktop
$(RMDIR_IF_EMPTY) $(DESTDIR)$(PREFIX)/share/applications
.PHONY: gitconfig
gitconfig:
git config format.subjectPrefix "PATCH aerc"
git config sendemail.to "~rjarry/aerc-devel@lists.sr.ht"
@mkdir -p .git/hooks
@rm -f .git/hooks/sendemail-validate*
@if grep -q GIT_SENDEMAIL_FILE_COUNTER `git --exec-path`/git-send-email 2>/dev/null; then \
ln -svf ../../contrib/sendemail-validate .git/hooks/sendemail-validate && \
git config sendemail.validate true; \
fi
.PHONY: check-patches
check-patches:
@contrib/check-patches origin/master..
.PHONY: all doc clean install uninstall debug

View File

@@ -72,6 +72,7 @@ Install the dependencies:
older versions may be dropped at any time due to incompatibilities or newer older versions may be dropped at any time due to incompatibilities or newer
required language features.)* required language features.)*
- [scdoc](https://git.sr.ht/~sircmpwn/scdoc) - [scdoc](https://git.sr.ht/~sircmpwn/scdoc)
- GNU make (on \*BSD, `make` commands must be replaced by `gmake`).
Then compile aerc: Then compile aerc: