
QUIET ?= @

UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Darwin)
    SO_EXT = dylib
else
    SO_EXT = so
endif

all: lib/libwigxjpf.a bin/wigxjpf

fpsimple: lib/libfpsimplexj.a

# The reason for _shared in the shared object library name is to
# ensure that linking with the static library uses the static without
# ambiguity and thus avoid hunting library paths later.

shared: lib/libwigxjpf_shared.$(SO_EXT)

AR = ar
RLIB = ranlib

HEADERS = src/multi_word_int.h src/multi_word_int_dbl.h \
	src/prime_factor.h src/calc.h src/calc_minmax.h src/calc_dbl.h \
	inc/wigxjpf.h inc/wigxjpf_quadmath.h \
	gen/wigxjpf_auto_config.h \
	cfg/wigxjpf_config.h

LIB_OBJS = prime_factor.o calc.o trivial_zero.o \
	c_wrap.o fortran_wrap.o

LIB_OBJECTS = $(LIB_OBJS:%.o=obj/%.o)

LIB_OBJS_QUADMATH = calc_float128.o c_wrap_float128.o

LIB_OBJECTS_QUADMATH = $(LIB_OBJS_QUADMATH:%.o=obj/%.o)

FPSIMPLE_OBJS = fpsimple.o fpsimple_log.o fpsimple_precalc.o

FPSIMPLE_OBJECTS = $(FPSIMPLE_OBJS:%.o=obj/%.o)

FCFLAGS += -O3 -I mod/
CFLAGS += -O3 -fPIC -Wall -Wextra -Wconversion -Wcast-qual -g -I inc/ -I cfg/ -I gen/
ARFLAGS = -cr

LDLIBS += -lm

# HAVE_QUADMATH := $(shell $(CC) -DTEST_FLOAT128=1 src/test_cc_dbl.c -lquadmath \
# 	-o /dev/null 2> /dev/null && echo 1)

ifeq ($(HAVE_QUADMATH),1)
LDLIBS += -lquadmath
lib/libwigxjpf.a: lib/libwigxjpf_quadmath.a
endif

AUTO_CONFIG_TESTS = TEST_LONG_DOUBLE TEST_FLOAT128 \
	TEST_THREAD TEST_UINT128

gen/wigxjpf_auto_config.h.%: src/test_cc_dbl.c Makefile
	@echo "  AUTO   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)rm -f $@
	$(QUIET)echo "/* Autogenerated: test $* - editing is useless! */" > $@
	$(QUIET)$(CC) -D$*=1 $< -o $@.exe $(LDLIBS) -Werror \
	  > $@.cc.out 2> $@.cc.err && \
	  ./$@.exe \
	  > $@.run.out 2> $@.run.err && \
	  grep define $@.run.out >> $@ || true

gen/wigxjpf_auto_config.h: $(addprefix gen/wigxjpf_auto_config.h.,$(AUTO_CONFIG_TESTS))
	@echo "  AUTO   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)cat $^ > $@

obj/%.o: src/%.c $(HEADERS)
	@echo "   CC    $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CC) $(CFLAGS) -o $@ -c $<

obj/%.o: example/%.c $(HEADERS)
	@echo "   CC    $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CC) $(CFLAGS) -o $@ -c $<

obj/%.o: example/%.cc $(HEADERS)
	@echo "   CXX   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CXX) $(CFLAGS) -o $@ -c $<

obj/%.o: example/%.f $(HEADERS)
	@echo "   FC    $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(FC) $(FCFLAGS) -o $@ -c $<

lib/libwigxjpf.a: $(LIB_OBJECTS)
	@echo "   AR    $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(AR) $(ARFLAGS) $@ $(LIB_OBJECTS)
	$(QUIET)$(RLIB) $@

lib/libwigxjpf_quadmath.a: $(LIB_OBJECTS_QUADMATH)
	@echo "   AR    $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(AR) $(ARFLAGS) $@ $(LIB_OBJECTS_QUADMATH)
	$(QUIET)$(RLIB) $@

lib/libfpsimplexj.a: $(FPSIMPLE_OBJECTS)
	@echo "   AR    $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(AR) $(ARFLAGS) $@ $(FPSIMPLE_OBJECTS)
	$(QUIET)$(RLIB) $@

lib/libwigxjpf_shared.so: lib/libwigxjpf.a
	@echo "  LINK   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CC) -shared -Wl,-whole-archive $< -Wl,-no-whole-archive -o $@

lib/libwigxjpf_shared.dylib: lib/libwigxjpf.a
	@echo "  LINK   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CC) -dynamiclib -Wl,-force_load $< -o $@

bin/wigxjpf: obj/wigxjpf.o lib/libwigxjpf.a
	@echo "  LINK   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CC) $(LDFLAGS) -o $@ $< -Llib/  -lwigxjpf $(LDLIBS)

mod/fwigxjpf.mod: src/fwigxjpf.f
	@echo "   MOD   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)cd $(dir $@) ; $(FC) -c ../$<

obj/fsimple.o: mod/fwigxjpf.mod

bin/fsimple: obj/fsimple.o lib/libwigxjpf.a
	@echo "  LINK   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(FC) $(LDFLAGS) -o $@ $< -Llib/ -lwigxjpf $(LDLIBS)

bin/csimple: obj/csimple.o lib/libwigxjpf.a
	@echo "  LINK   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CC) $(LDFLAGS) -o $@ $<  -Llib/ -lwigxjpf $(LDLIBS)

bin/cthreadedsimple: example/cthreadedsimple.c lib/libwigxjpf.a
	@echo " CC+LINK $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CC) $(CFLAGS) -fopenmp $(LDFLAGS) -o $@ $< -Llib/ -lwigxjpf $(LDLIBS)

bin/ccsimple: obj/ccsimple.o lib/libwigxjpf.a
	@echo "  LINK   $@"
	$(QUIET)mkdir -p $(dir $@)
	$(QUIET)$(CXX) $(LDFLAGS) -o $@ $<  -Llib/ -lwigxjpf $(LDLIBS)

%simple.test: bin/%simple
	@echo "  CHECK  $@"
	$(QUIET)mkdir -p gen/
	$(QUIET)./$< > gen/$*simple.out
	$(QUIET)diff example/$*simple.good gen/$*simple.out
	$(QUIET)#touch $@ # Do not stamp, so test is re-run.

pysimple.test: example/pysimple.py shared
	@echo "  CHECK  $@"
	$(QUIET)mkdir -p gen/
	$(QUIET)PYTHONPATH=pywigxjpf/ ./$< > gen/pysimple.out
	$(QUIET)diff example/pysimple.good gen/pysimple.out
	$(QUIET)#touch $@ # Do not stamp, so test is re-run.

evaltable.%.test: bin/wigxjpf
	@echo "  CHECK  $@"
	$(QUIET)mkdir -p gen/
	$(QUIET)MEMUSE=$* STATS=" " example/evaltable.sh | \
	  sed -e "s/ //g" > gen/evaltable.$*.out
	$(QUIET)cat example/evaltable.$*.good | \
	  sed -e "s/#.*//" -e "s/ //g" -e '/^$$/d' > gen/evaltable.$*.cmpgood
	$(QUIET)diff gen/evaltable.$*.cmpgood gen/evaltable.$*.out
	$(QUIET)#touch $@ # Do not stamp, so test is re-run.

test: evaltable.small.test csimple.test
test-large: evaltable.large.test
test-huge: evaltable.huge.test

clean-test:
	rm -f *.test

clean: clean-test
	rm -rf obj/
	rm -rf gen/
	rm -rf lib/
	rm -rf bin/
	rm -rf mod/
