########################################
# 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
oa_ver ?=0.0.1
oa_build=`date +%Y/%m/%dT%H:%M:%S%z`
OPT_OA_VER=-DOA_VERSION=$(oa_ver)
OPT_OA_BUILD=-DOA_BUILD=$(oa_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=
OS_LIB_PATH=
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_OA_VER) $(OPT_OA_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

# lrauv-lcmtypes
LRAUV_LCM_INC_PATH= -I../../lrauv-lcmtypes/include

# Compilation Options
LINT = cppcheck
LINT_FLAGS = --force
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) $(LRAUV_LCM_INC_PATH) -I../idt

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

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

OA_SRC	= ObsAvoid.cc ObsAvoidLog.cc
OA_OBJ	= $(OA_SRC:%.cc=$(BUILD_DIR)/%.o)

OATEST	= lrTest
OATEST_SRC	= lrTest.cc
OATEST_OBJ	= $(OATEST_SRC:%.cc=$(BUILD_DIR)/%.o)
OATEST_LIBS	= -lm -ldeltat -lidt83p -lqnx -lgeolib -liniparser -llcm

MAIN	= oa
MAIN_SRC	= oa.cc
MAIN_OBJ	= $(MAIN_SRC:%.cc=$(BUILD_DIR)/%.o)
MAIN_LIBS	= -lm -ldeltat -lidt83p -loautils -lqnx -lgeolib -liniparser -llcm

########################################
# Build Files (mostly for cleanup)
SOURCES	= $(OA_SRC) $(OATEST_SRC) $(MAIN_SRC)
OBJECTS	= $(OA_OBJ) $(OATEST_OBJ) $(MAIN_OBJ)

#DEPENDS = $(BUILD_DIR)/*.d
DEPENDS = $(OA_SRC:%.cc=$(BUILD_DIR)/%.d) \
		$(OATEST_SRC:%.cc=$(BUILD_DIR)/%.d) \
		$(MAIN_SRC:%.cc=$(BUILD_DIR)/%.d)

BINARIES = $(OUTPUT_DIR)/$(OATEST) $(OUTPUT_DIR)/$(MAIN)

CLEANUP = gmon.out
# dSYMs : XCode debug symbol file folders
#DSYMS   = $(BINARIES:%=%.dSYM)
#RM_DSYMS = rm -rf $(DSYMS)

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

all: $(BINARIES)

-include $(DEPENDS)

# build oa test utility
$(OUTPUT_DIR)/$(OATEST):	$(OA_OBJ) $(OATEST_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(LIB_PATHS) $^ -o $@ $(LD_FLAGS) $(OATEST_LIBS)
	@echo

# build oa main
$(OUTPUT_DIR)/$(MAIN):	$(MAIN_OBJ) $(OA_OBJ)
	@echo building $@...
	$(CXX) $(INC_PATHS) $(LIB_PATHS) $^ -o $@ $(LD_FLAGS) $(MAIN_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
.PHONY: lint

# lint : lint the source code for this project
lint:
	$(LINT) $(LINT_FLAGS) $(OA_SRC) $(MAIN_SRC) $(INC_PATHS)

# 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
