.POSIX:
DATE = 1970-01-01
VERSION = 0.1.0
NAME = grovel
NAME_UC = $(NAME)
MAILING_LIST = public-inbox
LANGUAGES =
## Installation prefix. Defaults to "/usr".
PREFIX = /usr
BINDIR = $(PREFIX)/bin
LIBDIR = $(PREFIX)/lib
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 =
.SUFFIXES:
.SUFFIXES: .in .c .o .to .xa .bin .msg .cat
.SUFFIXES: .s
.in:
sed \
-e 's:@VERSION@:$(VERSION):g' \
-e 's:@DATE@:$(DATE):g' \
-e 's:@NAME@:$(NAME):g' \
< $< > $@
if [ -x $< ]; then chmod +x $@; fi
.s.o:
$(CC) $(CFLAGS) -o $@ -c $<
.c.o:
$(CC) $(CFLAGS) -o $@ -c $<
.c.to:
$(CC) $(CFLAGS) -DTEST -o $@ -c $<
.xa.bin:
$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
all:
include deps.mk
manpages = $(manpages.in:.in=)
catalogs.cat = $(catalogs.msg:.msg=.cat)
sources.o = $(sources.c:.c=.o) $(sources.s:.s=.o)
sources.to = $(sources.c:.c=.to)
sources.xa = $(sources.c:.c=.xa)
sources.bin = $(sources.c:.c=.bin)
fuzz.o = $(fuzz.c:.c=.o)
fuzz.xa = $(fuzz.c:.c=.xa)
fuzz.bin = $(fuzz.c:.c=.bin)
sources = \
$(sources.c) \
$(sources.c:.c=.h) \
src/config.h.in \
src/config.h \
src/main.c \
src/$(NAME).h \
$(catalogs.msg) \
empty-libs.a = \
libm.a \
librt.a \
libpthread.a \
libcrypt.a \
libutil.a \
libxnet.a \
libresolv.a \
libdl.a \
derived-assets = \
lib$(NAME).a \
$(empty-libs.a) \
libc.a \
src/config.h \
$(manpages) \
$(catalogs.cat) \
$(sources.o) \
$(sources.to) \
$(sources.xa) \
$(sources.bin) \
src/main.o \
src/main.xa \
src/main.bin \
side-assets = \
$(fuzz.o) \
$(fuzz.xa) \
$(fuzz.bin) \
## Default target. Builds all artifacts required for testing
## and installation.
all: $(derived-assets)
lib$(NAME).a: $(libc.c:.c=.o) $(libc.s:.s=.o)
src/main.xa: $(sources.o) src/main.o
$(fuzz.bin): lib$(NAME).a
$(manpages) src/config.h: Makefile deps.mk
$(sources.o) $(sources.to): Makefile deps.mk src/config.h
$(sources.xa): crt/crt1.o crt/x86_64/crti.o crt/x86_64/crtn.o
$(sources.xa): $(libc.c:.c=.o) $(libc.s:.s=.o)
crt/crt1.bin:
touch $@
chmod +x $@
lib$(NAME).a $(sources.xa) src/main.xa $(fuzz.xa) $(empty-libs.a):
$(AR) $(ARFLAGS) $@ $?
src/$(NAME).en.cat: src/i18n.bin
env DUMP_TRANSLATABLE_STRINGS=1 $(EXEC)src/i18n.bin > $*.msg.new
cmp -s $*.msg.new $*.msg || mv $*.msg.new $*.msg
rm -f $*.msg.new
gencat $@ $*.msg
touch $@
libc.a: lib$(NAME).a
ln -fs lib$(NAME).a $@
.SUFFIXES: .bin-check
sources.bin-check = $(sources.c:.c=.bin-check)
$(sources.bin-check):
$(EXEC)$*.bin
check-unit: $(sources.bin-check)
## 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
fuzz.bin-check = $(fuzz.c:.c=.bin-check)
$(fuzz.bin-check):
$(EXEC)$*.bin tests/fuzz/corpus/ $(FUZZFLAGS)
## Run fuzzing targets indefinitely.
fuzz: $(fuzz.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)$(LIBDIR)' \
'$(DESTDIR)$(INCLUDEDIR)'
cp src/main.bin '$(DESTDIR)$(BINDIR)'/$(NAME)
# FIXME headers in '$(DESTDIR)$(INCLUDEDIR)'
cp -P lib$(NAME).a $(empty-libs.a) libc.a '$(DESTDIR)$(LIBDIR)'
for f in $(FIXME_sources); do \
dir='$(DESTDIR)$(SRCDIR)'/"`dirname "$${f#src/}"`"; \
mkdir -p "$$dir"; \
cp -P "$$f" "$$dir"; \
done
for l in $(LANGUAGES); do \
dir='$(DESTDIR)$(LOCALEDIR)'/"$$l"/LC_MESSAGES; \
mkdir -p "$$dir"; \
cp src/$(NAME)."$$l".cat "$$dir"/$(NAME).cat; \
done
sh tools/manpages.sh -ip '$(DESTDIR)$(MANDIR)' $(manpages)
## 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)$(LIBDIR)'/lib$(NAME).a \
'$(DESTDIR)$(INCLUDEDIR)'/$(NAME).h \
'$(DESTDIR)$(SRCDIR)'
for l in $(empty-libs.a) libc.a; do \
rm -f '$(DESTDIR)$(LIBDIR)'/"$$l"; \
done
for l in $(LANGUAGES); do \
rm -f '$(DESTDIR)$(LOCALEDIR)'/"$$l"/LC_MESSAGES/$(NAME).cat; \
done
sh tools/manpages.sh -up '$(DESTDIR)$(MANDIR)' $(manpages)
MAKEFILE = Makefile
## Show this help.
help:
cat $(MAKEFILE) | sh tools/makehelp.sh
ALWAYS: