aboutsummaryrefslogtreecommitdiff
.POSIX:
DATE         = 1970-01-01
VERSION      = 0.1.0
NAME         = stm
NAME_UC      = $(NAME)
LANGUAGES    = en
## Installation prefix.  Defaults to "/usr".
PREFIX       = /usr
BINDIR       = $(PREFIX)/bin
LIBDIR       = $(PREFIX)/lib
GOLIBDIR     = $(LIBDIR)/go
INCLUDEDIR   = $(PREFIX)/include
SRCDIR       = $(PREFIX)/src/$(NAME)
SHAREDIR     = $(PREFIX)/share
LOCALEDIR    = $(SHAREDIR)/locale
MANDIR       = $(SHAREDIR)/man
EXEC         = ./
## Where to store the installation.  Empty by default.
DESTDIR      =
LDLIBS       = --static
GOCFLAGS     = -I $(GOLIBDIR)
GOLDFLAGS    = -L $(GOLIBDIR)
N            = `nproc`



.SUFFIXES:
.SUFFIXES: .go .a .bin .bin-check .adoc .po .mo

.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) -o $@ --extldflags '$(LDLIBS)' $<

.adoc:
	asciidoctor -b manpage -o $@ $<

.po.mo:
	msgfmt -cfv -o $@ $<



all:
include deps.mk


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.N.adoc  = $(manpages.en.N.adoc) $(manpages.XX.N.adoc)
manpages.N       = $(manpages.N.adoc:.adoc=)
sources.mo       = $(sources.po:.po=.mo)

sources = \
	src/$(NAME).go                 \
	src/meta.go                    \


derived-assets = \
	src/meta.go                    \
	$(libs.a)                      \
	$(mains.a)                     \
	$(mains.bin)                   \
	$(manpages.XX.N.adoc)          \
	$(manpages.N)                  \
	$(sources.mo)                  \

side-assets = \
	tests/fuzz/corpus/             \
	tests/benchmarks/*/main.txt    \



## Default target.  Builds all artifacts required for testing
## and installation.
all: $(derived-assets)


$(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 LOCALEDIR = "$(LOCALEDIR)"' >> $@

$(manpages.XX.N.adoc): po/doc/po4a.cfg
	po4a --no-update --translate-only $@ po/doc/po4a.cfg



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 = \

.PRECIOUS: $(integration-tests)
$(integration-tests): $(NAME).bin
$(integration-tests): ALWAYS
	sh $@

check-integration: $(integration-tests)
check-integration: fuzz


## 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



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)



i18n-doc:
	po4a po/doc/po4a.cfg

i18n-code:
	gotext src/$(NAME).go > po/$(NAME)/$(NAME).pot
	po4a po/$(NAME)/po4a.cfg

i18n: i18n-doc i18n-code



## 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)$(GOLIBDIR)'   \
		'$(DESTDIR)$(SRCDIR)'     \

	cp src/$(NAME).a     '$(DESTDIR)$(GOLIBDIR)'
	cp $(sources)        '$(DESTDIR)$(SRCDIR)'
	instool              '$(DESTDIR)$(MANDIR)'    install man $(manpages.N)
	instool              '$(DESTDIR)$(LOCALEDIR)' install mo  $(sources.mo)

## 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)$(GOLIBDIR)'/$(NAME).a     \
		'$(DESTDIR)$(SRCDIR)'                 \

	instool '$(DESTDIR)$(MANDIR)'    uninstall man $(manpages.N)
	instool '$(DESTDIR)$(LOCALEDIR)' uninstall mo  $(sources.mo)



ALWAYS: