# variables that can be changed by users # VERSION ?= $(shell git describe --long --abbrev=12 --tags --dirty 2>/dev/null || echo 0.17.0) DATE ?= $(shell date +%Y-%m-%d) PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin SHAREDIR ?= $(PREFIX)/share/aerc LIBEXECDIR ?= $(PREFIX)/libexec/aerc MANDIR ?= $(PREFIX)/share/man GO ?= go INSTALL ?= install GOFLAGS ?= $(shell contrib/goflags.sh) BUILD_OPTS ?= -trimpath GO_LDFLAGS := GO_LDFLAGS += -X main.Version=$(VERSION) GO_LDFLAGS += -X main.Date=$(DATE) 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 . .PHONY: lint lint: @contrib/check-whitespace `git ls-files ':!:filters/vectors'` && \ echo white space ok. @contrib/check-docs && echo docs 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.56.1 run \ $$(echo $(GOFLAGS) | sed s/-tags=/--build-tags=/) $(GO) run $(GOFLAGS) contrib/linters.go ./... .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 $(subst -trimpath,,$(GOFLAGS)) -gcflags=*=-N -gcflags=*=-l -ldflags="$(GO_LDFLAGS)" -o aerc.debug .PHONY: doc doc: $(docs) @: .PHONY: clean clean: $(RM) $(docs) aerc $(cfilters) linters.so # 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 rmdir $$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" git config format.notes true git config notes.rewriteRef refs/notes/commits git config notes.rewriteMode concatenate @mkdir -p .git/hooks @rm -f .git/hooks/commit-msg* ln -s ../../contrib/commit-msg .git/hooks/commit-msg @rm -f .git/hooks/sendemail-validate* @if grep -q GIT_SENDEMAIL_FILE_COUNTER `git --exec-path`/git-send-email 2>/dev/null; then \ set -xe; \ ln -s ../../contrib/sendemail-validate .git/hooks/sendemail-validate && \ git config sendemail.validate true; \ fi .PHONY: check-patches check-patches: @contrib/check-patches origin/master.. .PHONY: validate validate: CFLAGS = -Wall -Wextra -Wconversion -Werror -Wformat-security -Wstack-protector -Wpedantic -Wmissing-prototypes validate: all tests lint check-patches # 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 $@