aboutsummaryrefslogtreecommitdiff
.POSIX:
DATE         = 1970-01-01
VERSION      = 0.1.0
NAME         = urubu
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)



.SUFFIXES:
.SUFFIXES: .go .a .bin .bin-check

.go.a:
	go tool compile -I $(@D) $(GOCFLAGS)  -o $@ -p $(*F) \
		`find $< $$(if [ $(*F) != main ]; then \
			echo src/$(NAME).go src/version.go; fi) | uniq`

.a.bin:
	go tool link    -L $(@D) $(GOLDFLAGS) -o $@ --extldflags '$(LDLIBS)' $<



all:
include deps.mk


libs.a                 = $(libs.go:.go=.a)
mains.a                = $(mains.go:.go=.a)
mains.bin              = $(mains.go:.go=.bin)
functional-tests/lib.a = $(functional-tests/lib.go:.go=.a)
fuzz-targets/lib.a     = $(fuzz-targets/lib.go:.go=.a)
benchmarks/lib.a       = $(benchmarks/lib.go:.go=.a)

existing = \
	src/urubu/utf8 \
	src/urubu/ucd \
	src/urubu/error \
	src/urubu/compressor \
	src/urubu/spec/grammar \
	src/urubu/spec/grammar/parser \
	src/urubu/spec/test \
	src/urubu/grammar/symbol \
	src/urubu/grammar/lexical/parser \
	src/urubu/grammar/lexical/dfa \
	src/urubu/grammar/lexical \
	src/urubu/grammar \
	src/urubu/driver/lexer \
	src/urubu/driver/parser \
	src/urubu/tester \

xtests = \
	tests/unit/compressor/compressor.go \
	tests/unit/grammar/symbol/symbol.go \
	tests/unit/spec/test/test.go \
	tests/unit/utf8/utf8.go \
	tests/unit/spec/grammar/parser/parser.go \
	tests/unit/grammar/grammar.go \
	tests/unit/tester/tester.go \
	tests/unit/grammar/lexical/dfa/dfa.go \
	tests/unit/grammar/lexical/parser/parser.go \
	tests/unit/grammar/lexical/lexical.go \
	tests/unit/driver/lexer/lexer.go \
	tests/unit/driver/parser/parser.go \

xmains = \
	src/urubu/cmd/ucdgen \
	src/urubu/cmd/vartan \
	src/urubu/cmd/vartan-go \

xtmains = \
	tests/unit/compressor/main.go \
	tests/unit/grammar/symbol/main.go \
	tests/unit/spec/test/main.go \
	tests/unit/tester/main.go \
	tests/unit/utf8/main.go \
	tests/unit/spec/grammar/parser/main.go \
	tests/unit/grammar/main.go \
	tests/unit/grammar/lexical/dfa/main.go \
	tests/unit/grammar/lexical/parser/main.go \
	tests/unit/grammar/lexical/main.go \
	tests/unit/driver/lexer/main.go \
	tests/unit/driver/parser/main.go \

existing.a  = $(existing:=.a)
xmains.a    = $(xmains:=.a)
xmains.bin  = $(xmains:=.bin)
xtests.a    = $(xtests:.go=.a)
xtmains.a   = $(xtmains:.go=.a)
xtmains.bin = $(xtmains:.go=.bin)


sources = \
	src/$(NAME).go                 \
	src/version.go                 \
	src/main.go                    \


derived-assets = \
	$(xtests.a)                    \
	$(xtmains.a)                   \
	$(xtmains.bin)                 \
	$(existing.a)                  \
	$(xmains.a)                    \
	$(xmains.bin)                  \
	src/version.go                 \
	$(libs.a)                      \
	$(mains.a)                     \
	$(mains.bin)                   \
	$(NAME).bin                    \

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



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


$(existing.a) $(xmains.a): Makefile deps.mk
$(libs.a): Makefile deps.mk
$(libs.a): src/$(NAME).go src/version.go


$(existing.a):
	go tool compile -I src -o $@ -p `echo $* | sed 's,^src/,,'` $*.go

$(xtests.a):
	p="`echo $(*D) | sed 's,^tests/unit/,,'`"; \
	go tool compile -I src -o $@ -p $(*F) src/urubu/$$p.go $*.go

$(xmains.a):
	go tool compile -I src -o $@ -p main $*/*.go

$(xmains.bin):
	go tool link    -L src -o $@ --extldflags '$(LDLIBS)' $*.a

$(xtmains.a):
	go tool compile -I $(@D) -o $@ -p main $*.go

$(xtmains.bin):
	go tool link    -L $(@D) -L src -o $@ --extldflags '$(LDLIBS)' $*.a

$(fuzz-targets/lib.a):
	go tool compile $(GOCFLAGS) -o $@ -p $(NAME) -d=libfuzzer \
		$*.go src/$(NAME).go src/version.go

src/version.go: Makefile
	echo 'package $(NAME); const Version = "$(VERSION)"' > $@

$(NAME).bin: src/main.bin
	ln -fs src/main.bin $@



tests.bin-check = \
	tests/main.bin-check \
	$(functional-tests/main.go:.go=.bin-check) \
	$(xtmains:.go=.bin-check) \

$(tests.bin-check):
	$(EXEC)$*.bin

check-unit: $(tests.bin-check)


integration-tests = \
	tests/cli-opts.sh              \
	tests/integration.sh           \

.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-targets/main.bin-check = $(fuzz-targets/main.go:.go=.bin-check)
$(fuzz-targets/main.bin-check):
	$(EXEC)$*.bin --test.fuzztime=$(FUZZSEC)s \
		--test.fuzz='.*' --test.fuzzcachedir=tests/fuzz/corpus

fuzz: $(fuzz-targets/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)'

## 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)'                 \



ALWAYS: