
CFILEEXT=cpp

ifndef CXX
CXX=g++
endif

CXXFLAGS+=-g -Wall -D_REENTRANT -fno-exceptions -fPIC
CXXINC_BASE=-I../include -I../include/Aria -I../include/ArNetworking
CXXLINK_BASE=-L../lib -lBaseArnl -lArNetworkingForArnl -lAriaForArnl -lpthread -ldl -lrt -Xlinker -Bstatic -lstdc++ -Xlinker -Bdynamic -lpthread -ldl -lrt 
LIBTARGETS_BASE=../lib/libBaseArnl.so ../lib/libArNetworkingForArnl.so ../lib/libAriaForArnl.so 

CXXLINK_ARNL=-lArnl
LIBTARGETS_ARNL=../lib/libArnl.so
CXXINC_ARNL=-DARNL

CXXLINK_SONARNL=-lSonArnl
LIBTARGETS_SONARNL=../lib/libSonArnl.so
CXXINC_SONARNL=-DSONARNL

CXXLINK_MOGS=-lMogs
LIBTARGETS_MOGS=../lib/libMogs.so
CXXINC_MOGS=-DMOGS

# Initialize _ALL variables with BaseArnl options:

CXXLINK_ALL=$(CXXLINK_BASE)
LIBTARGETS_ALL=$(LIBTARGETS_BASE)
CXXINC_ALL=$(CXXINC_BASE)
DEFAULT_TARGETS=

# Now add options to the _ALL variables depending on what header files we have:

ifeq (../include/ArLocalizationTask.h,$(wildcard ../include/ArLocalizationTask.h))
CXXLINK_ALL+=$(CXXLINK_ARNL)
CXXINC_ALL+=$(CXXINC_ARNL)
LIBTARGETS_ALL+=$(LIBTARGETS_ARNL)
DEFAULT_TARGETS+=arnlServer
endif

ifeq (../include/ArSonarLocalizationTask.h,$(wildcard ../include/ArSonarLocalizationTask.h))
CXXLINK_ALL+=$(CXXLINK_SONARNL)
CXXINC_ALL+=$(CXXINC_SONARNL)
LIBTARGETS_ALL+=$(LIBTARGETS_SONARNL)
DEFAULT_TARGETS+=sonarnlServer
endif

ifeq (../include/ArGPSLocalizationTask.h,$(wildcard ../include/ArGPSLocalizationTask.h))
CXXLINK_ALL+=$(CXXLINK_MOGS)
CXXINC_ALL+=$(CXXINC_MOGS)
LIBTARGETS_ALL+=$(LIBTARGETS_MOGS)
DEFAULT_TARGETS+=mogsServer
endif

#ifeq ($(LIBTARGETS_ALL),)
#$(error No library targets selected, are the header files missing?)
#endif

#CXXSTATICLINK+=-L../lib -Xlinker -Bstatic -lBaseArnl -lArNetworkingForArnl -lAriaForArnl -Xlinker -Bdynamic -lpthread -ldl -lrt -Xlinker -Bstatic -lstdc++ -Xlinker -Bdynamic

LIBTARGETS_ALL_STATIC:=$(patsubst %.so,%.a,$(LIBTARGETS_ALL))
LIBTARGETS_ARNL_STATIC:=$(patsubst %.so,%.a,$(LIBTARGETS_ARNL))
LIBTARGETS_SONARNL_STATIC:=$(patsubst %.so,%.a,$(LIBTARGETS_SONARNL))
LIBTARGETS_MOGS_STATIC:=$(patsubst %.so,%.a,$(LIBTARGETS_MOGS))
LIBTARGETS_BASE_STATIC:=$(patsubst %.so,%.a,$(LIBTARGETS_BASE))

EXAMPLES_CPP:=$(shell find . -name '*.$(CFILEEXT)')
EXAMPLES:=$(patsubst %.$(CFILEEXT),%,$(EXAMPLES_CPP))

# (Explicitlly add those targets whose source files may not have been autogenerated yet)
ALL_TARGETS:=$(EXAMPLES) arnlServer sonarnlServer mogsServer arnlJustLocalization sonarnlJustLocalization mogsJustLocalization 
ALL_TARGETS_STATIC:=$(patsubst %,%Static,$(ALL_TARGETS))

default: $(DEFAULT_TARGETS)

all: $(ALL_TARGETS)

.PHONY: libs checkCompiler all clean info depAll cleanAll  src

Makefile.dep: 
	$(MAKE) dep

dep: clean 
	if [ -f `echo *.cpp | cut -d' ' -f1` ]; then \
	$(CXX) $(CXXFLAGS) $(CXXINC_ALL) -MM *.cpp | \
	awk '$$1 ~ /:/{printf "%s\n", $$0} $$1 !~ /:/' | \
	sed 's/\.o//' > Makefile.dep; fi

cleanDep:
	-rm Makefile.dep


info:
	@echo LIBTARGETS_BASE=$(LIBTARGETS_BASE)
	@echo LIBTARGETS_ARNL=$(LIBTARGETS_ARNL)
	@echo LIBTARGETS_SONARNL=$(LIBTARGETS_SONARNL)
	@echo LIBTARGETS_MOGS=$(LIBTARGETS_MOGS)
	@echo LIBTARGETS_ALL=$(LIBTARGETS_ALL)
	@echo LIBTARGETS_BASE_STATIC=$(LIBTARGETS_BASE_STATIC)
	@echo LIBTARGETS_ARNL_STATIC=$(LIBTARGETS_ARNL_STATIC)
	@echo LIBTARGETS_SONARNL_STATIC=$(LIBTARGETS_SONARNL_STATIC)
	@echo LIBTARGETS_MOGS_STATIC=$(LIBTARGETS_MOGS_STATIC)
	@echo LIBTARGETS_ALL_STATIC=$(LIBTARGETS_ALL_STATIC)
	@echo DEFAULT_TARGETS=$(DEFAULT_TARGETS)
	@echo EXAMPLES_CPP=$(EXAMPLES_CPP)
	@echo EXAMPLES=$(EXAMPLES)
	@echo ALL_TARGETS=$(ALL_TARGETS)
	@echo CXXLINK_BASE=$(CXXLINK_BASE)
	@echo CXXLINK_ARNL=$(CXXLINK_ARNL)
	@echo CXXLINK_SONARNL=$(CXXLINK_SONARNL)
	@echo CXXLINK_MOGS=$(CXXLINK_MOGS)
	@echo CXXLINK_ALL=$(CXXLINK_ALL)
	@echo CXXINC_BASE=$(CXXINC_BASE)
	@echo CXXINC_ARNL=$(CXXINC_ARNL)
	@echo CXXINC_SONARNL=$(CXXINC_SONARNL)
	@echo CXXINC_MOGS=$(CXXINC_MOGS)
	@echo CXXINC_ALL=$(CXXINC_ALL)
	@echo CXXFLAGS=$(CXXFLAGS)

help:
	@echo To build the default examples based on what localization libraries are available, run 'make'.
	@echo To build a program named 'example' with source file example.cpp, and linking with all localization libraries available, run 'make example'.  
	@echo To build all programs in this directory, linking with all localization libraries available, run 'make all'.  
	@echo To build a program linking only to one localization library, prefix it with 'arnl', 'sonarnl', or 'mogs'.



# if we're using an ARNL developer's machine, define rules
# to build libraries, autogenerate examples, etc.
ifeq (../src/Makefile,$(wildcard ../src/Makefile))
depAll:
	$(MAKE) -C ../src depAll

cleanAll:
	$(MAKE) -C ../src cleanAll

../lib/lib%: FORCE
	$(MAKE) -C ../src $@

# Dummy rule to force running $(MAKE) -C ../src to make libraries (if
# neccesary), since there's no easy way to know here if neccesary.
FORCE: 

# Tell make not to delete the library targets after building them 
.SECONDARY: $(LIBTARGETS_ALL) $(LIBTARGETS_ALL_STATIC) $(LIBTARGETS_BASE) $(LIBTARGETS_BASE_STATIC)

# Generate example programs from a template program, resolving
# all of its ugly ifdefs:
GPPOPTS:=--noincludes -D_GPP +s '/*' '*/' '' +s '//' '\n' '' +s '///' '\n' '' +s '/**' '*/' '' +s '/*!' '*/' '' +s '"' '"' '\\'

arnl%.cpp: combined%.cpp ../utils/gpp
	@echo Generating $@ from $< using gpp -DARNL...
	../utils/gpp $(GPPOPTS) -DARNL <$< >$@

sonarnl%.cpp: combined%.cpp ../utils/gpp
	@echo Generating $@ from $< using gpp -DSONARNL...
	../utils/gpp $(GPPOPTS) -DSONARNL <$< >$@

mogs%.cpp: combined%.cpp ../utils/gpp
	@echo Generating $@ from $< using gpp -DMOGS...
	../utils/gpp $(GPPOPTS) -DMOGS <$< >$@

src: arnlServer.cpp sonarnlServer.cpp mogsServer.cpp arnlSimpleExample.cpp sonarnlSimpleExample.cpp mogsSimpleExample.cpp

../utils/gpp: ../utils/gpp.c
	$(MAKE) -C ../utils gpp

combined%_arnl: combined%.cpp  $(LIBTARGETS_ARNL) $(LIBTARGETS_BASE)
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_ARNL) $< -o $@ $(CXXLINK_ARNL) $(CXXLINK_BASE)

combined%_sonarnl: combined%.cpp  $(LIBTARGETS_SONARNL) $(LIBTARGETS_BASE)
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_SONARNL) $< -o $@ $(CXXLINK_SONARNL) $(CXXLINK_BASE)

combined%_mogs: combined%.cpp  $(LIBTARGETS_MOGS) $(LIBTARGETS_BASE)
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_MOGS) $< -o $@ $(CXXLINK_MOGS) $(CXXLINK_BASE)

clean:
	-rm -f $(ALL_TARGETS) $(ALL_TARGETS_STATIC) 

# Cancel make's default rule, which would otherwise be used if libraries aren't built yet:
%: %.$(CFILEEXT)

else

# Default rules used if library targets are missing: 
#%: %.$(CFILEEXT) 
#	echo error Error building $@. Missing one of: $(LIBTARGETS_ALL) $(LIBTARGETS_BASE) Makefile.dep, critical error
#	for f in $(LIBTARGETS_ALL) $(LIBTARGETS_BASE) Makefile.dep; do echo testing $$f; if test ! -e $$f; then echo $$f is missing.; else echo $$f is there; fi; done
#	echo reinstall package
#
#%Static: %.$(CFILEEXT)
#	echo error Error building $@. Missing one of: $(LIBTARGETS_ALL_STATIC) $(LIBTARGETS_BASE_STATIC) Makefile.dep, critical error
#	for f in $(LIBTARGETS_ALL_STATIC) $(LIBTARGETS_BASE_STATIC) Makefile.dep; do echo testing $$f; if test ! -e $$f; then echo $$f is missing.; else echo $$f is there; fi; done
#	echo reinstall package

clean:
	-rm -f $(ALL_TARGETS)

endif

arnl%Static: arnl%.cpp $(LIBTARGETS_ARNL_STATIC) $(LIBTARGETS_BASE_STATIC) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_ARNL) $< -o $@ -Wl,-Bstatic $(CXXLINK_ARNL) $(CXXLINK_BASE)

sonarnl%Static: sonarnl%.cpp $(LIBTARGETS_SONARNL_STATIC) $(LIBTARGETS_BASE_STATIC) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_SONARNL) $< -o $@ -Wl,-Bstatic $(CXXLINK_SONARNL) $(CXXLINK_BASE)

mogs%Static: mogs%.cpp $(LIBTARGETS_MOGS_STATIC) $(LIBTARGETS_BASE_STATIC) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_MOGS) $< -o $@ -Wl,-Bstatic $(CXXLINK_MOGS) $(CXXLINK_BASE)

arnl%: arnl%.cpp $(LIBTARGETS_ARNL) $(LIBTARGETS_BASE) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_ARNL) $< -o $@ $(CXXLINK_ARNL) $(CXXLINK_BASE)

sonarnl%: sonarnl%.cpp $(LIBTARGETS_SONARNL) $(LIBTARGETS_BASE) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_SONARNL) $< -o $@ $(CXXLINK_SONARNL) $(CXXLINK_BASE)

mogs%: mogs%.cpp $(LIBTARGETS_MOGS) $(LIBTARGETS_BASE) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_MOGS) $< -o $@ $(CXXLINK_MOGS) $(CXXLINK_BASE)

mogsServer: mogsServer.cpp $(LIBTARGETS_MOGS) $(LIBTARGETS_BASE) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_MOGS) $< -o $@ $(CXXLINK_MOGS) $(CXXLINK_BASE)

sickLogger: sickLogger.cpp $(LIBTARGETS_ARNL) $(LIBTARGETS_BASE) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_ARNL) $< -o $@ $(CXXLINK_ARNL) $(CXXLINK_BASE)

sickLoggerStatic: sickLogger.cpp $(LIBTARGETS_ARNL_STATIC) $(LIBTARGETS_BASE_STATIC) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_ARNL) $< -o $@ -Wl,-Bstatic $(CXXLINK_ARNL) $(CXXLINK_BASE)

%Static: %.$(CFILEEXT) $(LIBTARGETS_ALL_STATIC) $(LIBTARGETS_BASE_STATIC) Makefile.dep
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_ALL) $< -o $@ -Wl,-Bstatic $(CXXLINK_ALL) $(CXXLINK_BASE)

%: %.$(CFILEEXT) $(LIBTARGETS_ALL) $(LIBTARGETS_BASE) Makefile.dep 
	$(CXX) $(CXXFLAGS) $(CXXINC_BASE) $(CXXINC_ALL) $< -o $@ $(CXXLINK_ALL) $(CXXLINK_BASE)

convertCoordsToArMap: convertCoordsToArMap.cpp ../lib/libAriaForArnl.so Makefile.dep
	$(CXX) $(CXXFLAGS) -I../include/Aria $< -o $@ -L../lib -lAriaForArnl -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -lpthread -ldl -lrt

checkCompiler:
	@GCCMAJOR=`$(CXX) -v 2>&1 | grep "gcc version" | cut -f 3 -d ' ' | cut -f 1 -d .`; \
	GCCMINOR=`$(CXX) -v 2>&1 | grep "gcc version" | cut -f 3 -d ' ' | cut -f 2 -d .`; \
	if [ $$GCCMAJOR != "3" ] || [ $$GCCMINOR != "4" ] ; then  \
	echo "You must use gcc 3.4 when compiling ARNL"; \
	echo "It seems you are using gcc $$GCCMAJOR.$$GCCMINOR"; \
	echo "See Arnl/README.txt in the Linux Installation section"; \
	exit 1; fi

ifeq (Makefile.dep,$(wildcard Makefile.dep))
include Makefile.dep
endif


