SHELL		= /bin/sh
MAKE		= make

CC		= cc
CFLAGS		= -DNDEBUG
LDFLAGS		= $(CFLAGS)
MACROS=		-DHNEFATAFL_UI_AIM\
		-DHNEFATAFL_UI_XLIB

PRGNAM		= hnefatafl
BIN		= $(PRGNAM)
OBJS		= cli.o cliio.o cliiot.o config.o control.o controlt.o\
		filefind.o funcx.o\
		langkey.o langkeyt.o\
		main.o\
		ui.o uiutil.o\
			uiutilt.o\
			xlib/uix.o\
			xlib/uixconsole.o\
			xlib/uixgame.o\
			xlib/uixfont.o\
			xlib/uixpaint.o\
			xlib/uixt.o xlib/uixtheme.o xlib/uixthemet.o\
			xlib/uixutil.o xlib/uixutilt.o\
			xlib/xlib.o

GLEIPNIR	= gleipnir
GLEIPNIR_DIR	= ../$(GLEIPNIR)

GLINE		= $(GLEIPNIR)_line
GLINE_H		= $(GLINE).h

GLINES		= $(GLEIPNIR)_lines
GLINES_H	= $(GLINES).h

GLINEREAD	= $(GLEIPNIR)_lineread
GLINEREAD_H	= $(GLINEREAD).h

GLANG		= $(GLEIPNIR)_lang
GLANG_A		= lib$(GLANG).a
GLANG_H		= $(GLANG).h

CORE		= hnefatafl
CORE_A		= lib$(CORE).a
CORE_SO		= lib$(CORE).so
CORE_H		= $(CORE).h
CORE_DIR	= ../core

AIM		= hnefatafl_aim
AIM_A		= lib$(AIM).a
AIM_SO		= lib$(AIM).so
AIM_H		= $(AIM).h
AIM_DIR		= ../aim

DEPS_A		= $(CORE_DIR)/$(CORE_A)\
		$(AIM_DIR)/$(AIM_A)\
		$(GLEIPNIR_DIR)/$(GLANG_A)
DEPS_SO		= $(CORE_DIR)/$(CORE_SO)\
		$(AIM_DIR)/$(AIM_SO)
DEPS_H		= $(CORE_DIR)/$(CORE_H)\
		$(AIM_DIR)/$(AIM_H)\
		$(GLEIPNIR_DIR)/$(GLINE_H)\
		$(GLEIPNIR_DIR)/$(GLINES_H)\
		$(GLEIPNIR_DIR)/$(GLINEREAD_H)\
		$(GLEIPNIR_DIR)/$(GLANG_H)

LDLIBS_X	= -lX11 -lXpm
LDLIBS		= -lm\
		-l$(CORE)\
		-l$(AIM)\
		$(LDLIBS_X)
INC_X		= -I/usr/include\
		-I/usr/local/include
INC		= -I.\
		-Ixlib\
		-I$(CORE_DIR)\
		-I$(CORE_DIR)/zhash\
		-I$(AIM_DIR)\
		-I$(GLEIPNIR_DIR)\
		$(INC_X)
LIB_X		= -L/usr/lib\
		-L/usr/local/lib

LIB		= -L$(CORE_DIR)\
		-L$(AIM_DIR)\
		$(LIB_X)

CGLANG		= scan-build
CPPCHECK	= cppcheck --enable=all
GCC		= gcc -g -std=c89\
		-pedantic-errors -Waggregate-return -Wall\
		-Wbad-function-cast -Wcast-align -Wcast-qual -Wcomment\
		-Wconversion -Wdeclaration-after-statement\
		-Wdisabled-optimization -Wdouble-promotion -Werror\
		-Wextra -Wfloat-equal -Wformat=2\
		-Wframe-larger-than=256 -Winline -Winit-self\
		-Winvalid-pch -Wjump-misses-init -Wlarger-than=320\
		-Wlogical-op -Wlong-long -Wmissing-declarations\
		-Wmissing-format-attribute -Wmissing-include-dirs\
		-Wmissing-prototypes -Wnested-externs\
		-Wold-style-declaration -Wold-style-definition -Wpacked\
		-Wredundant-decls -Wshadow -Wstack-protector\
		-Wstack-usage=256 -Wstrict-aliasing -Wstrict-overflow=5\
		-Wstrict-prototypes -Wswitch-default -Wswitch-enum\
		-Wsync-nand -Wtrampolines -Wundef -Wuninitialized\
		-Wunreachable-code -Wunsafe-loop-optimizations -Wunused\
		-Wvector-operation-performance -Wvla -Wwrite-strings
LINT		= splint -strict -strict-lib -ansi89limits\
		-booltype HNEF_BOOL -boolfalse HNEF_FALSE\
		-booltrue HNEF_TRUE -systemdirerrors -exportany\
		-bounds +likelybounds
VALGRIND	= valgrind -v --leak-check=full\
		--track-origins=yes --show-reachable=yes

all: static

static: $(DEPS_H) $(DEPS_A) $(OBJS)
	$(CC) $(CFLAGS) -lm $(LDLIBS_X) $(LIB_X) $(INC) $(MACROS)\
		-o $(BIN) $(OBJS) $(DEPS_A)

dynamic: $(DEPS_H) $(DEPS_A) $(DEPS_SO) $(OBJS)
	$(CC) $(CFLAGS) $(LDLIBS) $(LIB) $(INC) $(MACROS)\
		-o $(BIN) $(OBJS) $(DEPS_A)

cli.o: cli.c cli.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o cli.o cli.c

cliio.o: cliio.c cliio.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o cliio.o cliio.c

cliiot.o: cliiot.c cliiot.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o cliiot.o cliiot.c

config.o: config.c config.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o config.o config.c

control.o: control.c control.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o control.o control.c

controlt.o: controlt.c controlt.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o controlt.o controlt.c

filefind.o: filefind.c filefind.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o filefind.o filefind.c

funcx.o: funcx.c funcx.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o funcx.o funcx.c

langkey.o: langkey.c langkey.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o langkey.o langkey.c

langkeyt.o: langkeyt.c langkeyt.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o langkeyt.o langkeyt.c

main.o: main.c
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o main.o main.c

ui.o: ui.c ui.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o ui.o ui.c

uiutil.o: uiutil.c uiutil.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o uiutil.o uiutil.c

uiutilt.o: uiutilt.c uiutilt.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o uiutilt.o uiutilt.c

xlib/uix.o: xlib/uix.c xlib/uix.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uix.o xlib/uix.c

xlib/uixconsole.o: xlib/uixconsole.c xlib/uixconsole.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixconsole.o xlib/uixconsole.c

xlib/uixgame.o: xlib/uixgame.c xlib/uixgame.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixgame.o xlib/uixgame.c

xlib/uixfont.o: xlib/uixfont.c xlib/uixfont.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixfont.o xlib/uixfont.c

xlib/uixpaint.o: xlib/uixpaint.c xlib/uixpaint.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixpaint.o xlib/uixpaint.c

xlib/uixt.o: xlib/uixt.c xlib/uixt.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixt.o xlib/uixt.c

xlib/uixtheme.o: xlib/uixtheme.c xlib/uixtheme.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixtheme.o xlib/uixtheme.c

xlib/uixthemet.o: xlib/uixthemet.c xlib/uixthemet.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixthemet.o xlib/uixthemet.c

xlib/uixutil.o: xlib/uixutil.c xlib/uixutil.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixutil.o xlib/uixutil.c

xlib/uixutilt.o: xlib/uixutilt.c xlib/uixutilt.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/uixutilt.o xlib/uixutilt.c

xlib/xlib.o: xlib/xlib.c xlib/xlib.h
	$(CC) $(CFLAGS) $(INC) $(MACROS)\
		-c -o xlib/xlib.o xlib/xlib.c

$(GLEIPNIR_DIR)/$(GLANG_A): FORCE
	cd $(GLEIPNIR_DIR)	&& $(MAKE) $(GLANG_A)\
					CC="$(CC)"\
					CFLAGS="$(CFLAGS)"

$(GLEIPNIR_DIR)/$(GLINE_H): FORCE
	cd $(GLEIPNIR_DIR)	&& $(MAKE) $(GLINE_H)

$(GLEIPNIR_DIR)/$(GLINES_H): FORCE
	cd $(GLEIPNIR_DIR)	&& $(MAKE) $(GLINES_H)

$(GLEIPNIR_DIR)/$(GLINEREAD_H): FORCE
	cd $(GLEIPNIR_DIR)	&& $(MAKE) $(GLINEREAD_H)

$(GLEIPNIR_DIR)/$(GLANG_H): FORCE
	cd $(GLEIPNIR_DIR)	&& $(MAKE) $(GLANG_H)

$(CORE_DIR)/$(CORE_A): FORCE
	cd $(CORE_DIR)		&& $(MAKE) $(CORE_A)\
					CC="$(CC)"\
					CFLAGS="$(CFLAGS)"

$(CORE_DIR)/$(CORE_SO): FORCE
	cd $(CORE_DIR)		&& $(MAKE) $(CORE_SO)\
					CC="$(CC)"\
					CFLAGS="$(CFLAGS)"\
					LDFLAGS="$(LDFLAGS)"

$(CORE_DIR)/$(CORE_H): FORCE
	cd $(CORE_DIR)		&& $(MAKE) $(CORE_H)

$(AIM_DIR)/$(AIM_A): FORCE
	cd $(AIM_DIR)		&& $(MAKE) $(AIM_A)\
					CC="$(CC)"\
					CFLAGS="$(CFLAGS)"

$(AIM_DIR)/$(AIM_SO): FORCE
	cd $(AIM_DIR)		&& $(MAKE) $(AIM_SO)\
					CC="$(CC)"\
					CFLAGS="$(CFLAGS)"\
					LDFLAGS="$(LDFLAGS)"

$(AIM_DIR)/$(AIM_H): FORCE
	cd $(AIM_DIR)		&& $(MAKE) $(AIM_H)

clean:
	rm -f $(OBJS)
	rm -f uix*\.o
	rm -f xlib*\.o

mrproper: clean
	rm -f $(BIN)

clean-dist: mrproper
	@true

dist: clean-dist
	@true

clang: clean
	$(CGLANG) $(CC) -g -std=c99 -O0 $(INC) -c *.c */*.c

cppcheck:
	$(CPPCHECK) $(INC) *.c */*.c

gcc: clean
	$(MAKE) dynamic CC="$(GCC)" CFLAGS="" LDFLAGS=""

lint:
	$(LINT) $(INC) $(MACROS) -systemdirs\
		"/usr/include:/usr/local/include:$(GLEIPNIR_DIR):$(CORE_DIR):$(AIM_DIR)"\
		*.c */*.c

run: dynamic
	@LD_LIBRARY_PATH="$(CORE_DIR):$(AIM_DIR):$(GLEIPNIR_DIR)"\
		./$(BIN)\
		-d "$$(pwd)/../../data"

run_l: dynamic
	@LD_LIBRARY_PATH="$(CORE_DIR):$(AIM_DIR):$(GLEIPNIR_DIR)"\
		./$(BIN) -d "$$(pwd)/../../data" -s

valgrind: dynamic
	@LD_LIBRARY_PATH="$(CORE_DIR):$(AIM_DIR):$(GLEIPNIR_DIR)"\
		$(VALGRIND) ./$(BIN)\
		-d "$$(pwd)/../../data"

valgrind_l: dynamic
	@LD_LIBRARY_PATH="$(CORE_DIR):$(AIM_DIR):$(GLEIPNIR_DIR)"\
		$(VALGRIND) ./$(BIN)\
		-s -d "$$(pwd)/../../data"

valgrind_z: dynamic
	@printf 'x null\nq\n'\
		| LD_LIBRARY_PATH="$(CORE_DIR):$(AIM_DIR):$(GLEIPNIR_DIR)"\
		$(VALGRIND) ./$(BIN) -s -C\
		-d "$$(pwd)/../../data" -l swe -r hnefatafl11_v1

.PHONY: all clean mrproper\
	dynamic static\
	clean-dist dist\
	clang cppcheck gcc lint\
	run run_l\
	valgrind valgrind_l valgrind_z

FORCE:

