summaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile221
1 files changed, 162 insertions, 59 deletions
diff --git a/Makefile b/Makefile
index 9b60452..65b1bb2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,88 +1,191 @@
.POSIX:
+DATE = 1970-01-01
+VERSION = 0.1.0
+NAME = remembering
+NAME_UC = $(NAME)
+## Installation prefix. Defaults to "/usr".
PREFIX = /usr
+BINDIR = $(PREFIX)/bin
+LIBDIR = $(PREFIX)/lib
+GOLIBDIR = $(LIBDIR)/go
+SRCDIR = $(PREFIX)/src/$(NAME)
SHAREDIR = $(PREFIX)/share
+LOCALEDIR = $(SHAREDIR)/locale
MANDIR = $(SHAREDIR)/man
-VERSION = 0.3.0
-DATE = 2022-11-25
-NAME = remembering
-MAILING_LIST = public-inbox
+EXEC = ./
+## Where to store the installation. Empty by default.
+DESTDIR =
+LDLIBS = --static
+GOCFLAGS = -I $(GOLIBDIR)
+GOLDFLAGS = -L $(GOLIBDIR)
+N = `nproc`
+
.SUFFIXES:
-.SUFFIXES: .in
+.SUFFIXES: .go .a .bin .bin-check .adoc
-.in:
- sed \
- -e 's:@VERSION@:$(VERSION):g' \
- -e 's:@DATE@:$(DATE):g' \
- -e 's:@NAME@:$(NAME):g' \
- < $< > $@
- if [ -x $< ]; then chmod +x $@; fi
+.go.a:
+ go tool compile -I $(@D) $(GOCFLAGS) -o $@ -p $(*F) \
+ `find $< $$(if [ $(*F) != main ]; then \
+ echo src/$(NAME).go src/meta.go; fi) | uniq`
+.a.bin:
+ go tool link -L $(@D) $(GOLDFLAGS) -extld $(CC) \
+ -o $@ --extldflags '$(LDLIBS)' $<
-manpages.en.in = \
- doc/remembering.en.1.in \
- doc/remembering.en.5.in
-manpages.in = $(manpages.en.in) \
- doc/remembering.pt.1.in \
- doc/remembering.fr.1.in \
- doc/remembering.eo.1.in \
- doc/remembering.pt.5.in \
- doc/remembering.fr.5.in \
- doc/remembering.eo.5.in
-manpages = $(manpages.in:.in=)
+.adoc:
+ asciidoctor -b manpage -o $@ $<
-all: src/remembering $(manpages)
+all:
+include deps.mk
-src/remembering: src/remembering.in
+libs.a = $(libs.go:.go=.a)
+mains.a = $(mains.go:.go=.a)
+mains.bin = $(mains.go:.go=.bin)
+functional/lib.a = $(functional/lib.go:.go=.a)
+fuzz/lib.a = $(fuzz/lib.go:.go=.a)
+benchmarks/lib.a = $(benchmarks/lib.go:.go=.a)
+manpages = $(manpages.adoc:.adoc=)
-test-files = \
- tests/cli-opts.sh \
- tests/ranking.sh \
- tests/signals.sh \
+sources = \
+ src/$(NAME).go \
+ src/meta.go \
+ src/main.go \
-$(test-files): src/remembering ALWAYS
- @echo sh $@
-check: $(test-files)
+derived-assets = \
+ src/meta.go \
+ $(libs.a) \
+ $(mains.a) \
+ $(mains.bin) \
+ $(NAME).bin \
+ $(manpages) \
-clean:
- rm -rf \
- public/ $(manpages) *.*.md *.sentinel doc/*.html *.html \
- src/remembering tests/test-profiles/ aux/preamble-md \
- aux/generated.mk aux/checks/manpages/*.0
+side-assets = \
+ tests/fuzz/corpus/ \
+ tests/benchmarks/*/main.txt \
+ tests/test-profiles/ \
-install: all
- mkdir -p '$(DESTDIR)$(PREFIX)/bin'
- cp src/remembering '$(DESTDIR)$(PREFIX)/bin'
- sh doc/manpages.sh -ip '$(DESTDIR)$(MANDIR)' $(manpages)
-uninstall:
- rm -f '$(DESTDIR)$(PREFIX)/bin/remembering'
- sh doc/manpages.sh -up '$(DESTDIR)$(MANDIR)' $(manpages)
+## Default target. Builds all artifacts required for testing
+## and installation.
+all: $(derived-assets)
-ALWAYS:
+$(libs.a): Makefile deps.mk
+$(libs.a): src/$(NAME).go src/meta.go
+
+
+$(fuzz/lib.a):
+ go tool compile $(GOCFLAGS) -o $@ -p $(NAME) -d=libfuzzer \
+ $*.go src/$(NAME).go src/meta.go
+
+src/meta.go: Makefile
+ echo 'package $(NAME)' > $@
+ echo 'const Version = "$(VERSION)"' >> $@
+ echo 'const Name = "$(NAME)"' >> $@
+ echo 'const Date = "$(DATE)"' >> $@
+
+$(NAME).bin: src/main.bin
+ ln -fs src/main.bin $@
+
+
+
+tests.bin-check = \
+ tests/main.bin-check \
+ $(functional/main.go:.go=.bin-check) \
+
+$(tests.bin-check):
+ $(EXEC)$*.bin
+
+check-unit: $(tests.bin-check)
+
+
+integration-tests = \
+ tests/cli-opts.sh \
+ tests/ranking.sh \
+ tests/signals.sh \
+
+.PRECIOUS: $(integration-tests)
+$(integration-tests): $(NAME).bin
+$(integration-tests): ALWAYS
+ sh $@
+
+check-integration: $(integration-tests)
+check-integration: fuzz
-#
-# Personal workflow targets
-#
-dist:
- sh aux/workflow/dist.sh -d '$(DATE)' -V '$(VERSION)' -n '$(NAME)'
+## Run all tests. Each test suite is isolated, so that a parallel
+## build can run tests at the same time. The required artifacts
+## are created if missing.
+check: check-unit check-integration
-public po/po4a.cfg dev-check:
- $(MAKE) -f aux/dev.mk $@ \
- en_files='$(manpages.en.in)' \
- manpages.in='$(manpages.in)' \
- md_files="`echo *.??.md`" \
- MAILING_LIST='$(MAILING_LIST)'
-public: TODOs.md README.md CHANGELOG.md po/po4a.cfg $(manpages)
-po/po4a.cfg: ALWAYS
-dev: all check public dev-check
+FUZZSEC=1
+fuzz/main.bin-check = $(fuzz/main.go:.go=.bin-check)
+$(fuzz/main.bin-check):
+ $(EXEC)$*.bin --test.fuzztime=$(FUZZSEC)s --test.parallel=$N \
+ --test.fuzz='.*' --test.fuzzcachedir=tests/fuzz/corpus
+
+fuzz: $(fuzz/main.bin-check)
+
+
+
+benchmarks/main.bin-check = $(benchmarks/main.go:.go=.bin-check)
+$(benchmarks/main.bin-check):
+ printf '%s\n' '$(EXEC)$*.bin' > $*.txt
+ LANG=POSIX.UTF-8 time -p $(EXEC)$*.bin 2>> $*.txt
+ printf '%s\n' '$*.txt'
+
+bench: $(benchmarks/main.bin-check)
+
+
+
+## Remove *all* derived artifacts produced during the build.
+## A dedicated test asserts that this is always true.
+clean:
+ rm -rf $(derived-assets) $(side-assets)
+
+
+## Installs into $(DESTDIR)$(PREFIX). Its dependency target
+## ensures that all installable artifacts are crafted beforehand.
+install: all
+ mkdir -p \
+ '$(DESTDIR)$(BINDIR)' \
+ '$(DESTDIR)$(GOLIBDIR)' \
+ '$(DESTDIR)$(SRCDIR)' \
+
+ cp $(NAME).bin '$(DESTDIR)$(BINDIR)'/$(NAME)
+ cp src/$(NAME).a '$(DESTDIR)$(GOLIBDIR)'
+ cp $(sources) '$(DESTDIR)$(SRCDIR)'
+ for f in $(manpages); do \
+ n=`basename "$$f"`; \
+ section=$${n##*.}; \
+ mkdir -p '$(DESTDIR)$(MANDIR)'/man$$section; \
+ cp "$$f" '$(DESTDIR)$(MANDIR)'/man$$section; \
+ done
+
+## Uninstalls from $(DESTDIR)$(PREFIX). This is a perfect mirror
+## of the "install" target, and removes *all* that was installed.
+## A dedicated test asserts that this is always true.
+uninstall:
+ rm -rf \
+ '$(DESTDIR)$(BINDIR)'/$(NAME) \
+ '$(DESTDIR)$(GOLIBDIR)'/$(NAME).a \
+ '$(DESTDIR)$(SRCDIR)' \
+
+ for f in $(manpages); do \
+ n=`basename "$$f"`; \
+ section=$${n##*.}; \
+ rm -f '$(DESTDIR)$(MANDIR)'/man$$section/$$n; \
+ done
+
+
+
+ALWAYS: