# Implicit rules are implemented in make as suffix rules. The following rule
# empties the suffix list to disable the predefined implicit rules. This
# increases performance and avoids hard-to-debug behaviour.
.SUFFIXES:
MAKEFLAGS += -Rr
ifeq ("$(origin CC)", "default")
        CC := cc
endif
.ONESHELL:
.SHELLFLAGS := -ec

PREFIX ?= /usr/local
M4 := m4
LN := ln -f
LEX := lex
RM := rm -f
AR := ar
GROFF := groff
CP := cp
INSTALL := install
GZIP := gzip -f9
ZCAT := zcat

DATE_FMT := +%B %Y
# To get a reproducible build, we use $(SOURCE_DATE_EPOCH) instead of the
# current time if this variable is set.
ifdef SOURCE_DATE_EPOCH
	DATE := $(shell LC_ALL=C date -u -d '@$(SOURCE_DATE_EPOCH)' \
		'$(DATE_FMT)' 2>/dev/null || LC_ALL=C date -u '$(DATE_FMT)')
else
	DATE := $(shell date '$(DATE_FMT)')
endif
GIT_VERSION := $(shell ./version-gen.sh)
PLAIN_VERSION := $(firstword $(subst -, , $(GIT_VERSION)))
MAJOR_VERSION := $(firstword $(subst ., , $(PLAIN_VERSION)))
SONAME := liblopsub.so.$(MAJOR_VERSION)
REALNAME := liblopsub.so.$(PLAIN_VERSION)
LINKERNAME:=liblopsub.so

m4_man_pages := lopsub-suite.5.gz lopsub.7.gz
all := $(m4_man_pages) $(REALNAME) lopsubgen lopsubgen.1.gz \
	lopsubex lopsubex.1.gz
all: $(all)

# deps
lopsubgen.o: lsg.h
lopsub.o lsg.o: lopsub.h lopsub-internal.h
lsg.o: lopsubgen.lsg.h lopsub-internal.h
lopsubex.o: lopsubex.lsg.h lopsub.h
config_file.c: lopsub-internal.h lopsub.h
version.o: version.c

# m4 stuff
gendoc := gendoc/gendoc.m4
%.h: %.h.m4 $(gendoc)
	$(M4) -DOUTPUT_MODE=C $(gendoc) $< > $@
$(m4_man_pages): %.gz: %.m4 version.c
	$(M4) -DGIT_VERSION=$(GIT_VERSION) -DDATE="$(DATE)" $< | $(GZIP) > $@

# flex
%.c: %.l
	$(LEX) -o $@ $<

# lopsubgen
lopsubgen.lsg.c lopsubgen.lsg.h: lopsubgen.suite lopsubgen-stage1 \
		lopsub-internal.h
	./lopsubgen-stage1 < $<
%.lsg.c: %.suite lopsubgen
	./lopsubgen --gen-c < $<
%.lsg.h: %.suite lopsubgen
	./lopsubgen --gen-header < $<
%.1.gz: %.suite lopsubgen
	./lopsubgen --gen-man=${@:.gz=} --version-string $(GIT_VERSION) < $<
	$(GZIP) ${@:.gz=}

# compiling
lsg1_objs := lopsubgen.o lsg1.o version.o
lsg_objs := lopsubgen.o lsg.o lopsubgen.lsg.o lopsub.o version.o
liblopsub_objs := config_file.o lopsub.o version.o
lopsubex_objs := lopsubex.o lopsubex.lsg.o $(liblopsub_objs)

$(lsg_objs) $(liblopsub_objs) $(lopsubex_objs): %.o: %.c
lopsubgen.o config_file.o:
	$(CC) -g -c -fPIC -o $@ ${@:.o=.c}
lsg1.o: lsg.c lsg.h
	$(CC) -g -DSTAGE1 -Wall -g -c $< -o $@
%.o: %.c
	$(CC) -Wall -I. -g -c -fPIC -o $@ $<

# linking
lopsubgen-stage1: $(lsg1_objs)
	$(CC) -Wall -g $(lsg1_objs) -o $@
lopsubgen: $(lsg_objs)
	$(CC) -Wall -g -o $@ $(lsg_objs)
$(REALNAME): $(liblopsub_objs)
	$(CC) --shared -Wl,-soname,liblopsub.so.$(MAJOR_VERSION) -o $@ $^
lopsubex: $(lopsubex_objs) $(REALNAME)
	$(CC) -Wall -g -o $@ $(lopsubex_objs)

# web
html := $(addprefix web/, $(addsuffix .html, \
	index lopsub-api lopsubgen.1 lopsubex.1 $(m4_man_pages)))
$(html): $(addprefix web/, $(addsuffix .html, header footer))

www: $(html)

web/lopsub-api.html: lopsub.h.m4
	$(M4) -DOUTPUT_MODE=HTML web/header.html $(gendoc) \
		$< web/footer.html > $@
web/index.html: web/lopsub.7.html
	$(LN) -s $(notdir $<) $@
web/%.html: %.gz
	$(CP) web/header.html $@
	$(ZCAT) $< | $(GROFF) -m man -Thtml | sed -e '1,/^<body>/d' >> $@

install: $(all)
	$(INSTALL) -d $(DESTDIR)$(PREFIX)/lib $(DESTDIR)$(PREFIX)/include \
		$(DESTDIR)$(PREFIX)/share/man/man1 $(DESTDIR)$(PREFIX)/share/man/man5 \
		$(DESTDIR)$(PREFIX)/share/man/man7 $(DESTDIR)$(PREFIX)/bin
	$(INSTALL) -m 644 $(REALNAME) $(DESTDIR)$(PREFIX)/lib
	$(LN) -s $(REALNAME) $(DESTDIR)$(PREFIX)/lib/$(SONAME)
	$(LN) -s $(SONAME) $(DESTDIR)$(PREFIX)/lib/$(LINKERNAME)
	$(INSTALL) -m 755 lopsubgen $(DESTDIR)$(PREFIX)/bin
	$(INSTALL) -m 644 lopsub.h $(DESTDIR)$(PREFIX)/include
	$(INSTALL) -m 644 lopsub-internal.h $(DESTDIR)$(PREFIX)/include
	$(INSTALL) -m 644 lopsubgen.1.gz $(DESTDIR)$(PREFIX)/share/man/man1
	$(INSTALL) -m 644 lopsub-suite.5.gz $(DESTDIR)$(PREFIX)/share/man/man5
	$(INSTALL) -m 644 lopsub.7.gz $(DESTDIR)$(PREFIX)/share/man/man7

clean:
	$(RM) $(all) $(html) *.o *.man
distclean: clean
	$(RM) *.lsg.c *.lsg.h lopsubgen.c config_file.c lopsubgen-stage1 \
		lopsub.h lopsub.7 lopsub-suite.5 version.c

