#-----------------------------------------------------------------------------
# GNU makefile for building WCSLIB 5.6 and its test suite.
#
# Summary of the main targets
# ---------------------------
#   build:     Build the library.
#
#   clean:     Delete intermediate object files.
#
#   cleaner:   clean, and also delete the test executables.
#
#   cleanest (distclean or realclean): cleaner, and also delete the object
#              library and the C source files generated by 'flex'.
#
#   check (or test): Compile and run the test programs.  By default they are
#              executed in batch mode, and non-graphical tests only report
#              "PASS" on success.  Use
#
#                make MODE=interactive check
#
#              to run them interactively with full diagnostic output.  To skip
#              graphical tests even if PGPLOT is available, use
#
#                make CHECK=nopgplot check
#
#   tests:     Compile the test programs (but don't run them).
#
# Notes:
#   1) If you need to make changes then preferably modify ../makedefs.in
#      instead and re-run configure.
#
# Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
# http://www.atnf.csiro.au/people/Mark.Calabretta
# $Id: GNUmakefile,v 5.6 2015/06/14 07:11:24 mcalabre Exp $
#-----------------------------------------------------------------------------
# Get configure settings.
include ../makedefs

FLEXMODS := $(patsubst %.l,%.c,$(wildcard *.l))
MODULES  := $(sort \
              $(patsubst %.c,%.o, \
                $(filter-out getwcstab.c,$(wildcard *.c)) $(FLEXMODS)))

ifeq "$(WCSTRIG)" "MACRO"
  CPPFLAGS += -DWCSTRIG_MACRO
  MODULES  := $(filter-out wcstrig.o, $(MODULES))
else
  ifeq "$(WCSTRIG)" "NATIVE"
    MODULES := $(filter-out wcstrig.o, $(MODULES))
  endif
endif

# For building the sharable library.
PICLIB := libwcs-PIC.a

CPPFLAGS += -I. -I..

vpath %.c  test
vpath %.h  ..
vpath %.in ..


# For building and exercising the test suite
# ------------------------------------------
# Test programs that don't require CFITSIO or PGPLOT...
TEST_N := tlin tdis1 tlog tprj1 tsph tsphdpa tspx ttab1 twcs twcssub tpih1 \
          tbth1 tfitshdr tunits twcsfix twcscompare

# ...and unofficial test programs.
TEST_n := tspcaips tspcspxe tspctrne twcs_locale

# Test programs that require CFITSIO (they don't need PGPLOT).
TEST_C := twcstab twcshdr twcslint

# Test programs that require PGPLOT but not PGSBOX.
TEST_P := tspc tprj2 tcel1 tcel2 ttab2 ttab3 twcsmix

# Test programs that require PGPLOT and PGSBOX.
TEST_B := tpih2

# Test programs that aren't automatically exercised.
TEST_X := tsphdpa twcshdr

TESTS  := $(TEST_N)

# Add test programs that require CFITSIO if we have it.
ifneq "$(CFITSIOINC)" ""
ifneq "$(CFITSIOLIB)" ""
  TESTS += $(TEST_C)
endif
endif

# Add test programs that require PGPLOT if we have it.
ifneq "$(CHECK)" "nopgplot"
ifneq "$(PGPLOTINC)" ""
ifneq "$(PGPLOTLIB)" ""
  TESTS += $(TEST_P) $(TEST_B)
endif
endif
endif

# Remove tests that aren't automatically exercised.
TESTS := $(filter-out $(TEST_X), $(TESTS))

PGSBOXLIB := ../pgsbox/libpgsbox-$(LIBVER).a

ADDRE := 0x[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]*

# Pattern rules
#--------------

ifeq "$(FLEX)" "flex"
  %.c : %.l
	-@ echo ''
	-@ $(RM) $@
	   $(FLEX) $(FLFLAGS) -t $< | sed -e 's/^[	 ]*#/#/' > $@
else
  %.c : %.l
	-@ echo ''
	-@ $(RM) $@
	   cp flexed/$@ .
endif

$(WCSLIB)(%.o) : %.c
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
	   $(AR) r $(WCSLIB) $%
	-@ $(RM) $%

$(PICLIB)(%.o) : %.c
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFLAGS) $(SHRFLAGS) -c $<
	   $(AR) r $(PICLIB) $%
	-@ $(RM) $%

%.i : %.c
	-@ echo ''
	-@ $(RM) $@
	   $(CPP) $(CPPFLAGS) $(CFLAGS) $< > $@

%.fits : test/%.keyrec tofits
	   ./tofits < $< > $@

# Print out include file dependencies.
%.d : %.c
	-@ echo ''
	-@ $(CPP) $(CPPFLAGS) $(CFLAGS) $< | \
	   sed -n -e 's|^# 1 "\([^/].*\.h\)".*|\1|p' | \
	   sort -u

# Use 'make FLAVOUR=Linux run_%' to have VALGRIND defined (from flavours).
run_% : %
	-@ echo ''
	-@ $(TIMER)
	 @ if [ '$(MODE)' = interactive -o '$(VALGRIND)' ] ; then \
	     printf 'Press <CR> to run $<: ' ; \
	     read DUMMY ; \
	   fi ; \
	   if [ '$(VALGRIND)' ] ; then \
	     if [ '$<' = tunits ] ; then \
	       $(VALGRIND) ./$< < test/units_test ; \
	     else \
	       $(VALGRIND) ./$< ; \
	     fi ; \
	   else \
	     if [ '$(filter $<, $(TEST_N) $(TEST_C))' ] ; then \
	       if [ '$<' = tunits ] ; then \
	         if [ '$(MODE)' = interactive ] ; then \
	           ./$< < test/units_test 2>&1 | tee $<.out ; \
	         else \
	           ./$< < test/units_test > $<.out 2>&1 ; \
	         fi ; \
	       else \
	         if [ '$(MODE)' = interactive ] ; then \
	           ./$< < /dev/null 2>&1 | tee $<.out ; \
	         else \
	           ./$< < /dev/null > $<.out 2>&1 ; \
	         fi ; \
	       fi ; \
	       if grep 'FAIL:' $<.out > /dev/null ; then \
	         if [ '$(MODE)' != interactive ] ; then \
	           head -2 $<.out ; \
	           grep 'FAIL:' $<.out ; \
	         fi ; \
	         echo 'FAIL: C/$<' >> test_results ; \
	       elif grep 'PASS:' $<.out > /dev/null ; then \
	         if [ '$(MODE)' != interactive ] ; then \
	           head -2 $<.out ; \
	           grep 'PASS:' $<.out ; \
	         fi ; \
	         echo 'PASS: C/$<' >> test_results ; \
	       elif [ -f 'test/$<.out' ] ; then \
	         trap 'rm -f run_test.tmp' 0 1 2 3 15 ; \
	         sed -e 's/$(ADDRE)/0x<address>/g' $<.out > \
	           run_test.tmp ; \
	         mv -f run_test.tmp $<.out ; \
	         if cmp -s $<.out test/$<.out ; then \
	           if [ '$(MODE)' != interactive ] ; then \
	             head -2 $<.out ; \
	           fi ; \
	           echo 'PASS: Output agrees with C/test/$<.out' ; \
	           echo 'PASS: C/$<' >> test_results ; \
	         else \
	           if [ '$(MODE)' != interactive ] ; then \
	             cat $<.out ; \
	           fi ; \
	           echo '' ; \
	           echo 'FAIL: Output disagrees with C/test/$<.out' ; \
	           echo 'FAIL: C/$<' >> test_results ; \
	         fi ; \
	       elif [ '$(MODE)' != interactive ] ; then \
	         cat $<.out ; \
	         echo 'FAIL: C/$<' >> test_results ; \
	       fi ; \
	     elif [ '$(MODE)' = interactive ] ; then \
	       ./$< ; \
	     else \
	       if [ '$<' = tcel2 ] ; then \
	         echo N | ./$< ; \
	       else \
	         ./$< < /dev/null 2>&1 ; \
	       fi ; \
	     fi ; \
	   fi
	-@ echo ''

# Static and static pattern rules
#--------------------------------

.PHONY : build check clean cleaner cleanest distclean install lib realclean \
         run_% test tests

build : lib

lib : $(FLEXMODS) $(WCSLIB) $(SHRLIB)

$(WCSLIB) : $(MODULES:%=$(WCSLIB)(%))
	-@ echo ''
	   $(RANLIB) $@

$(SHRLIB) : $(PICLIB)
	-@ echo ''
	-@ $(RM) -r tmp
	   mkdir tmp && \
	     cd tmp && \
	     trap 'cd .. ; $(RM) -r tmp' 0 1 2 3 15 ; \
	     $(AR) x ../$(PICLIB) && \
	     $(SHRLD) -o $@ *.o $(LDFLAGS) $(LIBS) && \
	     mv $@ ..

$(PICLIB) : $(MODULES:%.o=$(PICLIB)(%.o)) ;

install : build
	-  if [ ! -d "$(LIBDIR)" ] ; then \
	     $(INSTALL) -d -m 2775 $(LIBDIR) ; \
	   fi
	   $(INSTALL) -m 644 $(WCSLIB) $(LIBDIR)
	   $(RANLIB) $(LIBDIR)/$(WCSLIB)
	-  if [ -h "$(LIBDIR)/libwcs.a" ] ; then \
	     $(RM) $(LIBDIR)/libwcs.a ; \
	   fi
	-  $(LN_S) $(WCSLIB) $(LIBDIR)/libwcs.a
	-  if [ "$(SHRLIB)" != "" ] ; then \
	     $(INSTALL) -m 755 $(SHRLIB) $(LIBDIR) ; \
	     if [ -h "$(LIBDIR)/$(SONAME)" ] ; then \
	       $(RM) $(LIBDIR)/$(SONAME) ; \
	     fi ; \
	     $(LN_S) $(SHRLIB) $(LIBDIR)/$(SONAME) ; \
	     if [ "$(SHRLN)" != "" ] ; then \
	       if [ -h "$(LIBDIR)/$(SHRLN)" ] ; then \
	         $(RM) $(LIBDIR)/$(SHRLN) ; \
	       fi ; \
	       $(LN_S) $(SONAME) $(LIBDIR)/$(SHRLN) ; \
	     fi ; \
	   fi
	-  if [ ! -d "$(INCDIR)" ] ; then \
	     $(INSTALL) -d -m 2775 $(INCDIR) ; \
	   fi
	   $(INSTALL) -m 444 *.h $(INCDIR)
	   $(RM) $(INCLINK)
	   $(LN_S) $(notdir $(INCDIR)) $(INCLINK)

clean :
	- $(RM) -r *.o *.i a.out t*.out core *.dSYM $(EXTRA_CLEAN)

cleaner : clean
	-  $(RM) .gdb_history
	-  $(RM) $(TEST_N) $(TEST_n) $(TEST_X)
	-  $(RM) $(TEST_P) tpih2 twcstab twcshdr twcslint
	-  $(RM) tofits
	-  $(RM) bth.fits fitshdr.fits pih.fits wcslint.fits wcstab.fits
	-  $(RM) TPV3.fits TPV5.fits TPV7.fits SIP.fits
	-  $(RM) t*_cfitsio test_results

cleanest distclean realclean : cleaner
	-  $(RM) ../wcsconfig.h ../wcsconfig_tests.h
	-  $(RM) fitshdr.c wcsbth.c wcspih.c wcsulex.c wcsutrn.c
	-  $(RM) $(PICLIB) libwcs-*.a libwcs.so.* libwcs.*.dylib

check test : tests $(TESTS:%=run_%)

tests : $(TESTS) $(TEST_X)

$(TEST_N) $(TEST_n) : % : test/%.c $(WCSLIB)
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LDFLAGS) $(WCSLIB) $(LIBS)
	-@ $(RM) $@.o

$(TEST_P) : % : test/%.c $(WCSLIB)
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(PGPLOTINC) $(CFLAGS) -c -o $@.o $<
	   $(LD) -o $@ $@.o $(LDFLAGS) $(PGPLOTLIB) $(WCSLIB) $(FLIBS) $(LIBS)
	-@ $(RM) $@.o

tpih2 : test/tpih2.c $(PGSBOXLIB) $(WCSLIB)
	-@ echo ''
	   $(CC) $(CPPFLAGS) -I../pgsbox $(PGPLOTINC) $(CFLAGS) -c -o $@.o $<
	   $(LD) -o $@ $@.o $(LDFLAGS) $(PGSBOXLIB) $(PGPLOTLIB) $(WCSLIB) \
	     $(FLIBS) $(LIBS)
	-@ $(RM) $@.o

tfitshdr_cfitsio tpih1_cfitsio tbth1_cfitsio : %_cfitsio : test/%.c $(WCSLIB)
	-@ echo ''
	   $(CC) -DDO_CFITSIO $(CPPFLAGS) $(CFITSIOINC) $(CFLAGS) \
	     -o $@ $< $(LDFLAGS) $(CFITSIOLIB) $(WCSLIB) $(LIBS)
	-@ $(RM) $@.o

tpih2_cfitsio : test/tpih2.c $(PGSBOXLIB) $(WCSLIB)
	-@ echo ''
	   $(CC) -DDO_CFITSIO $(CPPFLAGS) -I../pgsbox $(PGPLOTINC) \
	     $(CFITSIOINC) $(CFLAGS) -c -o $@.o $<
	   $(LD) -o $@ $@.o $(LDFLAGS) $(PGSBOXLIB) $(PGPLOTLIB) \
	     $(CFITSIOLIB) $(WCSLIB) $(FLIBS) $(LIBS)
	-@ $(RM) $@.o

twcstab : test/twcstab.c $(GETWCSTAB) $(WCSLIB)
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFITSIOINC) $(CFLAGS) -o $@ $< $(GETWCSTAB) \
	     $(LDFLAGS) $(CFITSIOLIB) $(WCSLIB) $(LIBS)
	-@ $(RM) $@.o

twcshdr : test/twcshdr.c $(GETWCSTAB) $(WCSLIB)
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFITSIOINC) $(CFLAGS) -o $@ $< $(GETWCSTAB) \
	     $(LDFLAGS) $(CFITSIOLIB) $(WCSLIB) $(LIBS)
	-@ $(RM) $@.o

twcslint : test/twcslint
	-@ echo ''
	   cp $< .
	-@ chmod a+x $@

getwcstab.o : getwcstab.c getwcstab.h
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFLAGS) $(CFITSIOINC) -c $<

$(PGSBOXLIB) :
	-@ echo ''
	   $(MAKE) -C ../pgsbox $(notdir $@)

tofits : test/tofits.c
	   $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $<

GNUmakefile : ../makedefs ;

../makedefs ../wcsconfig.h ../wcsconfig_tests.h : makedefs.in wcsconfig.h.in \
    wcsconfig_tests.h.in ../config.status
	-@ $(RM) ../wcsconfig.h ../wcsconfig_tests.h
	   cd .. && ./config.status

show ::
	-@ -@ echo '  FLEXMODS    := $(FLEXMODS)'
	-@ -@ echo '  MODULES     := $(MODULES)'

# Dependencies (use the %.d pattern rule to list them)
#-----------------------------------------------------

$(WCSLIB)(cel.o)      : cel.h prj.h sph.h wcsconfig.h wcserr.h wcsmath.h \
                        wcsprintf.h wcstrig.h
$(WCSLIB)(fitshdr.o)  : wcsconfig.h fitshdr.h wcsutil.h
$(WCSLIB)(dis.o)      : dis.h wcserr.h wcsprintf.h wcsutil.h
$(WCSLIB)(lin.o)      : dis.h lin.h wcserr.h wcsprintf.h
$(WCSLIB)(log.o)      : log.h
$(WCSLIB)(prj.o)      : prj.h wcsconfig.h wcserr.h wcsmath.h wcsprintf.h \
                        wcstrig.h wcsutil.h
$(WCSLIB)(spc.o)      : spc.h spx.h wcsconfig.h wcserr.h wcsmath.h \
                        wcsprintf.h wcstrig.h wcsutil.h
$(WCSLIB)(sph.o)      : sph.h wcsconfig.h wcstrig.h
$(WCSLIB)(spx.o)      : spx.h wcserr.h wcsmath.h
$(WCSLIB)(tab.o)      : tab.h wcserr.h wcsmath.h wcsprintf.h wcsutil.h
$(WCSLIB)(wcs.o)      : cel.h dis.h lin.h log.h prj.h spc.h sph.h spx.h \
                        tab.h wcs.h wcsconfig.h wcserr.h wcsmath.h \
                        wcsprintf.h wcstrig.h wcsunits.h wcsutil.h
$(WCSLIB)(wcsbth.o)   : cel.h lin.h prj.h spc.h spx.h wcs.h wcshdr.h \
                        wcsmath.h wcsprintf.h wcsutil.h
$(WCSLIB)(wcserr.o)   : wcserr.h wcsprintf.h
$(WCSLIB)(wcsfix.o)   : cel.h lin.h prj.h spc.h sph.h spx.h wcs.h wcserr.h \
                        wcsfix.h wcsmath.h wcsunits.h wcsutil.h
$(WCSLIB)(wcshdr.o)   : cel.h lin.h prj.h spc.h spx.h tab.h wcs.h wcserr.h \
                        wcshdr.h wcsmath.h wcsutil.h
$(WCSLIB)(wcspih.o)   : cel.h lin.h prj.h spc.h spx.h wcs.h wcshdr.h \
                        wcsmath.h wcsprintf.h wcsutil.h
$(WCSLIB)(wcsprintf.o): wcsprintf.h
$(WCSLIB)(wcstrig.o)  : wcsconfig.h wcsmath.h wcstrig.h
$(WCSLIB)(wcsulex.o)  : wcserr.h wcsmath.h wcsunits.h wcsutil.h
$(WCSLIB)(wcsunits.o) : wcserr.h wcsunits.h
$(WCSLIB)(wcsutil.o)  : wcsmath.h wcsutil.h
$(WCSLIB)(wcsutrn.o)  : wcserr.h wcsunits.h

tbth1 tbth1_cfitsio : cel.h lin.h prj.h spc.h spx.h tab.h wcs.h wcsconfig.h \
                      wcsconfig_tests.h wcserr.h wcsfix.h wcshdr.h
tcel1   : cel.h prj.h
tcel2   : cel.h prj.h
tfitshdr tfitshdr_cfitsio : fitshdr.h wcsconfig.h wcsconfig_tests.h
tlin    : lin.h
tdis1   : cel.h dis.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcshdr.h \
          wcsprintf.h
tlog    : log.h
tpih1 tpih1_cfitsio : cel.h lin.h prj.h spc.h spx.h wcs.h wcsconfig.h \
                      wcsconfig_tests.h wcserr.h wcsfix.h wcshdr.h wcsprintf.h
tpih2 tpih2_cfitsio : cel.h lin.h prj.h spc.h spx.h wcs.h wcsconfig.h \
                      wcsconfig_tests.h wcshdr.h
tprj1   : prj.h wcsconfig.h wcstrig.h
tprj2   : prj.h
tspc    : spc.h spx.h wcsconfig.h wcstrig.h
tspcaips: spc.h spx.h
tspctrne: spc.h spx.h wcserr.h
tsph    : sph.h wcsconfig.h wcstrig.h
tsphdpa : sph.h
tspx    : spx.h
ttab1   : tab.h
ttab2   : tab.h
ttab3   : prj.h tab.h
tunits  : wcserr.h wcsunits.h
twcs    : cel.h fitshdr.h lin.h log.h prj.h spc.h sph.h spx.h tab.h wcs.h \
          wcsconfig.h wcsconfig_tests.h wcserr.h wcsfix.h wcshdr.h wcslib.h \
          wcsmath.h wcsprintf.h wcstrig.h wcsunits.h wcsutil.h
twcs_locale : cel.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcshdr.h \
              wcsprintf.h
twcsfix : cel.h lin.h prj.h spc.h spx.h wcs.h wcserr.h wcsfix.h wcsprintf.h \
          wcsunits.h
twcshdr : cel.h fitshdr.h getwcstab.h lin.h log.h prj.h spc.h sph.h spx.h \
          tab.h wcs.h wcsconfig.h wcserr.h wcsfix.h wcshdr.h wcslib.h \
          wcsmath.h wcsprintf.h wcstrig.h wcsunits.h wcsutil.h
twcsmix : cel.h lin.h prj.h spc.h sph.h spx.h wcs.h
twcssub : cel.h lin.h prj.h spc.h spx.h wcs.h wcserr.h
twcstab : cel.h fitshdr.h getwcstab.h lin.h log.h prj.h spc.h sph.h spx.h \
          tab.h wcs.h wcsconfig.h wcserr.h wcsfix.h wcshdr.h wcslib.h \
          wcsmath.h wcsprintf.h wcstrig.h wcsunits.h wcsutil.h

run_tdis1 : TPV3.fits TPV5.fits TPV7.fits
run_tbth1 run_tbth1_cfitsio : bth.fits
run_tfitshdr run_tfitshdr_cfitsio : fitshdr.fits
run_tpih1 run_tpih1_cfitsio : pih.fits
run_tpih2 run_tpih2_cfitsio : pih.fits
run_twcslint : wcslint.fits
run_twcs_locale : pih.fits
