################################################################################
#
# This makefile creates the "saxs" executables of the saxs package.
#
# The string defined in the PVERSION macros will be passed on to the 
# compiler and can be used by the programs to create a version identifier.
#
# This Makefile can create the library for HP-UX, SunOS, LINUX, MAC and the 
# CYGNUS user environment on Window-PCs (CYGWIN). The versions for the 
# different operating systems are stored in different subdirectories. 
# For details, see below.
#
# Possible targets of this Makefile are:
#
# - all          (default) to make the library
# - clean_run    to remove all executables created by the Makefile 
# - clean_lib    to remove all libraries and objects created by the Makefile
# - clean_obj    to remove all object files created by the Makefile
# - clean        to remove everything that was created by the Makefile
#
# Each target will create or remove files only for the operating system it
# is being run with, e.g. doing "make clean" on a SUN will not remove any
# files that are in the subdirectories for HP-UX.
#
# MAKEFILE FLAGS:
#   H5FILES=1|0   # H5File support yes/no (default H5FILES=0)
#   IOALLOC=1|0   # alternative allocation routines yes/no (default IOALLOC=0)
#   LIBLZ4=1|0    # lz4 filter library (bitshuffle, lzf, lz4) yes/no (default LIBLZ4=0)
#
# Update: 2007-02-14 P. Boesecke (boesecke@esrf.fr)
#                    (original makefile from R. Wilcke (wilcke@esrf.fr))
#                    first working version.
#         2009-11    P. Boesecke (boesecke@esrf.fr), R. Wilcke ((wilcke@esrf.fr)
#                    Apple Darwin (MAC) added, gmake -> make
#         2016-03    P. Boesecke
#                    Wildcard changed to *.[0-9][0-9][0-9]*
#         2017-02    P. Boesecke (boesecke@esrf.fr)
#                    'export H5FILES=1' includes all h5*.[ch] files in the make,
#                    to undo use 'unset H5FILES' or 'export H5FILES=0'.
#                    The h5 include files and libraries are expected in
#                    ../hdf5/<DIRNAM>/hdf5/include
#                    ../hdf5/<DIRNAM>/hdf5/lib
#                    Already compiled or archived h5 objects will not be removed
#                    after unsetting H5FILES. For doing that the objects and
#                    library must be deleted and recompiled.
#                    If the edfpack library has been created without H5FILES=1
#                    h5 files will not be automatically inluded when setting
#                    H5FILES=1. The library must be deleted and recreated.
#         2017-05    P. Boesecke (boesecke@esrf.fr)
#                    IOALLOC=1 uses specific allocation routines
#         2017-09-08 P. Boesecke (boesecke@esrf.fr)
#                    -ldl option required for static linking with hdf5-1.8.19
#         2017-10-02 P. Boesecke (boesecke@esrf.fr)
#                    'export LIBLZ4=1' makes and links with liblz4
################################################################################

################################################################################

CC = gcc
LD = gcc 
AR = ar ru
RANLIB = ranlib
MAKE = make

#
# The PVERSION string defined here will be passed  on to the compiler with 
# the "-D" option.
# The backslashes and quotes (\") are necessary to pass it as a string.
#
PVERSION := $(wildcard src/P*)

#CFLAGS := -g -O -DPVERSION=\"$(PVERSION)\" -Wno-sign-compare -Wno-parentheses -Wno-misleading-indentation
CFLAGS := -g -O -DPVERSION=\"$(PVERSION)\" -Wno-sign-compare -Wno-parentheses

#
# Find out the operating system, and define the names of the directories
# for the object files, libraries and executables accordingly:
# - the object files will be in   obj/$(DIRNAM)
# - the libraries will be in      lib/$(DIRNAM)
# - the executables will be in    bin/$(DIRNAM)
#
# where $(DIRNAM) is
# - HPUX     on HP-UX systems
# - SUN      on SunOS systems
# - LINUX    on 32-bit LINUX systems
# - LINUX64  on 64-bit LINUX systems
# - CYGWIN on PCs with the 32-bit Cygnus user enviromnent
# - CYGWIN64 on PCs with the 64-bit Cygnus user enviromnent
#

OPSYS := $(shell uname)

ifeq ($(OPSYS),Darwin)

PVERSION := $(PVERSION)_mac
DIRNAM = MAC
CFLAGS += -m32
LFLAGS := -m32

else
ifeq ($(OPSYS),HP-UX)

PVERSION := $(PVERSION)_hpux10-20
DIRNAM = HPUX

else
ifeq ($(OPSYS),SunOS)

PVERSION := $(PVERSION)_sunos5-7
DIRNAM = SUN
CFLAGS += -DUNDERSCORE

else
ifeq ($(OPSYS),Linux)

ifeq ($(shell uname -m),x86_64)
DIRNAM = LINUX64
PVERSION := $(PVERSION)_linux64
else
PVERSION := $(PVERSION)_linux
DIRNAM = LINUX
endif
CFLAGS += -DUNDERSCORE
LFLAGS = -static
MAKE = make

else

ifeq ($(findstring CYGWIN,$(OPSYS)),CYGWIN)

ifeq ($(shell uname -m),x86_64)
DIRNAM = CYGWIN64
CFLAGS += -DUNDERSCORE
PVERSION := $(PVERSION)_cygwin64
else
DIRNAM = CYGWIN
CFLAGS += -DUNDERSCORE
PVERSION := $(PVERSION)_cygwin
endif
MAKE = make

else
PVERSION := $(PVERSION)_undefined
endif      # Cygwin
endif      # Linux
endif      # SunOS
endif      # HP-UX
endif      # Darwin

CFLAGS += -c -Isaxspack -Irocapack -Iedfpack

ifeq ($(IOALLOC),1)
  CFLAGS += -DIOALLOC=1
endif # IOALLOC

ifeq ($(LIBLZ4),1)
  CFLAGS += -DLIBLZ4=1
endif # IOALLOC

#
#
# Determine the source file names and the corresponding object file names for
# "saxs".
#
SAXS_OBJECTS := $(patsubst %.c, %.o, $(notdir $(shell echo src/*.c)))
SAXS_OBJ_DIR = src/bin/$(DIRNAM)
SAXS_OBJ_FILES = $(addprefix $(SAXS_OBJ_DIR)/, $(SAXS_OBJECTS))
SAXS_SRC_FILES = $(shell echo src/*.[ch])
SAXS_INC_FILES := $(shell echo edfpack/*.h)
SAXS_INC_FILES += $(shell echo rocapack/*.h)
SAXS_INC_FILES += $(shell echo saxspack/*.h)

# Define the name for the "rocapack" library.
#
ROCAP_DIR = rocapack/lib/$(DIRNAM)
ROCAP_LIB = $(addprefix $(ROCAP_DIR)/, librocapack.a)
LFLAGS += -L$(ROCAP_DIR) -lrocapack

#
# Define the name for the "saxspack" library.
#
SAXSP_DIR = saxspack/lib/$(DIRNAM)
SAXSP_LIB = $(addprefix $(SAXSP_DIR)/, libsaxspack.a)
LFLAGS += -L$(SAXSP_DIR) -lsaxspack

#
# Define the name for the "edfpack" library.
#
EDFP_DIR = edfpack/lib/$(DIRNAM)
EDFP_LIB = $(addprefix $(EDFP_DIR)/, libedfpack.a)
LFLAGS += -L$(EDFP_DIR) -ledfpack

ifeq ($(H5FILES),1)
H5LIB_DIR := ../hdf5/$(DIRNAM)/hdf5/lib
LFLAGS += -L$(H5LIB_DIR) $(H5LIB_DIR)/libhdf5.a -ldl
#LFLAGS += -L$(H5LIB_DIR) $(H5LIB_DIR)/libhdf5.a

endif

#
# Include libz4 for data compression
#
ifeq ($(LIBLZ4),1)
  LZ4LIB_DIR=filters/lib/$(DIRNAM)
  LZ4LIB=$(LZ4LIB_DIR)/liblz4.a
  LFLAGS += -L$(LZ4LIB_DIR) $(LZ4LIB)
else
  LZ4LIB_DIR=""
endif # IOALLOC

#
# Include zlib for data compression
#
LFLAGS += -lz

#
# Include mathlib as last library
#
LFLAGS += -lm

#
# Define the name of the runtime directory, where the executables are stored.
#
# The name is "bin/$(DIRNAM)", where DIRNAM has the same value as explained
# above.
#
RUN_DIR = bin/$(DIRNAM)

SAXS_RUN_FILES :=$(addprefix $(RUN_DIR)/, $(SAXS_OBJECTS))
SAXS_RUN_FILES :=$(SAXS_RUN_FILES:%.o=%.exe)

# In CYGWIN it is no longer necessary and even not allowed to append the
# suffix .exe to each file in SAXS_RUN_FILES, remove it always
SAXS_RUN_FILES := $(basename $(SAXS_RUN_FILES))

# List SAXS_RUN_FILES
#$(info $(SAXS_RUN_FILES))

#
# Make the "saxs" executables. This is the default.
# ?([w]) matches w or nothing
#
all:	$(RUN_DIR) $(SAXS_OBJ_DIR) $(SAXS_RUN_FILES)
	cp -f edfpack/E*.[0-9][0-9][0-9]* $(RUN_DIR)
	cp -f rocapack/R*.[0-9][0-9][0-9]* $(RUN_DIR)
	cp -f saxspack/V*.[0-9][0-9][0-9]* $(RUN_DIR)
	cp -f src/P*.[0-9][0-9][0-9]* $(RUN_DIR)

$(RUN_DIR)/%: src/%.c $(SAXS_OBJ_DIR)/%.o $(EDFP_LIB) $(SAXSP_LIB) $(ROCAP_LIB) $(LZ4LIB)
	$(LD) -o $@ $(SAXS_OBJ_DIR)/$(notdir $@).o $(LFLAGS)

#
# Make the runtime file directory if it does not yet exist.
#
$(RUN_DIR):
	mkdir -p $(RUN_DIR)

#
# Make the object file directory if it does not yet exist.
#
$(SAXS_OBJ_DIR):
	mkdir -p $(SAXS_OBJ_DIR)

#
# Make the required object files for "saxs".
#
$(SAXS_OBJ_FILES): $(SAXS_OBJ_DIR)/%.o: src/%.c $(SAXS_INC_FILES)
	$(CC) $(CFLAGS) $< -o $@

#
# Make the "edfpack" library by calling the corresponding Makefile.
#
$(EDFP_LIB):
	(cd edfpack; $(MAKE) all)

# Make the "rocapack" library by calling the corresponding Makefile.
#
$(ROCAP_LIB):
	(cd rocapack; $(MAKE) all)

$(LZ4LIB):
	(cd filters; $(MAKE) all)
#
# Make the "saxspack" library by calling the corresponding Makefile.
#
$(SAXSP_LIB):
	(cd saxspack; $(MAKE) all)

#
#
# Clean up all files that can be made by "make". Several variations exist:
# - "clean_run" cleans all executables
# - "clean_obj" cleans all object files (including the
#               common files and the corresponding libraries)
# - "clean"     cleans all the files created by the Makefile (including the
#               common files, the corresponding libraries and the 
#               executables).
# 
clean_run: 
	rm -rf $(RUN_DIR)

ifeq ($(LIBLZ4),1)
clean_obj: 
	rm -rf $(SAXS_OBJ_DIR)
	(cd edfpack; $(MAKE) clean_obj)
	(cd rocapack; $(MAKE) clean_obj)
	(cd saxspack; $(MAKE) clean_obj)
else
clean_obj: 
	rm -rf $(SAXS_OBJ_DIR)
	(cd edfpack; $(MAKE) clean_obj)
	(cd rocapack; $(MAKE) clean_obj)
	(cd saxspack; $(MAKE) clean_obj)
	(cd filters; $(MAKE) clean_obj)
endif

ifeq ($(LIBLZ4),1)
clean_lib:
	rm -rf $(SAXS_OBJ_DIR)
	(cd edfpack; $(MAKE) clean)
	(cd rocapack; $(MAKE) clean)
	(cd saxspack; $(MAKE) clean)
	(cd filters; $(MAKE) clean)
else
clean_lib:
	rm -rf $(SAXS_OBJ_DIR)
	(cd edfpack; $(MAKE) clean)
	(cd rocapack; $(MAKE) clean)
	(cd saxspack; $(MAKE) clean)
endif

ifeq ($(LIBLZ4),1)
clean: 
	rm -rf $(RUN_DIR)
	rm -rf $(SAXS_OBJ_DIR)
	(cd edfpack; $(MAKE) clean)
	(cd rocapack; $(MAKE) clean)
	(cd saxspack; $(MAKE) clean)
	(cd filters; $(MAKE) clean)
else
clean: 
	rm -rf $(RUN_DIR)
	rm -rf $(SAXS_OBJ_DIR)
	(cd edfpack; $(MAKE) clean)
	(cd rocapack; $(MAKE) clean)
	(cd saxspack; $(MAKE) clean)
endif
