#############################################################################
# build environment

# version and build configuration

# uncomment and optionally define on command line
# to override value defined in source, e.g.
#   MF_VER=1.0.1 make
lib_ver ?=0.0.1
lib_build=`date +%Y/%m/%dT%H:%M:%S%z`
OPT_LIB_VER=-DLIB_VERSION=$(lib_ver)
OPT_LIB_BUILD=-DLIB_BUILD=$(lib_build)
BUILD_OPTS=

# user symbols
# C standard e.g. -std=c99 -std=gnu99
# may be needed for Cygwin (e.g. for loop declare/init)
# not currently C89 compatible
STD= #-std=c99 -std=gnu99 -std=c89
OPTIONS= $(STD) -D_GNU_SOURCE $(BUILD_OPTS) $(OPT_LIB_VER) $(OPT_LIB_BUILD)

# dependency paths

# build directories
OUTPUT_DIR=../bin
BUILD_DIR=../build

# compilation
CXX = gcc
AR = ar
#CXX = i686-w64-mingw32-gcc
#AR = i686-w64-mingw32-ar

# compile and link with -pg for profiling support
# then do gprof <application> gmon.out for profile output to console
GPROF= #-pg # for gprofile support
CFLAGS = -g -O2 -Wall $(GPROF) -Wno-deprecated -Wsign-compare $(OPTIONS) 
LD_FLAGS = $(GPROF) -g -lm
MPLAB_PATHS = #-I../src
INC_PATHS =  -I. -I../src $(MPLAB_PATHS)
LIB_PATHS = -L$(OUTPUT_DIR)

#############################################################################
# target definitions

# libz85 : z85 codec lib
LIBZ85=libz85.a
LIBZ85_SRC=../src/z85.c
LIBZ85_OBJ=$(LIBZ85_SRC:%.c=$(BUILD_DIR)/%.o)
LIBZ85_LIBS =

LIBLUTILS=liblutils.a
LIBLUTILS_SRC=../src/lutil_api.c ../src/lutil_impl.c ../src/iowfile.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LIBLUTILS_OBJ=$(LIBLUTILS_SRC:%.c=$(BUILD_DIR)/%.o)
LIBLUTILS_LIBS =

# liblogutilsdll : licor log utils lib
LIBLUTILSDLL=liblutils.dll
LIBLUTILSDLL_SRC=../src/lutil_api.c ../src/lutil_impl.c ../src/iowfile.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LIBLUTILSDLL_OBJ=$(LIBLUTILSDLL_SRC:%.c=$(BUILD_DIR)/%.o)
LIBLUTILSDLL_LIBS = -lz85

# libiowser : serial IO wrapper lib
LIBIOWSER=libiowser.a
LIBIOWSER_SRC=iowserial.c
LIBIOWSER_OBJ=$(LIBIOWSER_SRC:%.c=$(BUILD_DIR)/%.o)
LIBIOWSER_LIBS =

# libiowserso : serial IO wrapper lib
LIBIOWSERSO=libiowser.so
LIBIOWSERSO_SRC=iowserial.c
LIBIOWSERSO_OBJ=$(LIBIOWSERSO_SRC:%.c=$(BUILD_DIR)/%.o)
LIBIOWSERSO_LIBS =

# libiowserdll : serial IO wrapper lib
LIBIOWSERDLL=libiowser.dll
LIBIOWSERDLL_SRC=iowserial.c
LIBIOWSERDLL_OBJ=$(LIBIOWSERDLL_SRC:%.c=$(BUILD_DIR)/%.o)
LIBIOWSERDLL_LIBS =

# logout : log output utility
LOGOUT=lout
LOGOUT_SRC=lout.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LOGOUT_OBJ=$(LOGOUT_SRC:%.c=$(BUILD_DIR)/%.o)
LOGOUT_LIBS = -lz85 -llutils

# linspect : log info utility
LINSPECT=linspect
LINSPECT_SRC=linspect.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LINSPECT_OBJ=$(LINSPECT_SRC:%.c=$(BUILD_DIR)/%.o)
LINSPECT_LIBS = -lz85 -llutils

# lcat : log record show utility
LCAT=lcat
LCAT_SRC=lcat.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LCAT_OBJ=$(LCAT_SRC:%.c=$(BUILD_DIR)/%.o)
LCAT_LIBS = -lz85 -llutils

# lless : log record pager utility
LLESS=lless
LLESS_SRC=lless.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LLESS_OBJ=$(LLESS_SRC:%.c=$(BUILD_DIR)/%.o)
LLESS_LIBS = -lz85 -llutils

# ldqueue : log download queue utility
LDQUEUE=ldq
LDQUEUE_SRC=ldqueue.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LDQUEUE_OBJ=$(LDQUEUE_SRC:%.c=$(BUILD_DIR)/%.o)
LDQUEUE_LIBS = -lz85 -llutils

# lgen : log generator utility
LGEN=lgen
LGEN_SRC=lgen.c ../src/licor8xx-shared.c ../src/cwg-shared.c
LGEN_OBJ=$(LGEN_SRC:%.c=$(BUILD_DIR)/%.o)
LGEN_LIBS = -lz85 -llutils

# getlog : log download utility
GLOG=getlog
GLOG_SRC=getlog.c ../src/cwg-shared.c
GLOG_OBJ=$(GLOG_SRC:%.c=$(BUILD_DIR)/%.o)
GLOG_LIBS = -lz85 -llutils

# RAW2X : raw licor transform utility
RAW2X=raw2x
RAW2X_SRC=raw2x.c  ../src/cwg-shared.c
RAW2X_OBJ=$(RAW2X_SRC:%.c=$(BUILD_DIR)/%.o)
RAW2X_LIBS = -lz85 -llutils

# XCAT : file cat utility
XCAT=xcat
XCAT_SRC=xcat.c   ../src/fileutils.c ../src/cwg-shared.c
XCAT_OBJ=$(XCAT_SRC:%.c=$(BUILD_DIR)/%.o)
XCAT_LIBS = -lz85 -llutils

# ttest : time test utility
TTEST=ttest
TTEST_SRC=ttest.c ../src/cwg-shared.c ../src/iowfile.c ../src/fileutils.c
TTEST_OBJ=$(TTEST_SRC:%.c=$(BUILD_DIR)/%.o)
TTEST_LIBS =

# futil : file util test utility
FUTIL=futil
FUTIL_SRC=futil.c ../src/cwg-shared.c ../src/iowfile.c ../src/fileutils.c
FUTIL_OBJ=$(FUTIL_SRC:%.c=$(BUILD_DIR)/%.o)
FUTIL_LIBS =

# b85fmt : base85 record viewer
B85FMT=b85fmt
B85FMT_SRC=b85fmt.c #../src/cwg-shared.c
B85FMT_OBJ=$(B85FMT_SRC:%.c=$(BUILD_DIR)/%.o)
B85FMT_LIBS = -lz85 -llutils

# cwglib : client API library
LIBCWG=libcwg.a
LIBCWG_SRC=cwglib.c
LIBCWG_OBJ=$(LIBCWG_SRC:%.c=$(BUILD_DIR)/%.o)
LIBCWG_LIBS = -llutils -liowser

LIBCWGSO=libcwg.so
LIBCWGSO_SRC=cwglib.c
LIBCWGSO_OBJ=$(LIBCWGSO_SRC:%.c=$(BUILD_DIR)/%.o)
LIBCWGSO_LIBS = -llutils -liowser

LIBCWGDLL=libcwg.dll
LIBCWGDLL_SRC=cwglib.c
LIBCWGDLL_OBJ=$(LIBCWGDLL_SRC:%.c=$(BUILD_DIR)/%.o)
LIBCWGDLL_LIBS = -llutils -liowser


# cwgcli : client test utility
CWGTEST=cwg-test
CWGTEST_SRC=cwglib-test.c  ../src/cwg-shared.c
CWGTEST_OBJ=$(CWGTEST_SRC:%.c=$(BUILD_DIR)/%.o)
CWGTEST_LIBS = -lcwg -lz85 -llutils -liowser

# doxyen: Doxygen documentation

#############################################################################
# build files (mostly for cleanup)
SOURCES = \
	$(LIBZ85_SRC) \
	$(LIBLUTILS_SRC) \
	$(LINSPECT_SRC) \
	$(LCAT_SRC) \
	$(LLESS_SRC) \
	$(LDQUEUE_SRC) \
    $(LOGOUT_SRC) \
	$(LGEN_SRC) $(GLOG_SRC) $(RAW2X_SRC) $(TTEST_SRC)  $(FUTIL_SRC) \
    $(XCAT_SRC) $(LIBCWG_SRC) $(LIBCWGSO_SRC) $(LIBIOWSER_SRC) $(LIBIOWSERSO_SRC) \
    $(B85FMT_SRC) \
	$(CWGTEST_SRC)
# $(LIBLUTILSDLL_SRC)  $(LIBIOWSERDLL_SRC)  $(LIBCWGDLL_SRC)

OBJECTS = $(SOURCES:%.c=$(BUILD_DIR)/%.o) \
	$(OUTPUT_DIR)/$(LIBZ85) \
	$(OUTPUT_DIR)/$(LIBLUTILS) \
	$(LLESS_OBJ) \
	$(LINSPECT_OBJ) \
	$(LCAT_OBJ) \
	$(LDQUEUE_OBJ) \
	$(OUTPUT_DIR)/$(LIBIOWSER) \
	$(OUTPUT_DIR)/$(LIBIOWSERSO)  \
	$(OUTPUT_DIR)/$(LIBCWG) $(OUTPUT_DIR)/$(LIBCWGSO) \
    $(B85FMT_OBJ) \
# $(OUTPUT_DIR)/$(LIBLUTILSDLL) $(OUTPUT_DIR)/$(LIBIOWSERDLL) $(OUTPUT_DIR)/$(LIBCWGDLL)

DEPENDS = $(SOURCES:%.c=$(BUILD_DIR)/%.d)

BINARIES = $(OUTPUT_DIR)/$(LINSPECT) \
	$(OUTPUT_DIR)/$(LCAT) \
	$(OUTPUT_DIR)/$(LLESS) \
	$(OUTPUT_DIR)/$(LDQUEUE) \
	$(OUTPUT_DIR)/$(LOGOUT) \
	$(OUTPUT_DIR)/$(LGEN) $(OUTPUT_DIR)/$(GLOG) \
	$(OUTPUT_DIR)/$(RAW2X) $(OUTPUT_DIR)/$(XCAT) $(OUTPUT_DIR)/$(TTEST) $(OUTPUT_DIR)/$(FUTIL) $(OUTPUT_DIR)/$(CWGTEST) $(OUTPUT_DIR)/$(B85FMT)

DSYMS   = $(BINARIES:%=%.dSYM)
CLEANUP = gmon.out

#############################################################################
# rules: build targets

all: $(OBJECTS) \
	$(OUTPUT_DIR)/$(LINSPECT) \
	$(OUTPUT_DIR)/$(LCAT) \
	$(OUTPUT_DIR)/$(LLESS) \
	$(OUTPUT_DIR)/$(LDQUEUE) \
	$(OUTPUT_DIR)/$(LOGOUT) \
	$(OUTPUT_DIR)/$(LGEN) $(OUTPUT_DIR)/$(GLOG) $(OUTPUT_DIR)/$(RAW2X) \
	$(OUTPUT_DIR)/$(TTEST) $(OUTPUT_DIR)/$(FUTIL) $(OUTPUT_DIR)/$(XCAT) \
	$(OUTPUT_DIR)/$(CWGTEST) \
	$(OUTPUT_DIR)/$(B85FMT)

# build z85 library
$(OUTPUT_DIR)/$(LIBZ85): $(LIBZ85_OBJ)
	@echo building $@...
	$(AR) -r $@ $(LIBZ85_OBJ)

# build logutils library
$(OUTPUT_DIR)/$(LIBLUTILS): $(LIBLUTILS_OBJ)
	@echo building $@...
	$(AR) -r $@ $(LIBLUTILS_OBJ)

$(OUTPUT_DIR)/$(LIBLUTILSDLL): $(LIBLUTILSDLL_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) -shared -fpic $(LIB_PATHS) $^ -o $@ $(LIBLUTILSDLL_LIBS) $(LD_FLAGS)
	@echo

# build linspect utility
$(OUTPUT_DIR)/$(LINSPECT): $(LINSPECT_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(LINSPECT_LIBS) $(LD_FLAGS)
	@echo

# build lcat utility
$(OUTPUT_DIR)/$(LCAT): $(LCAT_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(LCAT_LIBS) $(LD_FLAGS)
	@echo

# build lless utility
$(OUTPUT_DIR)/$(LLESS): $(LLESS_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS)
	@echo building $@...
	@echo SOURCES $(SOURCES)
	@echo OBJECTS $(OBJECTS)
	@echo
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(LLESS_LIBS) $(LD_FLAGS)
	@echo

# build ldqueue utility
$(OUTPUT_DIR)/$(LDQUEUE): $(LDQUEUE_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(LDQUEUE_LIBS) $(LD_FLAGS)
	@echo

# build lgen utility
$(OUTPUT_DIR)/$(LGEN): $(LGEN_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(LGEN_LIBS) $(LD_FLAGS)
	@echo

# build lout utility
$(OUTPUT_DIR)/$(LOGOUT): $(LOGOUT_OBJ) $(OUTPUT_DIR)/$(LIBZ85)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(LOGOUT_LIBS) $(LD_FLAGS)
	@echo

# build getlog utility
$(OUTPUT_DIR)/$(GLOG): $(GLOG_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS) $(OUTPUT_DIR)/$(LIBZ85)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(GLOG_CFLAGS) $(LIB_PATHS) $^ -o $@ $(GLOG_LIBS) $(LD_FLAGS)
	@echo

# build rawxform utility
$(OUTPUT_DIR)/$(RAW2X): $(RAW2X_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS) $(OUTPUT_DIR)/$(LIBZ85)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(RAW2X_CFLAGS) $(LIB_PATHS) $^ -o $@ $(RAW2X_LIBS) $(LD_FLAGS)
	@echo

# build xcat utility
$(OUTPUT_DIR)/$(XCAT): $(XCAT_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS) $(OUTPUT_DIR)/$(LIBZ85)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(XCAT_CFLAGS) $(LIB_PATHS) $^ -o $@ $(XCAT_LIBS) $(LD_FLAGS)
	@echo

# build ttest utility
$(OUTPUT_DIR)/$(TTEST): $(TTEST_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(TTEST_LIBS) $(LD_FLAGS)
	@echo

# build futil utility
$(OUTPUT_DIR)/$(FUTIL): $(FUTIL_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(FUTIL_LIBS) $(LD_FLAGS)
	@echo

# build b85fmt utility
$(OUTPUT_DIR)/$(B85FMT): $(B85FMT_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(LIB_PATHS) $^ -o $@ $(B85FMT_LIBS) $(LD_FLAGS)
	@echo

# build iowserial library
$(OUTPUT_DIR)/$(LIBIOWSER): $(LIBIOWSER_OBJ)
	@echo building $@...
	$(AR) -r $@ $(LIBIOWSER_OBJ)

$(OUTPUT_DIR)/$(LIBIOWSERSO): $(LIBIOWSERSO_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) -shared -fpic $(LIB_PATHS) $^ -o $@ $(LIBIOWSERSO_LIBS) $(LD_FLAGS)

$(OUTPUT_DIR)/$(LIBIOWSERDLL): $(LIBIOWSERDLL_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) -shared -fpic $(LIB_PATHS) $^ -o $@ $(LIBIOWSERDLL_LIBS) $(LD_FLAGS)

# build cwg client library
$(OUTPUT_DIR)/$(LIBCWG): $(LIBCWG_OBJ)
	@echo building $@...
	ar -r $@ $(LIBCWG_OBJ)

$(OUTPUT_DIR)/$(LIBCWGSO): $(LIBCWGSO_OBJ) $(OUTPUT_DIR)/$(LIBLUTILS)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) -shared -fpic $(LIB_PATHS) $^ -o $@ $(LIBCWGSO_LIBS) $(LD_FLAGS)

$(OUTPUT_DIR)/$(LIBCWGDLL): $(LIBCWGDLL_OBJ) $(OUTPUT_DIR)/$(LIBLUTILSDLL)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) -shared -fpic $(LIB_PATHS) $^ -o $@ $(LIBCWGDLL_LIBS) $(LD_FLAGS)

# build cwg-test utility
$(OUTPUT_DIR)/$(CWGTEST): $(CWGTEST_OBJ) $(OUTPUT_DIR)/$(LIBCWG)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(OPTIONS) $(CWGTEST_CFLAGS) $(LIB_PATHS) $^ -o $@ $(CWGTEST_LIBS) $(LD_FLAGS)
	@echo

# uncomment to enable/disable dependency generation
#include $(DEPENDS)
-include $(DEPENDS)

# rule: build object files from source files
$(BUILD_DIR)/%.o :%.c
	@echo compiling $<...
	$(CXX) $(CFLAGS) $(INC_PATHS) -c $< -o $@
	@echo

# rule: build dependency files from source files
$(BUILD_DIR)/%.d :%.c
	@[ -d $(BUILD_DIR) ] || mkdir -p $(BUILD_DIR)
	@[ -d $(OUTPUT_DIR) ] || mkdir -p $(OUTPUT_DIR)
	@echo generating dependency file for $<
	@set -e; $(CXX) -MM $(CFLAGS) $(INC_PATHS) $< \
	| awk '/o:/ {printf "%s", "$@ $(BUILD_DIR)/"} {print}' > $@; \
	[ -s $@ ] || rm -f $@
	@echo

install:
	@echo "Installing...(not implemented)"

###########################################################################
# rules:

.PHONY: clean

# clean : delete object, dependency, binary files
clean:
	@echo Removing Objects
	rm -f $(OBJECTS)
	@echo
	@echo Removing Objects
	rm -f $(DEPENDS)
	@echo
	@echo Removing Objects
	rm -f $(BINARIES)
	@echo
	@echo Removing DSYMS
	rm -rf $(DSYMS)

.PHONY: purge

# purge : delete delete object, dependency, binary files, build directories
purge:
	rm -f $(BINARIES) $(OBJECTS) $(DEPENDS) $(DSYMS) $(CLEANUP)
	rm -rf $(OUTPUT_DIR) $(BUILD_DIR)

# include the dependencies
ifneq ($(MAKECMDGOALS),purge)
ifneq ($(MAKECMDGOALS),clean)
#	-include $(DEPENDS)
endif
endif

