########################################
# Build Environment
# version and build configuration

# uncomment and optionally define on command line
# to override value defined in source, e.g.
#   trn_ver=1.0.1 make
idt_ver ?=0.0.1
idt_build=`date +%Y/%m/%dT%H:%M:%S%z`
OPT_IDT_VER=-DLIBIDT_VERSION=$(idt_ver)
OPT_IDT_BUILD=-DLIBIDT_BUILD=$(idt_build)

# C standard e.g. -std=c99 -std=gnu99
# may be needed for Cygwin (e.g. for loop declare/init)
#STD= -std=c99

# Platform-specific options
ifeq ($(shell uname),Linux)
OS_CFLAGS=
OS_INC_PATH=-I/opt/local/include
OS_LIB_PATH=-L/opt/local/lib
OS_LIBS=-lrt
endif

ifeq ($(shell uname),Darwin)
OS_CFLAGS=
OS_INC_PATH=-I/opt/local/include
OS_LIB_PATH=-L/opt/local/lib
OS_LIBS=
endif

ifeq ($(shell uname),Cygwin)
OS_CFLAGS=
OS_INC_PATH=-I/opt/local/include
OS_LIB_PATH=-L/opt/local/lib
OS_LIBS=-lrt
endif

# Build options
BUILD_OPTIONS = $(STD) -D_GNU_SOURCE  $(OPT_IDT_VER) $(OPT_IDT_BUILD)

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

# utils
INIPARSER_INC_PATH = -I../utils/iniparser/src
OAHU_UTILS_INC_PATH = -I../utils $(INIPARSER_INC_PATH)

# QNX utils
QNX_UTILS_INC_PATH = -I../qnx-utils

# Compilation Options
CXX = g++ #gcc
CC  = gcc
AR = ar
# compile and link with -pg for profiling support
# then do gprof <application> gmon.out for profile output to console
#GPROF= -pg
# use -Wall unless you know what you're doing
WARN_FLAGS=-Wall

# Compiler flags
CFLAGS = -g -O2 -c $(WARN_FLAGS) $(GPROF) $(BUILD_OPTIONS) $(OS_CFLAGS)
INC_PATHS =  -I. -I/usr/include $(OS_INC_PATH) $(QNX_UTILS_INC_PATH) $(OAHU_UTILS_INC_PATH)

# Linker flags
LD_FLAGS = -g $(GPROF)
LIB_PATHS = -L/usr/local/lib -L$(OUTPUT_DIR) $(OS_LIB_PATH)

########################################
# Target Definitions

LIBIDT=libidt83p.a
LIBIDT_SRC = Idt83pParser.c
LIBIDT_OBJ=$(LIBIDT_SRC:%.c=$(BUILD_DIR)/%.o)
#LIBIDT_LIBS = -lstd++
LIBIDT_LIBS =

DELTAT_LIB = libdeltat.a
DELTAT_SRC = DeltaT.cc DeltaTLog.cc
DELTAT_OBJ = $(DELTAT_SRC:%.cc=$(BUILD_DIR)/%.o)

DELTATTEST = deltaTTest
DELTATTEST_SRC = deltaTTest.cc
DELTATTEST_OBJ = $(DELTATTEST_SRC:%.cc=$(BUILD_DIR)/%.o)
DELTATTEST_LIBS = -lm -lidt83p -loautils -lqnx -liniparser

TESTIDT = testIdt
TESTIDT_SRC = testIdt.cc
TESTIDT_OBJ = $(TESTIDT_SRC:%.cc=$(BUILD_DIR)/%.o)
TESTIDT_LIBS = -lm -lidt83p

USE_LCM = 1
ifeq (1,$(USE_LCM))
CFLAGS += -DUSE_LCM
INC_PATHS += -I../../lrauv-lcmtypes/include
DELTAT_SRC += LcmDeltaT.cc
DELTATTEST_LIBS += -llcm
endif

########################################
# Build Files (mostly for cleanup)
SOURCES = $(LIBIDT_SRC) $(TESTIDT_SRC) $(DELTAT_SRC)
OBJECTS = $(TESTIDT_OBJ) $(LIBIDT_OBJ) $(DELTAT_OBJ)
#DEPENDS = $(BUILD_DIR)/*.d
DEPENDS = $(LIBIDT_SRC:%.c=$(BUILD_DIR)/%.d) \
		$(TESTIDT_SRC:%.cc=$(BUILD_DIR)/%.d) \
		$(DELTAT_SRC:%.cc=$(BUILD_DIR)/%.d) \
		$(DELTATTEST_SRC:%.cc=$(BUILD_DIR)/%.d)
BINARIES = $(OUTPUT_DIR)/$(LIBIDT) $(OUTPUT_DIR)/$(DELTAT_LIB) \
		$(OUTPUT_DIR)/$(TESTIDT) \
		$(OUTPUT_DIR)/$(DELTATTEST)
CLEANUP = gmon.out
# dSYMs : XCode debug symbol file folders
#DSYMS   = $(BINARIES:%=%.dSYM)
#RM_DSYMS = rm -rf $(DSYMS)

########################################
# Rules: build targets

all: $(BINARIES)

# build libidt83p library
$(OUTPUT_DIR)/$(LIBIDT): $(LIBIDT_OBJ)
	@echo building $@...
	$(AR) rcs $@ $(LIBIDT_OBJ)
	ranlib $@

-include $(DEPENDS)

# build testIdt utility
$(OUTPUT_DIR)/$(TESTIDT): $(TESTIDT_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(LIB_PATHS) $^ -o $@ $(LD_FLAGS) $(TESTIDT_LIBS)
	@echo

# build libdeltat library
$(OUTPUT_DIR)/$(DELTAT_LIB): $(DELTAT_OBJ)
	@echo building $@...
	$(AR) rcs $@ $(DELTAT_OBJ)
	ranlib $@

# build deltaTTest utility
$(OUTPUT_DIR)/$(DELTATTEST): $(DELTATTEST_OBJ) $(DELTAT_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(LIB_PATHS) $^ -o $@ $(LD_FLAGS) $(DELTATTEST_LIBS)
	@echo

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

$(BUILD_DIR)/%.o :%.cc
	@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; $(CC) -MM $(CFLAGS) $(INC_PATHS) $< \
	| awk '/o:/ {printf "%s", "$@ $(BUILD_DIR)/"} {print}' > $@; \
	[ -s $@ ] || rm -f $@
	@echo

$(BUILD_DIR)/%.d :%.cc
	@[ -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
.PHONY: purge

# clean : delete object, dependency, binary files
clean:
	rm -f $(OBJECTS) $(BINARIES) $(DEPENDS)
#	$(RM_DSYMS)

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

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