#-----------------------------------------------------------------------------
# GNU makefile for building the WCSLIB 8.7 FORTRAN wrappers.
#
# 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.
#
#   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.
#
#   2) This makefile assumes that the WCSLIB 8.7 sources reside in ../C
#      (as in the distribution kit).
#
#   3) twcstab assumes that ../C/wcstab.fits has already been generated by
#      the corresponding C test program.
#
# Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
# http://www.atnf.csiro.au/computing/software/wcs
# $Id: GNUmakefile,v 8.7 2026/05/11 12:01:10 mcalabre Exp $
#-----------------------------------------------------------------------------
# Get configure settings.
SUBDIR := Fortran
include ../makedefs

CFILES  := $(sort $(wildcard *.c))
MODULES := $(sort $(patsubst %.c,%.o,$(CFILES)))
MODULES += $(sort $(patsubst %.f,%.o,$(wildcard *.f)))

ifdef BINDC
  # Using Fortran 2003 BIND(C) interoperability mechanism.
  MODULES  += $(sort $(patsubst %.f90,%.o,$(wildcard *.f90)))
  CPPFLAGS += -DBINDC
endif

# Including getwcstab_f.c causes the sharable library to depend on CFITSIO.
MODULES := $(filter-out getwcstab_f.o,$(MODULES))

ifdef GETWCSTAB
  FGETWCSTAB := ../C/getwcstab.o
endif

WCSLIB  := ../C/$(WCSLIB)
LIBLOCK := ../C/lib.lock

# Build the sharable library?
ifneq "$(SHRLIB)" ""
  PICLIB := ../C/libwcs-PIC.a
  SHRLIB := ../C/$(SHRLIB)
endif

CPPFLAGS += -I.. -I../C

# Required by some test programs that use PGPLOT.
WCSLEEP  := wcsleep_f.o

vpath %.h  ..:../C
vpath %.in ..


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

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

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

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

TESTS  := $(TEST_N)

# Do we have CFITSIO?
DO_CFITSIO := 1
ifeq "$(CFITSIOLIB)" ""
  DO_CFITSIO := 0
endif

ifeq "$(DO_CFITSIO)" "1"
  # Yes, add test programs that use it.
  TESTS += $(TEST_C)
  CFITSIO_CFLAGS := $(filter-out -Wpadded,$(CFLAGS))
endif

# Do we have PGPLOT?
DO_PGPLOT := 0
ifneq "$(CHECK)" "nopgplot"
  DO_PGPLOT := 1
  ifeq "$(PGPLOTLIB)" ""
    DO_PGPLOT := 0
  endif

  ifeq "$(DO_PGPLOT)" "1"
    # Yes, add test programs that use it.
    TESTS += $(TEST_P) $(TEST_B)
  endif
endif

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

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
#--------------

$(WCSLIB)(%.o) : %.c
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
	 @ if [ ! -f $(LIBLOCK) ] ; then \
	     echo $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \
	     $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \
	     $(RM) $% ; \
	   fi

$(WCSLIB)(%.o) : %.f
	-@ echo ''
	   $(FC) $(FFLAGS) -c $<
	 @ if [ ! -f $(LIBLOCK) ] ; then \
	     echo $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \
	     $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \
	     $(RM) $% ; \
	   fi

$(WCSLIB)(%.o) : %.f90
	-@ echo ''
	   $(FC) $(FFLAGS) -c $<
	 @ if [ ! -f $(LIBLOCK) ] ; then \
	     echo $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \
	     $(AR) r$(ARFLAGS) $(WCSLIB) $% ; \
	     $(RM) $% ; \
	   fi

$(PICLIB)(%_f.o) : $(WCSLIB)(%_f.o)
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFLAGS) $(SHRFLAGS) -c $(%:.o=.c)
	 @ if [ ! -f $(LIBLOCK) ] ; then \
	     echo $(AR) r$(ARFLAGS) $(PICLIB) $% ; \
	     $(AR) r$(ARFLAGS) $(PICLIB) $% ; \
	     $(RM) $% ; \
	   fi

$(PICLIB)(%_data.o) : $(WCSLIB)(%_data.o)
	-@ echo ''
	   $(FC) $(FFLAGS) $(SHRFLAGS) -c $(%:.o=.f)
	 @ if [ ! -f $(LIBLOCK) ] ; then \
	     echo $(AR) r$(ARFLAGS) $(PICLIB) $% ; \
	     $(AR) r$(ARFLAGS) $(PICLIB) $% ; \
	     $(RM) $% ; \
	   fi

$(PICLIB)(%_bindc.o) : $(WCSLIB)(%_bindc.o)
	-@ echo ''
	   $(FC) $(FFLAGS) $(SHRFLAGS) -c $(%:.o=.f90)
	 @ if [ ! -f $(LIBLOCK) ] ; then \
	     echo $(AR) r$(ARFLAGS) $(PICLIB) $% ; \
	     $(AR) r$(ARFLAGS) $(PICLIB) $% ; \
	     $(RM) $% ; \
	   fi

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

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

%.o : %.f
	-@ echo ''
	   $(FC) $(FFLAGS) -c $<

%.o : %.f90
	-@ echo ''
	   $(FC) $(FFLAGS) -c $<

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

# Static code analysis (clang-tidy).
%.sca : %.c ../.clang-tidy
	-@ echo ''
	   $(ANALYSE) $< -- 2>&1 | tee $@

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 \
	           ./$< < ../C/test/units_test 2>&1 | tee $<.out ; \
	         else \
	           ./$< < ../C/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: Fortran/$<' >> test_results ; \
	       elif grep 'PASS:' $<.out > /dev/null ; then \
	         if [ '$(MODE)' != interactive ] ; then \
	           head -2 $<.out ; \
	           grep 'PASS:' $<.out ; \
	         fi ; \
	         echo 'PASS: Fortran/$<' >> test_results ; \
	       elif [ -f 'test/$<.out' ] ; then \
	         trap 'rm -f run_$<.tmp' 0 1 2 3 15 ; \
	         sed -e 's/$(ADDRE)/0x<address>/g' \
	             -e 's/chksum:.*/chksum: <CHECKSUM>/' $<.out > \
	           run_$<.tmp ; \
	         mv -f run_$<.tmp $<.out ; \
	         if cmp -s $<.out test/$<.out ; then \
	           if [ '$(MODE)' != interactive ] ; then \
	             head -2 $<.out ; \
	             echo 'PASS: Output agrees with Fortran/test/$<.out' ; \
	           fi ; \
	           echo 'PASS: Fortran/$<' >> test_results ; \
	         else \
	           if [ '$(MODE)' != interactive ] ; then \
	             cat $<.out ; \
	           fi ; \
	           echo '' ; \
	           echo 'FAIL: Output disagrees with Fortran/test/$<.out' ; \
	           echo 'FAIL: Fortran/$<' >> test_results ; \
	         fi ; \
	       elif [ '$(MODE)' != interactive ] ; then \
	         cat $<.out ; \
	         echo 'FAIL: Fortran/$<' >> test_results ; \
	       fi ; \
	     elif [ '$(MODE)' = interactive ] ; then \
	       ./$< ; \
	     else \
	       if [ '$<' = tcel2 ] ; then \
	         echo N | ./$< ; \
	       else \
	         yes 2>/dev/null | ./$< 2>&1 ; \
	       fi ; \
	     fi ; \
	   fi
	-@ echo ''

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

.PHONY : analyse build check clean cleaner cleanest distclean install lib \
         realclean test tests uninstall

build : lib

lib :
	 @ $(MAKE) -C ../C lib
	-@ echo ''
	-@ echo 'Building WCSLIB Fortran wrappers...'
	 @ $(MAKE) --no-print-directory $(WCSLIB)

$(WCSLIB) : $(LIBLOCK) $(MODULES:%=$(WCSLIB)(%))
	-@ echo ''
	 @ set *.o ; \
	     if [ "$$1" != "*.o" ] ; then \
	       echo $(AR) r$(ARFLAGS) $@ *.o ; \
	       $(AR) r$(ARFLAGS) $@ *.o ; \
	       echo $(RANLIB) $@ ; \
	       $(RANLIB) $@ ; \
	       $(RM) *.o ; \
	     fi
	-@ $(RM) $<
	 @ if [ "$(SHRLIB)" != "" ] ; then \
	     $(MAKE) --no-print-directory $(SHRLIB) ; \
	   fi

$(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 $(@F) *.o $(LDFLAGS) $(LIBS) && \
	     mv $(@F) ../../C

$(PICLIB) : $(LIBLOCK) $(MODULES:%.o=$(PICLIB)(%.o))
	-@ echo ''
	 @ set *.o ; \
	     if [ "$$1" != "*.o" ] ; then \
	       echo $(AR) r$(ARFLAGS) $@ *.o ; \
	       $(AR) r$(ARFLAGS) $@ *.o ; \
	       $(RM) *.o ; \
	     fi
	-@ $(RM) $<

$(LIBLOCK) : FORCE
	 @ $(RM) *.o
	 @ touch $@

analyse : $(CFILES:%.c=%.sca)

install : build
	$(MAKE) -C ../C install
	$(INSTALL) -m 444 *.inc $(INCDIR)

uninstall :
	$(MAKE) -C ../C uninstall

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

cleaner : clean
	-  $(RM) .gdb_history
	-  $(RM) $(TEST_N)
	-  $(RM) $(TEST_P) tpih2 twcstab
	-  $(RM) fitshdr.fits pih.fits TPV7.fits test_results

cleanest distclean realclean : cleaner
	-  $(RM) $(WCSLIB) $(PICLIB) $(SHRLIB)

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

tests : $(TESTS)

$(TEST_N) : % : test/%.f $(WCSLIB)
	-@ echo ''
	   $(FC) $(FFLAGS) -o $@ $< $(LDFLAGS) $(WCSLIB) $(LIBS)
	-@ $(RM) $@.o

$(TEST_P) : % : test/%.f $(WCSLIB) $(WCSLEEP)
	-@ echo ''
	   $(FC) $(FFLAGS) -o $@ $< $(LDFLAGS) $(WCSLIB) $(WCSLEEP) $(PGPLOTLIB) $(LIBS)
	-@ $(RM) $@.o

tpih2 : % : test/%.f $(PGSBOXLIB) $(WCSLIB) $(WCSLEEP)
	-@ echo ''
	   $(FC) $(FFLAGS) -o $@ $< $(LDFLAGS) $(PGSBOXLIB) $(WCSLIB) \
	     $(WCSLEEP) $(PGPLOTLIB) $(LIBS)
	-@ $(RM) $@.o

twcstab : test/twcstab.f getwcstab_f.o getwcstab.inc $(FGETWCSTAB) \
    $(WCSLIB)
	-@ echo ''
	   $(FC) $(FFLAGS) -o $@ $< getwcstab_f.o $(FGETWCSTAB) \
	     $(LDFLAGS) $(CFITSIOLIB) $(WCSLIB) $(LIBS)
	-@ $(RM) $@.o $(FGETWCSTAB)

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

../C/getwcstab.o ::
	-@ echo ''
	   $(MAKE) -C ../C getwcstab.o

$(WCSLEEP) : test/wcsleep_f.c
	-@ echo ''
	   $(CC) $(CPPFLAGS) $(CFLAGS) -c $<

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

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

../C/wcstab.fits : ;

GNUmakefile : ../makedefs ;

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

show ::
	-@ echo '  BINDC       := $(BINDC)'
	-@ echo '  CFILES      := $(CFILES)'
	-@ echo '  MODULES     := $(MODULES)'
	-@ echo '  DO_CFITSIO  := $(DO_CFITSIO)'
	-@ echo '  DO_PGPLOT   := $(DO_PGPLOT)'
	-@ echo '  TESTS       := $(TESTS)'

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

$(WCSLIB)(cel_f.o)      : cel.h prj.h wcsconfig_f77.h wcserr.h wcsutil.h
$(WCSLIB)(dis_f.o)      : dis.h wcsconfig_f77.h wcserr.h wcsutil.h
$(WCSLIB)(fitshdr_f.o)  : fitshdr.h wcsconfig.h wcsconfig_f77.h wcsutil.h
$(WCSLIB)(getwcstab_f.o): getwcstab.h wcsconfig_f77.h
$(WCSLIB)(lin_f.o)      : dis.h lin.h wcsconfig_f77.h wcserr.h wcsutil.h
$(WCSLIB)(log_f.o)      : log.h wcsconfig_f77.h
$(WCSLIB)(prj_f.o)      : prj.h wcsconfig_f77.h wcserr.h wcsutil.h
$(WCSLIB)(spc_f.o)      : spc.h spx.h wcsconfig_f77.h wcserr.h wcsutil.h
$(WCSLIB)(sph_f.o)      : sph.h wcsconfig_f77.h
$(WCSLIB)(spx_f.o)      : spx.h wcsconfig_f77.h wcserr.h
$(WCSLIB)(tab_f.o)      : tab.h wcsconfig_f77.h wcserr.h wcsutil.h
$(WCSLIB)(wcs_f.o)      : cel.h lin.h prj.h spc.h spx.h wcs.h \
                          wcsconfig_f77.h wcserr.h wcsutil.h
$(WCSLIB)(wcsfix_f.o)   : cel.h lin.h prj.h spc.h spx.h wcs.h \
                          wcsconfig_f77.h wcserr.h wcsfix.h
$(WCSLIB)(wcshdr_f.o)   : cel.h lin.h prj.h spc.h spx.h wcs.h \
                          wcsconfig_f77.h wcshdr.h
$(WCSLIB)(wcsunits_f.o) : wcsconfig_f77.h wcserr.h wcsunits.h wcsutil.h

tcel1   : cel.inc prj.inc
tdis1   : lin.inc wcs.inc wcserr.inc wcshdr.inc
tdis2   : dis.inc lin.inc wcs.inc wcserr.inc wcshdr.inc
tfitshdr: fitshdr.inc wcshdr.inc
tlin    : lin.inc
tlog    : log.inc
tpih1   : wcs.inc wcsfix.inc wcshdr.inc
tpih2   : wcs.inc wcshdr.inc
tprj1   : prj.inc
tprj2   : prj.inc
tspc    : spc.inc spx.inc
tspx    : spx.inc
ttab1   : tab.inc
ttab2   : tab.inc
ttab3   : prj.inc tab.inc
tunits  : wcsunits.inc
twcs    : cel.inc prj.inc wcs.inc wcserr.inc wcsmath.inc
twcsfix : wcs.inc wcsfix.inc wcsunits.inc
twcsmix : cel.inc lin.inc prj.inc wcs.inc
twcssub : wcs.inc wcserr.inc
twcstab : getwcstab.inc wcs.inc wcsfix.inc wcshdr.inc

run_tdis1 run_tdis2 : TPV7.fits
run_tfitshdr : fitshdr.fits
run_tpih1 run_tpih2: pih.fits
run_twcstab: ../C/wcstab.fits
