# See the README file for brief notes about this makefile.

# Copyright Notices

# This software was developed for use by the U.S. Government as
# represented by the Administrator of the National Aeronautics and
# Space Administration. No copyright is claimed in the United States
# under 17 U.S.C. 105.

# This software may be used, copied, and provided to others only as
# permitted under the terms of the contract or other agreement under
# which it was acquired from the U.S. Government.  Neither title to nor
# ownership of the software is hereby transferred.  This notice shall
# remain on all copies of the software.

# Sub-makes need to know full path of this directory
EUROPA_DIR=$(shell pwd)

# Copied from commonMakeOptions.imake: we need this before including
#   that file to avoid running find on BeOS and Cygwin.
THIS_OS = $(shell uname -s)

# We need sed and awk programs that can handle arbitrary length lines.
#  Cygwin and BeOS have GNU-based ones that work fine, but other systems often
#  have standard ones that don't and name the GNU ones with a 'g' prefix.
ifneq (,$(findstring CYGWIN,$(THIS_OS))$(findstring BeOS,$(THIS_OS)))

AWK=awk
SED=sed

else

ifeq (,$(shell find $(subst :, ,$(shell echo $${PATH})) -name gsed -type f -print))
SED=sed
else
SED=gsed
endif

ifeq (,$(shell find $(subst :, ,$(shell echo $${PATH})) -name gawk -type f -print))
AWK=awk
else
AWK=gawk
endif

endif

include commonMakeOptions.imake

MOST_BUILDS=Includes/version.hh \
	Libraries/all ConstraintNetwork/all TemporalNetwork/all \
	TokenNetwork/all PlanInfo/all ModelManager/all \
	ModelParser/all SearchLibrary/all ModelLoader/all

MOST_BUILDS+=libeuropa.$(XLOF)

all: most
	echo $@ > $@

most: $(MOST_BUILDS)
	echo $@ > $@

# This target probably should depend on clean so that it never adds
#   object, executable, or library files.
# The contents of dist.files should agree with the NewPlanDist CVS module.
# Note the use of GNU tar's -X option.
EuropaDist.tar: dist.files dist.exclude ALWAYS
	gtar -cf $@.tmp -X dist.exclude `cat dist.files`
	mv $@.tmp $@

tar: EuropaDist.tar
	echo $@ > $@

# Run the "benchmark" timing tests
timings: allPlanners ALWAYS
	test ! -f SupportFiles/timings.makefile || (cd SupportFiles && $(MAKE) -f timings.makefile timings)

docs: documentation
	echo $@ > $@

documentation: DesignDocuments/all \
		ImplementationDocuments/all \
		UserDocuments/all \
		doxygen.docs
	echo $@ > $@

EUROPA_VERSION_HH_DONE=true
MAKE += EUROPA_VERSION_HH_DONE=$(EUROPA_VERSION_HH_DONE)

Includes/version.hh: ALWAYS
ifdef EUROPA_VERSION
	@echo '#define $(EUROPA_VERSION)' > $@.tmp
else
	@echo '/* Normal version */' > $@.tmp
endif
	@echo '/* CPU type built on: $(CPU) */' >> $@.tmp
	@echo '/* Operating system: $(THIS_OS) */' >> $@.tmp
	@echo '/* Architecture: $(ARCHITECTURE) */' >> $@.tmp
	@echo '/* Top level programs from $(PROGS_DIR) */' >> $@.tmp
	@echo '/* Optimization: $(OPTIMIZE) */' >> $@.tmp
	@echo '/* Shared libraries: $(SHARED) */' >> $@.tmp
	@echo '/* OPTFLAG: $(OPTFLAG) */' >> $@.tmp
	@echo '/* DIRFLAG: $(DIRFLAG) */' >> $@.tmp
	@echo '/* PROFILE: $(PROFILE) */' >> $@.tmp
	@echo '/* PROFFLAG: $(PROFFLAG) */' >> $@.tmp
	@echo '/* DEBUG: $(DEBUG) */' >> $@.tmp
	@echo '/* DEBFLAG: $(DEBFLAG) */' >> $@.tmp
	@echo '/* SHAREFLAG: $(SHAREFLAG) */' >> $@.tmp
	@echo '/* LINKEXEFLAG: $(LINKEXEFLAG) */' >> $@.tmp
	@echo '/* CC: $(CC) */' >> $@.tmp
	@echo '/* CFLAGS: $(CFLAGS) */' >> $@.tmp
	@echo '/* PURIFY: $(PURIFY) */' >> $@.tmp
	@echo '/* LD: $(LD) */' >> $@.tmp
	@echo '/* LDFLAG: $(LDFLAG) */' >> $@.tmp
	@echo '/* DEPEND: $(DEPEND) */' >> $@.tmp
	@echo '/* Values of LATEX, WARNFLAG, LIBFLAG, LIBS, PARSER_LIBS, */' >> $@.tmp
	@echo '/*  LD_DIR, AR_DIR, FLEX_DIR, BISON_DIR, and GPROF_DIR */' >> $@.tmp
	@echo '/*  should not affect the compilation into *.o files. */' >> $@.tmp
	@test -s $@.tmp || echo 'makefile:118: Error: new Includes/version.hh is empty or missing'
	test -s $@.tmp
	@-cmp -s $@ $@.tmp || echo 'makefile:120: Includes/version.hh has changed:'
	@-cmp -s $@ $@.tmp || echo diff $@ $@.tmp
	@-diff $@ $@.tmp
	-cmp -s $@ $@.tmp || mv $@.tmp $@
	-test -s $@.tmp && rm -f $@.tmp
	test -s $@

#!!Should add UserDocuments/test-code here
test-code: all Planners/all ModuleTests/test-code SystemsTests/test-code TAGS
	@echo cd `pwd`
	echo $@ > $@

#!!Should add UserDocuments/test here
tests: test-code ModuleTests/tests SystemsTests/tests ModelLoader/tests TAGS
	@echo cd `pwd`
	echo $@ > $@

parser-tests: all
	cd ModuleTests && $(MAKE) Parser/tests

# Runs the longer (duration) tests unless DEBUG;
#   the output files can be > 80 GB if DEBUG.
longTests: tests unofficial plannerTests
ifneq (_EUROPA_DEBUG_VERSION_,$(EUROPA_VERSION))
	cd ModuleTests && $(MAKE) longTests
	cd Planners && $(MAKE) longTests
	cd UnofficialTests && $(MAKE) longTests
endif
	echo $@ > $@

everything: all allPlanners longTests docs
	echo $@ > $@

plannerTests: allPlanners tests
	cd Planners && $(MAKE) tests
	echo $@ > $@

simplePlannerTests: all simple tests
	cd Planners && $(MAKE) simplePlannerTests
	echo $@ > $@

alphaPlannerTests: all alpha tests
	cd Planners && $(MAKE) alphaPlannerTests
	echo $@ > $@

betaPlannerTests: all beta tests
	cd Planners && $(MAKE) betaPlannerTests
	echo $@ > $@

allPlanners: all simple beta hbss
	echo $@ > $@

alpha: all Planners/alphaPlan$(EXE)
	echo $@ > $@

Planners/alphaPlan$(EXE): all simple ALWAYS
	cd Planners && $(MAKE) alphaPlan$(EXE)

beta: all Planners/betaPlan$(EXE)
	echo $@ > $@

Planners/betaPlan$(EXE): all simple ALWAYS
	cd Planners && $(MAKE) betaPlan$(EXE)

hbss: all Planners/HBSSPlan$(EXE)
	echo $@ > $@

Planners/HBSSPlan$(EXE): all ALWAYS
	cd Planners && $(MAKE) HBSSPlan$(EXE)

simple: all Planners/simplePlan$(EXE)
	echo $@ > $@

Planners/simplePlan$(EXE): all ALWAYS
	cd Planners && $(MAKE) simplePlan$(EXE)

#unofficial: plannerTests docs UnofficialTests/tests
unofficial: tests docs UnofficialTests/tests
	echo $@ > $@

check: SupportFiles/chkmkfs ALWAYS
	SupportFiles/chkmkfs > $@.tmp 2>&1
	mv $@.tmp $@
	cat $@

Libraries/all: Includes/version.hh TAGS
	cd Libraries && $(MAKE) all

ConstraintNetwork/all: Includes/version.hh TemporalNetwork/all TAGS
	cd ConstraintNetwork && $(MAKE) all

ModelManager/all: Includes/version.hh TAGS
	cd ModelManager && $(MAKE) all

ModelParser/all: Includes/version.hh Libraries/all TokenNetwork/all TAGS
	cd ModelParser && $(MAKE) all

# This doesn't depend on TAGS because TAGS depends on it
ModelParser/depend: Includes/version.hh ALWAYS
	cd ModelParser && $(MAKE) depend

ModelLoader/all: Includes/version.hh ModelParser/all TAGS
	cd ModelLoader && $(MAKE) all

TemporalNetwork/all: Includes/version.hh TAGS
	cd TemporalNetwork && $(MAKE) all

TokenNetwork/all: Includes/version.hh ConstraintNetwork/all ModelManager/all TAGS
	cd TokenNetwork && $(MAKE) all

PlanInfo/all: Includes/version.hh TokenNetwork/all TAGS
	cd PlanInfo && $(MAKE) all

ifneq (,$(findstring CYGWIN,$(THIS_OS)))
Planners/all: Includes/version.hh SearchLibrary/all ModelLoader/all ConstraintNetwork/all \
		Libraries/all TemporalNetwork/all TokenNetwork/all PlanInfo/all TAGS
	cd Planners && $(MAKE) all
else
Planners/all: Includes/version.hh SearchLibrary/all ModelLoader/all libeuropa.$(XLOF) TAGS
	cd Planners && $(MAKE) all
endif

SearchLibrary/all: Includes/version.hh TAGS
	cd SearchLibrary && $(MAKE) all

#!!These next three targets include a nasty kludge and
#!!  a hard-coded list of file names (in $(PARSEROBJS));
#!!  both need fixing --wedgingt 2002 Feb 6

# This next line should be used once the fixes are made
#SUBDIRS=SearchLibrary TokenNetwork PlanInfo ModelParser ModelManager ConstraintNetwork TemporalNetwork Libraries
SUBDIRS=SearchLibrary TokenNetwork PlanInfo ModelManager TemporalNetwork Libraries
SUBDIRALLS=$(foreach DIR,$(SUBDIRS),$(DIR)/all)
SUBDIRALLS+=ModelParser/all ConstraintNetwork/all ModelLoader/all

libeuropa.a:: Includes/version.hh $(SUBDIRALLS)

CONSNETSRCS=$(wildcard ConstraintNetwork/*.cc)
CONSNETOBJS=$(patsubst %.cc,%.o,$(CONSNETSRCS))

LOADEROBJ=ModelLoader/libModelLoader.o

PARSEROBJS=ModelParser/ddlModelParser.o ModelParser/ddl-lexer.o

$(PARSEROBJS): Includes/version.hh ModelParser/all
	test $(foreach file,$(PARSEROBJS),-s $(file) -a ) -d ModelParser

SUBDIRSRCS=$(foreach DIR,$(SUBDIRS),$(wildcard $(DIR)/*.cc))
SUBDIROBJS=$(patsubst %.cc,%.o,$(SUBDIRSRCS))
SUBDIROBJS+=$(PARSEROBJS)

ifneq (,$(findstring CYGWIN,$(THIS_OS)))

SUBDIROBJS+=$(CONSNETOBJS) $(MODEL_LOADER_OBJECTS)

ifneq (,$(JAM))
include ModelLoader/all-objects.txt
else
MODEL_LOADER_OBJECTS=ModelLoader/ModelLoader.o ModelLoader/ddlModelParserWrapper.o 
endif

else

SUBDIROBJS+=$(LOADEROBJ) libConstraintNetwork.o

libConstraintNetwork.o: ConstraintNetwork/all $(CONSNETOBJS) Includes/version.hh
	$(LD_DIR)/ld -r -o $@ $(CONSNETOBJS)

$(LOADEROBJ): ModelLoader/all Includes/version.hh

endif

libeuropa.a:: $(SUBDIROBJS)
	$(AR) $@ $?
	$(RANLIB) $@

# This modifies libeuropa.a every run, forcing a complete recompile and re-test every time
#libeuropa.a:: ALWAYS
#	$(RANLIB) $@

ifeq (,$(findstring CYGWIN,$(THIS_OS)))
libeuropa.so: Includes/version.hh $(SUBDIRALLS) libConstraintNetwork.o
	$(LD) $(LDFLAG) -o $@ $(SUBDIROBJS) $(PARSER_LIBS)
endif

SearchLibrary/libSearchToolLibrary.$(XLOF): SearchLibrary/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

TokenNetwork/libTokenNetwork.$(XLOF): TokenNetwork/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

PlanInfo/libPlanInfo.$(XLOF): PlanInfo/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

ModelParser/libddl-parser.$(XLOF): ModelParser/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

ModelLoader/libModelLoader.$(XLOF): ModelLoader/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

ModelManager/libModelManager.$(XLOF): ModelManager/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

ConstraintNetwork/libConstraintNetwork.$(XLOF): ConstraintNetwork/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

TemporalNetwork/libTemporalNetwork.$(XLOF): TemporalNetwork/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

Libraries/libCommonObjectLibrary.$(XLOF): Libraries/all
	cd $(dir $@) && $(MAKE) $(notdir $@)

DesignDocuments/all: TAGS ModelParser/depend
ifeq (,$(DONT_LATEX))
	cd DesignDocuments && $(MAKE) all
endif

ImplementationDocuments/all: TAGS
ifeq (,$(DONT_LATEX))
	cd ImplementationDocuments && $(MAKE) all
endif

UserDocuments/all: TAGS
ifeq (,$(DONT_LATEX))
	cd UserDocuments && $(MAKE) all
endif

doxygen.docs: TAGS ModelParser/depend
	doxygen doxygen.cfg > $@.tmp 2> $@.err
	@echo Doxygen stderr:
	cat $@.err
	@echo Doxygen stdout:
	cat $@.tmp
	@echo Doxygen done.
	mv $@.tmp $@

# This depends on simple because the ReaderWriter and Subscriber tests need simplePlan.
#   See GNATS 1648.
ModuleTests/test-code: Includes/version.hh TAGS simple
	cd ModuleTests && $(MAKE) test-code

# The next should depend on ModuleTests/test-code, but that means that
#  if any test(s) fail to compile, _no_ tests will be run.
# It thus depends on simple because ModuleTests/test-code does.
ModuleTests/tests: Includes/version.hh TAGS simple
	cd ModuleTests && $(MAKE) tests

ModelLoader/tests: Includes/version.hh TAGS libeuropa.a
	cd ModelLoader && $(MAKE) tests

SystemsTests/all: Includes/version.hh TAGS all
	cd SystemsTests && $(MAKE) all

SystemsTests/test-code: Includes/version.hh TAGS all
	cd SystemsTests && $(MAKE) test-code

SystemsTests/tests: Includes/version.hh TAGS all
	cd SystemsTests && $(MAKE) tests

UnofficialTests/test-code: Includes/version.hh TAGS
	cd UnofficialTests && $(MAKE) all

# This has the same problem as ModuleTests/tests, noted above.
UnofficialTests/tests: Includes/version.hh TAGS
	cd UnofficialTests && $(MAKE) tests

# This depends on ModelParser/depend because that creates some C/C++ source files
TAGS: ALWAYS ModelParser/depend
ifneq (,$(DONT_MAKE_TAGS))
	touch $@
else
	rm -f $@
	etags -o $@ Includes/*.hh
	find '$(EUROPA_DIR)' -name "*.cc" -o -name "*.c" | xargs etags -a -o $@
endif

ALWAYS:
ifdef SUNCC
ifeq ($(SUNCC),4)
	-test -d Templates.DB || mkdir Templates.DB
	test -d Templates.DB
else
	-test -d SunWS_cache || mkdir SunWS_cache
	test -d SunWS_cache
endif
endif

clean: Includes/version.hh cleanDepend
	test ! -f Libraries/makefile || (cd Libraries && $(MAKE) clean)
	test ! -f TemporalNetwork/makefile || (cd TemporalNetwork && $(MAKE) clean)
	test ! -f ConstraintNetwork/makefile || (cd ConstraintNetwork && $(MAKE) clean)
	test ! -f TokenNetwork/makefile || (cd TokenNetwork && $(MAKE) clean)
	test ! -f PlanInfo/makefile || (cd PlanInfo && $(MAKE) clean)
	test ! -f ModelManager/makefile || (cd ModelManager && $(MAKE) clean)
	test ! -f ModelParser/Makefile || (cd ModelParser && $(MAKE) clean)
	test ! -f ModelLoader/makefile || (cd ModelLoader && $(MAKE) clean)
	test ! -f SearchLibrary/makefile || (cd SearchLibrary && $(MAKE) clean)
	test ! -f Planners/makefile || (cd Planners && $(MAKE) clean)
	test ! -f DesignDocuments/makefile || (cd DesignDocuments && $(MAKE) clean)
	test ! -f ImplementationDocuments/makefile || (cd ImplementationDocuments && $(MAKE) clean)
	test ! -f UserDocuments/makefile || (cd UserDocuments && $(MAKE) clean)
	test ! -f ModuleTests/makefile || (cd ModuleTests && $(MAKE) clean)
	test ! -f SystemsTests/makefile || (cd SystemsTests && $(MAKE) clean)
	test ! -f UnofficialTests/makefile || (cd UnofficialTests && $(MAKE) clean)
	rm -f *.o all most tests test-code */all depend TAGS ALWAYS clean everything
	rm -f unofficial check libeuropa.a libeuropa.so longTests most simple docs
	rm -f plannerTests allPlanners alpha beta hbss check libConstraintNetwork.o
	rm -f cleanDepend tar EuropaDist.tar EuropaDist.tar.tmp timings documentation
	rm -f parser-tests simplePlannerTests alphaPlannerTests betaPlannerTests
	rm -f Includes/version.hh
	find '$(EUROPA_DIR)' -type f -name .planner_dir -exec rm -rf {} \;

cleanDepend: ALWAYS
	rm -f cleanDepend
	find '$(EUROPA_DIR)' -type f -name depend -exec rm -rf {} \;
ifdef SUNCC
ifeq ($(SUNCC),4)
	rm -f libTemplates.a libTemplates.$(XLOF)
	-cd Templates.DB && find '$(EUROPA_DIR)' -type f -exec rm {} \;
else
	find '$(EUROPA_DIR)' -type d -name SunWS_cache -exec rm -rf {} \;
endif
endif

# Use this if any .cc files are added to this directory.
#depend: *.cc makefile
#	$(DEPEND)

# Use this while there are no .cc files in this directory.
depend:
	touch $@

include depend
