
#Files containing evolution equations initial power spectrum module
EQUATIONS     ?= equations
POWERSPECTRUM ?= power_tilt
REIONIZATION ?= reionization
RECOMBINATION ?= recfast


BISPECTRUM ?= SeparableBispectrum

#Module doing non-linear scaling
NONLINEAR     ?= halofit_ppf

#Driver program
DRIVER        ?= inidriver.F90
#DRIVER       ?= sigma8.f90
#DRIVER       ?= tester.f90

Release: OUTPUT_DIR = Release
Debug: OUTPUT_DIR = Debug

Release: PYCAMB_OUTPUT_DIR = pycamb/camb
Release: DLL_DIR = Releaselib
Debug: DLL_DIR = Debuglib

OUTPUT_DIR ?= Release
PYCAMB_OUTPUT_DIR ?= pycamb/camb
DLL_DIR ?= Releaselib

Release: camb camblib.so
Debug: camb camblib.so


CAMBLIB       = $(OUTPUT_DIR)/libcamb_$(RECOMBINATION).a

F90FLAGS      = $(FFLAGS)
F90FLAGS += $(MODOUT) $(IFLAG)$(OUTPUT_DIR)/

SF90FLAGS      = $(SFFLAGS) $(FFLAGS)
SF90FLAGS += $(SMODOUT) $(IFLAG)$(DLL_DIR)/

HEALPIXLD     = -L$(HEALPIXDIR)/lib -lhealpix -L$(FITSDIR) -l$(FITSLIB)

CAMBOBJ       =  $(OUTPUT_DIR)/constants.o  $(OUTPUT_DIR)/utils.o $(EXTCAMBFILES)  $(OUTPUT_DIR)/subroutines.o  \
	$(OUTPUT_DIR)/inifile.o  $(OUTPUT_DIR)/$(POWERSPECTRUM).o  $(OUTPUT_DIR)/$(RECOMBINATION).o \
	$(OUTPUT_DIR)/$(REIONIZATION).o $(OUTPUT_DIR)/modules.o $(OUTPUT_DIR)/bessels.o $(OUTPUT_DIR)/$(EQUATIONS).o \
	$(OUTPUT_DIR)/$(NONLINEAR).o $(OUTPUT_DIR)/lensing.o $(OUTPUT_DIR)/$(BISPECTRUM).o $(OUTPUT_DIR)/cmbmain.o \
	$(OUTPUT_DIR)/camb.o

CAMBSO       =  $(DLL_DIR)/constants.o  $(DLL_DIR)/utils.o $(EXTCAMBFILES)  $(DLL_DIR)/subroutines.o  \
	$(DLL_DIR)/inifile.o  $(DLL_DIR)/$(POWERSPECTRUM).o  $(DLL_DIR)/$(RECOMBINATION).o \
	$(DLL_DIR)/$(REIONIZATION).o $(DLL_DIR)/modules.o $(DLL_DIR)/bessels.o $(DLL_DIR)/$(EQUATIONS).o \
	$(DLL_DIR)/$(NONLINEAR).o $(DLL_DIR)/lensing.o $(DLL_DIR)/$(BISPECTRUM).o $(DLL_DIR)/cmbmain.o \
	$(DLL_DIR)/camb.o $(DLL_DIR)/camb_python.o

F90CRLINK ?= -lstdc++

## CosmoRec
ifeq ($(RECOMBINATION),cosmorec)
COSMOREC_PATH ?=../CosmoRec/
GSL_LINK ?=-lgsl -lgslcblas
camb: libCosmoRec.a
$(CAMBLIB): libCosmoRec.a
F90CRLINK += -L$(COSMOREC_PATH) -lCosmoRec $(GSL_LINK)
endif


ifeq ($(RECOMBINATION),hyrec)
HYREC_PATH ?= ../HyRec/
camb: libhyrec.a
$(CAMBLIB): libhyrec.a
F90CRLINK += -L$(HYREC_PATH) -lhyrec
endif

default: camb

all: camb camblib.so libcamb

libcamb: $(CAMBLIB)


$(OUTPUT_DIR)/subroutines.o: $(OUTPUT_DIR)/constants.o $(OUTPUT_DIR)/utils.o
$(OUTPUT_DIR)/$(POWERSPECTRUM).o: $(OUTPUT_DIR)/subroutines.o  $(OUTPUT_DIR)/inifile.o
$(OUTPUT_DIR)/$(RECOMBINATION).o: $(OUTPUT_DIR)/subroutines.o $(OUTPUT_DIR)/inifile.o
$(OUTPUT_DIR)/$(REIONIZATION).o: $(OUTPUT_DIR)/constants.o $(OUTPUT_DIR)/inifile.o
$(OUTPUT_DIR)/modules.o: $(OUTPUT_DIR)/$(REIONIZATION).o $(OUTPUT_DIR)/$(POWERSPECTRUM).o $(OUTPUT_DIR)/$(RECOMBINATION).o
$(OUTPUT_DIR)/bessels.o: $(OUTPUT_DIR)/modules.o
$(OUTPUT_DIR)/$(EQUATIONS).o: $(OUTPUT_DIR)/bessels.o
$(OUTPUT_DIR)/$(NONLINEAR).o:  $(OUTPUT_DIR)/modules.o $(OUTPUT_DIR)/$(EQUATIONS).o
$(OUTPUT_DIR)/lensing.o: $(OUTPUT_DIR)/bessels.o
$(OUTPUT_DIR)/$(BISPECTRUM).o: $(OUTPUT_DIR)/lensing.o $(OUTPUT_DIR)/modules.o
$(OUTPUT_DIR)/cmbmain.o: $(OUTPUT_DIR)/lensing.o $(OUTPUT_DIR)/$(NONLINEAR).o $(OUTPUT_DIR)/$(EQUATIONS).o $(OUTPUT_DIR)/$(BISPECTRUM).o
$(OUTPUT_DIR)/camb.o: $(OUTPUT_DIR)/cmbmain.o
$(OUTPUT_DIR)/Matrix_utils.o: $(OUTPUT_DIR)/utils.o

$(DLL_DIR)/subroutines.o: $(DLL_DIR)/constants.o $(DLL_DIR)/utils.o
$(DLL_DIR)/$(POWERSPECTRUM).o: $(DLL_DIR)/subroutines.o  $(DLL_DIR)/inifile.o
$(DLL_DIR)/$(RECOMBINATION).o: $(DLL_DIR)/subroutines.o $(DLL_DIR)/inifile.o
$(DLL_DIR)/$(REIONIZATION).o: $(DLL_DIR)/constants.o $(DLL_DIR)/inifile.o
$(DLL_DIR)/modules.o: $(DLL_DIR)/$(REIONIZATION).o $(DLL_DIR)/$(POWERSPECTRUM).o $(DLL_DIR)/$(RECOMBINATION).o
$(DLL_DIR)/bessels.o: $(DLL_DIR)/modules.o
$(DLL_DIR)/$(EQUATIONS).o: $(DLL_DIR)/bessels.o
$(DLL_DIR)/$(NONLINEAR).o:  $(DLL_DIR)/modules.o $(DLL_DIR)/$(EQUATIONS).o
$(DLL_DIR)/lensing.o: $(DLL_DIR)/bessels.o
$(DLL_DIR)/$(BISPECTRUM).o: $(DLL_DIR)/lensing.o $(DLL_DIR)/modules.o
$(DLL_DIR)/cmbmain.o: $(DLL_DIR)/lensing.o $(DLL_DIR)/$(NONLINEAR).o $(DLL_DIR)/$(EQUATIONS).o $(DLL_DIR)/$(BISPECTRUM).o
$(DLL_DIR)/camb.o: $(DLL_DIR)/cmbmain.o
$(DLL_DIR)/Matrix_utils.o: $(DLL_DIR)/utils.o
$(DLL_DIR)/camb_python.o: $(DLL_DIR)/camb.o

camblib.so: folders $(CAMBSO)
	$(F90C) $(SF90FLAGS) $(CAMBSO) -o $(DLL_DIR)/camblib.so
	cp $(DLL_DIR)/camblib.so $(PYCAMB_OUTPUT_DIR)

camb: directories $(CAMBOBJ) $(DRIVER)
	$(F90C) $(F90FLAGS) $(CAMBOBJ) $(DRIVER) $(F90CRLINK) -o $@

$(CAMBLIB): directories $(CAMBOBJ)
	ar -r $@ $(CAMBOBJ)

camb_fits: directories writefits.f90 $(CAMBOBJ) $(DRIVER)
	$(F90C) $(F90FLAGS) -I$(HEALPIXDIR)/include $(CAMBOBJ) writefits.f90 $(DRIVER) $(HEALPIXLD) -DWRITE_FITS -o $@

$(DLL_DIR)/%.o: %.f90
	$(F90C) $(SF90FLAGS) -c $*.f90 -o $(DLL_DIR)/$*.o

$(DLL_DIR)/%.o: %.F90
	$(F90C) $(SF90FLAGS) -c $*.F90 -o $(DLL_DIR)/$*.o

$(OUTPUT_DIR)/%.o: %.f90
	$(F90C) $(F90FLAGS) -c $*.f90 -o $(OUTPUT_DIR)/$*.o

$(OUTPUT_DIR)/%.o: %.F90
	$(F90C) $(F90FLAGS) -c $*.F90 -o $(OUTPUT_DIR)/$*.o


folders:
	mkdir -p $(DLL_DIR)

directories:
	mkdir -p $(OUTPUT_DIR)


clean:
	rm -f *.o *.a *.d core *.mod $(DLL_DIR)/*.o $(DLL_DIR)/*.mod
	rm -f *.o *.a *.d core *.mod $(OUTPUT_DIR)/*.o $(OUTPUT_DIR)/*.mod $(PYCAMB_OUTPUT_DIR)/*.so
	rm -rf Release*
	rm -rf Debug*

## CosmoRec make parts
cleanCR:
	cd $(COSMOREC_PATH); make tidy;

libCosmoRec.a:
	cd $(COSMOREC_PATH); make lib;


libhyrec.a:
	cd $(HYREC_PATH); make libhyrec.a;


