
################## FXT makefile ##########################

CXX = g++
PPLIB = -lm -lstdc++
CXXFLAGS += -pipe -fno-exceptions
#CXXFLAGS += -D__NO_MATH_INLINES

#ARCHFLAG = -march=i586 # k6, i586, i686 ...  <--= ADJUST THIS to your CPU type
OFLAGS = -O -ffast-math
OFLAGS += $(ARCHFLAG)
OFLAGS += -fomit-frame-pointer # <--= disable for profiling
#OFLAGS += -malign-double
#OFLAGS += -mwide-multiply
#OFLAGS += -fschedule-insns2
#OFLAGS += -finline -finline-functions
#OFLAGS += -fimplicit-templates

# warnings:
WFLAGS = -Wall -Wstrict-prototypes -Wconversion
WFLAGS += -Winline
WFLAGS += -Wsign-promo
#WFLAGS += -Weffc++
#WFLAGS += -pedantic

# debuging:
GFLAGS = -g
#GFLAGS += -fno-inline -fno-default-inline

# profiling:
PFLAGS = -pg

IFLAGS = -I. -Iinclude -Iauxil -Ipermute -Imod -Iwavelet

#### choose the FLAG combo here:
CXXFLAGS += $(IFLAGS)
CXXFLAGS += $(WFLAGS) # uncomment for WARNINGS
CXXFLAGS += $(OFLAGS) # uncomment for OPTIMIZATION
#CXXFLAGS += $(PFLAGS) # uncomment for PROFILING
#CXXFLAGS += $(GFLAGS) # uncomment for DEBUGGING

#-------------------------------------


AUXOBJS= \
auxil/jjassert.o \
auxil/auxdouble.o \
auxil/auxprint.o \
auxil/sincos.o \
auxil/sincostb.o \
auxil/resample.o \
auxil/workspace.o \
auxil2d/array2d.o \
permute/revbinpermute.o \
permute/evenoddpermute.o \
permute/graypermute.o \

FFTOBJS= \
fft/fftdit4.o \
fft/fftdif4.o \
fft/fft8ditcore.o \
fft/fft8difcore.o \
fft/fft9.o \
fft/fftsplitradix.o \
fft/cfftsplitradix.o \
fft/fftcocnvl.o \
fft/fftcocorr.o \
fft/fftcnvl.o \
fft/fftcnvla.o \
fft/fftcorr.o \
fft/fftspect.o \
fft/fouriershift.o \
fft/skipfft.o \
fft/cfftwrap.o \

REALFFTOBJS= \
realfft/realfftbyfht.o \
realfft/realfftwrap.o \
realfft/realffteasyord.o \
realfft/realfftsplitradix.o \
realfft/skiprealfft.o \

OTHERFFTOBJS= \
chirp/fftarblen.o \
chirp/fftfract.o \
chirp/makechirp.o \
ndimfft/twodimfft.o \
ndimfft/ndimfft.o \
#chirp/fzt.o \

MATRIXOBJS= \
matrix/columnffts.o \
matrix/rowffts.o \
matrix/rowcnvls.o \
matrix/transpos2.o \
matrix/ctranspos2.o \
matrix/matrixfft.o \
matrix/matrixcnvl.o \
matrix/matrixcnvla.o \
matrix/matrixcocnvla.o \

FHTOBJS= \
fht/fhtsplitradixdit.o \
fht/fhtsplitradixdif.o \
fht/cfhtsplitradixdit.o \
fht/cfhtsplitradixdif.o \
fht/fht0.o \
fht/cfht0.o \
fht/fhttable.o \
fht/fhtfft.o \
fht/fhtcfft.o \
fht/fhtcnvl.o \
fht/cfhtcnvl.o \
fht/fhtcnvla.o \
fht/cfhtcnvla.o \
fht/fhtnegacnvla.o \
fht/fhtcorr.o \
fht/fhtspect.o \
fht/hartleyshift.o \
fht/skipfht.o \
fht/twodimfht.o \
fht/twodimfhtcnvl.o \

DCTDSTOBJS= \
dctdst/dcth.o \
dctdst/dctzapata.o \
dctdst/dsth.o \
dctdst/dst.o \
#dctdst/dct.o \

SLOWOBJS= \
slow/slowft.o \
slow/slowht.o \
slow/slowcnvl.o \
slow/slowcocnvl.o \
slow/slowcorr.o \
slow/slowcocorr.o \
slow/slowfracft.o \
slow/slowtwodimft.o \
slow/slowtwodimht.o \
slow/slowrowcolht.o \
slow/slowtwodimcnvl.o \
slow/slowwalsh.o \
slow/slowzt.o \

LEARNOBJS= \
learn/recfftdit2.o \
learn/recfftdif2.o \
learn/recfhtdit2.o \
learn/recfhtdif2.o \
learn/fftdit2.o \
learn/fftdif2.o \
learn/fftdit4l.o \
learn/fftdif4l.o \
learn/fhtdit2.o \
learn/fhtdif2.o \
learn/nttlearn.o \

WALSHOBJS= \
walsh/walshdit2.o \
walsh/walshdif2.o \
walsh/walshcirc.o \
walsh/walshseq.o \
walsh/walsh0.o \
walsh/dyadiccnvl.o \

HAAROBJS= \
haar/haar.o \
haar/inthaar.o \
haar/haarinplace.o \

WAVELETOBJS= \
wavelet/wavelet.o \
wavelet/invwavelet.o \
wavelet/waveletfilter.o \
wavelet/harmonicwavelet.o \
#wavelet/nrwavelet.o \

WEIGHTEDOBJS= \
weighted/weightedfft.o \
weighted/weightedconv.o \
#weighted/weightedfht.o \

FXTMULTOBJS = \
mult/auxil.o \
mult/carry.o \
mult/fxtmult.o \
mult/fxtsquare.o \
mult/fxtmultiply.o \
mult/multsqr.o \
mult/diskaux.o \
mult/diskaux2.o \
mult/diskrowpass.o \
mult/diskcolpass.o \
mult/diskcnvla.o \
mult/disksquare.o \
mult/diskmultiply.o \
#mult/diskcnvl.o \

MODOBJS= \
mod/mod.o \
mod/modinit.o \
mod/modinfo.o \
mod/modfuncs.o \
mod/auxfuncs.o \
mod/maxorder.o \
mod/primroot.o \
mod/erastothenes.o \
mod/order.o \
mod/modaux.o \
mod/mrevbinpermute.o  \
mod/factor.o \
mod/arithmodm.o \
mod/chinese.o \
mod/sqrtmod.o \
mod/kronecker.o \
mod/rabinmiller.o \
mod/phi.o \
mod/gcd.o \
mod/ipow.o \

NTTOBJS= \
mod/nttcnvl.o \
mod/slownttcnvl.o \
mod/slowntt.o \
mod/nttdit2.o \
mod/nttdif2.o \
mod/nttdif2nc.o \
mod/nttdit4.o \
mod/nttdif4.o \
mod/nttskip.o \
mod/nttndim.o \
mod/nttaux.o \

#
OBJS =
OBJS += $(AUXOBJS)
OBJS += $(FFTOBJS)
OBJS += $(REALFFTOBJS)
OBJS += $(FHTOBJS)
OBJS += $(OTHERFFTOBJS)
OBJS += $(MATRIXOBJS)
OBJS += $(DCTDSTOBJS)
OBJS += $(SLOWOBJS)
OBJS += $(LEARNOBJS)
OBJS += $(WALSHOBJS)
OBJS += $(HAAROBJS)
OBJS += $(WAVELETOBJS)
OBJS += $(WEIGHTEDOBJS)
OBJS += $(FXTMULTOBJS)
OBJS += $(MODOBJS)
OBJS += $(NTTOBJS)


#
SRC=$(OBJS:.o=.cc)


FXTLIB=libfxt.a

#-------------------------------------

%.o : %.cc
	$(CXX) $(CXXFLAGS) -c $< -o $@

.PHONY: all lib
all: lib
lib: $(FXTLIB)

$(FXTLIB): $(OBJS)
	@echo 'BUILDING THE FXT ARCHIVE: $(FXTLIB) '
	@ar rcs $(FXTLIB) $(OBJS)
#	nm -C $(FXTLIB)

PREFIX=/usr/local
LIBDIR=$(PREFIX)/lib/fxt
INCDIR=$(PREFIX)/include/fxt
INSTHDRS=`ls -1 */*.h | grep -v bucket | grep -v generators | grep -v play`

.PHONY: install
install: lib
	@echo 'PREFIX=$(PREFIX)  LIBDIR=$(LIBDIR)  INCDIR=$(INCDIR)'
	@test -d $(LIBDIR)  ||  mkdir $(LIBDIR)
#	rm -f $(LIBDIR)/*
	cp -auv $(FXTLIB) $(LIBDIR)/
	@test -d $(INCDIR)  ||  mkdir $(INCDIR)
#	rm -f $(INCDIR)/*
	cp -auv $(INSTHDRS) $(INCDIR)/

.PHONY: obj objs
obj:  objs
objs: $(OBJS)


TESTBIN=bin

TESTSRC=test/paranoia.cc
.PHONY: pa paranoia te test
te: paranoia
test: paranoia
pa: paranoia
paranoia: lib
	$(CXX) $(TESTSRC) $(CXXFLAGS) -g -O0 $(FXTLIB) -o $(TESTBIN) $(PPLIB)
	$(TESTBIN)

PLAYSRC= play/test.cc
#PLAYSRC= play/fftprimes.cc
#PLAYSRC= play/fat.cc
#PLAYSRC= play/walshbases.cc # show walsh bases
#PLAYSRC= play/2dim.cc
#PLAYSRC= play/matrix.cc # demonstrate revbinpermute-for-transpose algorithm
#PLAYSRC= play/testmod.cc
.PHONY: pl play test
pl: play
play: lib
	$(CXX) $(PLAYSRC) $(CXXFLAGS) -g -O0 $(FXTLIB) -o $(TESTBIN) $(PPLIB)
	$(TESTBIN)


TIMESRC= play/time.cc
.PHONY: ti time
ti: time
time: lib
	$(CXX) $(TIMESRC) $(CXXFLAGS) $(FXTLIB) -o $(TESTBIN) $(PPLIB) -lg++
	$(TESTBIN)

PRTMP=tmp-prof.txt
.PHONY: pr prof
pr: prof
prof: lib
	test -f gmon.out
	gprof -b $(TESTBIN)  |  grep -B 9999 'Call graph' > $(PRTMP)
	replace -fq 'unsigned long' 'ulong'  $(PRTMP)
	replace -fq 'complex<double>' 'Complex'  $(PRTMP)
	cat  $(PRTMP)


############## CALLALL ##############
.PHONY: ca callall
CALLSRC= callall.cc
ca: callall
callall: lib
	cat scripts/callall.head > $(CALLSRC)
	scripts/mkcallall.pl < include/fxt.h >> $(CALLSRC)
	scripts/mkcallall.pl < mod/ntt.h >> $(CALLSRC)
	cat scripts/callall.tail >> $(CALLSRC)
	$(CXX) $(CALLSRC) $(CXXFLAGS) -g -O0 $(FXTLIB) $(PPLIB) -o $(TESTBIN)
	$(TESTBIN)
	rm $(TESTBIN)
#	rm $(CALLSRC)
	@echo 'OK.'


############## CHKNAMES & AUTODOC ##############

ADOC=scripts/autodoc.sh
ALOG=/tmp/autodoc.log
#REDIRECT1=1> /dev/null
REDIRECT2=2>> $(ALOG)

PERMHDR= \
permute/reverse.h \
permute/rotate.h \
permute/evenoddpermute.h \
permute/evenoddrevpermute.h \
permute/graypermute.h \
permute/revbinpermute.h \

AUXHDR= \
auxil/inline.h \
auxil/auxbit.h \
auxil/auxdouble.h \
auxil/copy.h \
auxil/minmax.h \
auxil/scale.h \
auxil/scan.h \
auxil/scanbox.h \
auxil/shift.h \
auxil/misc.h \

AUX2HDR= \
auxil2d/copy2d.h \
auxil2d/reverse2d.h \
auxil2d/rotate2d.h \
auxil2d/shift2d.h \
auxil2d/scale2d.h \
auxil2d/minmax2d.h \
auxil2d/transpose.h \
auxil2d/misc2d.h \

.PHONY: doc autodoc
doc autodoc:
	rm -f $(ALOG)
	$(ADOC) include/fxt.h      > doc/fxt.h-doc.txt        $(REDIRECT2)
	$(ADOC) auxil/auxdouble.h  > doc/auxdouble.h-doc.txt  $(REDIRECT2)
	$(ADOC) auxil/auxbit.h     > doc/auxbit.h-doc.txt     $(REDIRECT2)
	$(ADOC) mod/ntt.h          > doc/ntt.h-doc.txt	      $(REDIRECT2)
	$(ADOC) include/fxt.h  fft    > doc/fft-doc.txt $(REDIRECT2)
	$(ADOC) include/fxt.h  fht    > doc/fht-doc.txt $(REDIRECT2)
	$(ADOC) include/fxt.h  'convol|correl' > doc/convolution-doc.txt  $(REDIRECT2)
	$(ADOC) include/fxt.h  slow  > doc/slow-doc.txt     $(REDIRECT2)
	$(ADOC) include/fxt.h  walsh > doc/walsh-doc.txt    $(REDIRECT2)
	$(ADOC) $(PERMHDR)           > doc/permute-doc.txt  $(REDIRECT2)
	$(ADOC) $(AUXHDR)            > doc/auxil-doc.txt    $(REDIRECT2)
	$(ADOC) $(AUX2HDR)           > doc/auxil2d-doc.txt  $(REDIRECT2)
	true
	echo "// -*- C++ -*-"                >  doc/fyi-doc.txt
	echo -e "// output of 'make fyi':\n" >> doc/fyi-doc.txt
	$(MAKE) --no-print-directory showfyi >> doc/fyi-doc.txt
	@echo 'OK.'

.PHONY: cn chknames
cn chknames:
	$(MAKE) doc || less $(ADOC)

############## SHOWFYI ##############

.PHONY: fyi showfyi
fyi showfyi:
	@FYISRC=`grep -l 'FYI' $(SRC)`; \
 for f in $$FYISRC; do \
  echo "----- $$f: -----"; \
  grep -v '^//#' $$f | grep -B1 'FYI'; \
  echo; \
 done

############## DOXYGEN: ##############

.PHONY: dox doxygen
dox doxygen:
	doxygen scripts/doxygen.conf

############## GENERATORS ##############
SFLAGS= -O2 -ffast-math -fverbose-asm $(ARCHFLAG)  -g
#SFLAGS+=-fschedule-insns2
FILEBASE=tmp
CCFILE=$(FILEBASE).cc
ASFILE=$(FILEBASE).s
LSFILE=$(FILEBASE)-lst.s
EXFILE=$(FILEBASE).exe

GEN=generators
AUXGEN=$(GEN)/auxgen.cc

#GENSRC=$(GEN)

ISIGN=+1
LDN=5
.PHONY: mkgen
mkgen: lib
	$(CXX) $(WFLAGS) -g $(GENSRC) $(AUXGEN) $(IFLAGS) -o $(TESTBIN) $(PPLIB) $(FXTLIB)
	$(TESTBIN) $(LDN) $(ISIGN)
#	rm -f $(CCFILE) $(ASFILE) $(EXFILE)

.PHONY: chkgen
chkgen:
	set - ; \
 echo "ldn = $(LDN) "; \
 $(TESTBIN) $(LDN) $(ISIGN) > $(CCFILE); \
 $(CXX)  $(WFLAGS) $(IFLAGS) $(CCFILE) -S $(SFLAGS) -o $(ASFILE); \
 grep '#' $(CCFILE) | grep '//'; \
 $(CXX)  $(WFLAGS) $(IFLAGS) $(CCFILE) -g $$CHKSRC -o $(EXFILE) $(PPLIB) $(FXTLIB); \
 $(EXFILE) $(LDN) $(ISIGN);


#GREPHACK=grep -A9999 '@function' | grep -B9999 'scope0'
# cat $(ASFILE) | $(GREPHACK) > tmp;  generators/opcount.sh tmp >> $(CCFILE); \
# as -alhn $(ASFILE) | $(GREPHACK) | grep -v '\.L[MB]' > $(LSFILE); \
# replace -fq $(CCFILE) ';$(CCFILE)' $(LSFILE); \


.PHONY: genfht
genfht: lib
	export GENSRC=$(GEN)/genfht.cc ;  $(MAKE) mkgen
#	export CHKSRC=$(GEN)/chkgenfht.cc ;  $(MAKE) chkgen

.PHONY: genfft
genfft: lib
	export GENSRC=$(GEN)/genfft.cc ;  $(MAKE) mkgen
#	export CHKSRC=$(GEN)/chkgenfft.cc ;  $(MAKE) chkgen


.PHONY: gencyc
gencyc: $(GEN)/gencycles.cc lib
	$(CXX) $(WFLAGS) $(IFLAGS) $< -o $(TESTBIN) $(PPLIB) $(FXTLIB);
	$(TESTBIN) -5

.PHONY: genrbp
genrbp: $(GEN)/genrevbinpermute.cc lib
	$(CXX) $(WFLAGS) $(IFLAGS) $< -o $(TESTBIN) $(PPLIB) $(FXTLIB);
	$(TESTBIN) 5


############## METAGEN: ##############

.PHONY: mg metagen mg1 mg2
mg: metagen
metagen: mg1 mg2
MG=scripts/metagen.pl
mg1:
#	cp auxil/revbinpermute.cc tmp && replace -f Type double tmp && $(MG) revbin_permute n < tmp > tmp1.cc
	$(MG) dif4_fft_core ldn < fft/fftdif4.cc > tmp1.cc
#	$(MG) split_radix_dif_fht_core ldn < fht/fhtsplitradixdif.cc > tmp1.cc
#	$(MG) split_radix_fft_dif_core ldn < fft/fftsplitradix.cc > tmp1.cc

mg2:
	$(CXX) $(IFLAGS) -g -I generators generators/auxgen.cc tmp1.cc -o tmp1 $(PPLIB) $(FXTLIB)
	echo 5 | tmp1 > tmp2.cc
	$(CXX) $(CXXFLAGS) tmp2.cc -o tmp2 $(PPLIB) $(FXTLIB)


############## MKCOMPL: ##############
#  automatically generate Complex versions of some files

MKCOMPL=scripts/mkcompl.sh
.PHONY: mkcompl
mkcompl:
	export NAME=fhtsplitradixdit.cc;  export CNAME=c$$NAME;  cd fht  &&  ../$(MKCOMPL)
	export NAME=fhtsplitradixdif.cc;  export CNAME=c$$NAME;  cd fht  &&  ../$(MKCOMPL)
	export NAME=fht0.cc;              export CNAME=c$$NAME;  cd fht  &&  ../$(MKCOMPL)
	export NAME=fhtcnvla.cc;          export CNAME=c$$NAME;  cd fht  &&  ../$(MKCOMPL)
	export NAME=fhtcnvl.cc;           export CNAME=c$$NAME;  cd fht  &&  ../$(MKCOMPL)
	export NAME=transpos2.cc;         export CNAME=c$$NAME;  cd matrix  &&  ../$(MKCOMPL)


.PHONY: pre
pre:
	$(CXX) -E -H -dM  $(CXXFLAGS) test/testpre.cc | sort


#-------------------------------------

DEP=depend.mk

include $(DEP)

.PHONY: dep depend
dep depend:
	rm -f $(DEP)
	$(MAKE) $(DEP)

$(DEP):
	$(CXX) -MM $(IFLAGS) $(SRC) > $(DEP)
	@echo 'FIXING $(DEP), sigh ...'
	@scripts/fixdepend.pl '$(strip $(OBJS))' < depend.mk > depend.fixed
	mv depend.fixed depend.mk


#-------------------------------------


.PHONY: clean
clean:
	rm -f  a.out core .gdb_history gmon.out $(TESTBIN)
	-find . -name \*.o -exec rm {} \;
	cd simplfft && $(MAKE) clean
	-mv -v tmp* /tmp/ &> /dev/null
	rm -f $(CALLSRC)

.PHONY: clobber
clobber:
	$(MAKE) clean
	rm -f  $(FXTLIB)
	cd simplfft && $(MAKE) clobber


CCFILES=`find . -name \*.cc -mindepth 1 | grep -v bucket | grep -v play | grep -v include`
.PHONY: showsrc
showsrc:
	@for f in $(CCFILES); do  echo $$f; done > tmp1
	@for f in $(SRC); do  echo "./$$f"; done >> tmp1
	@sort tmp1 > tmp2
	@echo 'NON source files are:'
	@-uniq -u tmp2
#	@rm tmp1 tmp2

.PHONY: shownote shownotes
shownote: shownotes
shownotes:
	-grep -i -A1 jjnote `find . -name \*.cc`  | grep -v bucket

.PHONY: new
new:
	@echo recompiling everything ...
	$(MAKE) clobber
	$(MAKE) depend
	$(MAKE) all


.PHONY: bak
bak: doc
	$(MAKE) clobber
	cp -aruv * /bak/jj/fxt/


ZBAK=/bak/zbak/fxt/fxt-`date '+%Y.%m.%d'`.tgz
.PHONY: zbak
zbak: check lsmdate doc
	$(MAKE) clobber
	cd .. &&  tar -cvzf $(ZBAK) fxt &&  ls -l $(ZBAK)
	cp $(ZBAK) /tmp


WEBDIR=/home/jj/www/public_html/fxt/
.PHONY: 2web
2web:
	cp -puv $(ZBAK) $(WEBDIR)
	cp -puv doc/*   $(WEBDIR)
	cp -puv include/fxt.h  $(WEBDIR)
	cp -puv fxt.lsm $(WEBDIR)

.PHONY: zbaka
zbaka: zbak
	mcopy -o $(ZBAK) fxt.lsm doc/fxt.h-doc.txt a:
	-mmd -o dito
	mcopy -o $(ZBAK) fxt.lsm doc/fxt.h-doc.txt a:dito
	mdir -/

LSMDATE=`date +%d%b%Y | tr a-z A-Z`
.PHONY: lsmdate date
date: lsmdate
lsmdate:
	replace 'Entered-date.*$$' "Entered-date:   $(LSMDATE)" fxt.lsm


.PHONY: check
check:
	@echo
	@echo '********* do a "make callall" *********'
	@echo
	grep -i date fxt.lsm
	date
	@echo
	@echo CXX is $(CXX)
	@echo
	@echo CXXFLAGS are $(CXXFLAGS)
	@echo

.PHONY: help
help:
	grep '^\.PHONY' *akefile*

################## end FXT makefile ##########################
