###############################################################################
# Makefile for libFAUDES, tmoor 20130811
#
# Requires GNU make
#
# PLATFORM:
#
# Unix/posix environment (Linux, Mac OSX) or Win32; see compiler options below. 
#
# USER TARGETS: 
# 
# default:    build library and utility executables
# static:     build libfaudes static library
# shared:     build libfaudes shared object
# tutorial:   build all examples from tutorial sections
# clean:      remove intermediate objects etc
# test:       validate test cases (requires tutorials)
#
# DEVELOPER TARGETS
#
# dist-clean: clear all configuration
# configure:  autogenerate includes and documentation files wrt 
#             compiletime options and plug-ins
# package:    prepare tgz-archive
#
#
# CONFIGURATION
#
# The target "configure" uses the variables FAUDES_PLUGINS, FAUDES_DEBUG
# and FAUDES_OPTIONS to configure sources, the run-time interface and documentaion. The
# variables are cached in Makefile.configuration. Any change of these variables requires
# a "make dist-clean", "make configure" to take an effect.
#
###############################################################################


###############################################################################
#
# PLUGINS:
#
# Setting the environment variable FAUDES_PLUGINS to a space separated list
# of plug-ins will include the corresponding plug-in makefiles to append
# additional sources and to register the plug-in in include/configuration.h. 
#
# Note: this only takes effect with the target "configure"
#
###############################################################################

# manualy enable plug-ins (uncomment corresponding lines)
ifeq ($(FAUDES_PLUGINS),)
FAUDES_PLUGINS = 
#FAUDES_PLUGINS += example
#FAUDES_PLUGINS += synthesis
#FAUDES_PLUGINS += observer
#FAUDES_PLUGINS += multitasking
#FAUDES_PLUGINS += diagnosis
#FAUDES_PLUGINS += bddsynthesis
#FAUDES_PLUGINS += pushdown
#FAUDES_PLUGINS += hiosys
#FAUDES_PLUGINS += iosystem
#FAUDES_PLUGINS += coordinationcontrol
#FAUDES_PLUGINS += hybrid
#FAUDES_PLUGINS += timed
#FAUDES_PLUGINS += simulator
#FAUDES_PLUGINS += iodevice
#FAUDES_PLUGINS += luabindings
endif

# auto-enable all present plug-ins except non-standards                                           
ifeq ($(FAUDES_PLUGINS),)
FAUDES_PLUGINS := $(notdir $(wildcard plugins/*))
FAUDES_PLUGINS := $(subst example,,$(FAUDES_PLUGINS))
FAUDES_PLUGINS := $(subst bddsynthesis,,$(FAUDES_PLUGINS))
FAUDES_PLUGINS := $(subst hybrid,,$(FAUDES_PLUGINS))
endif



###############################################################################
# Configure core features
#
# Note: this only takes effect with the target "configure"
#
###############################################################################

# elementary systemtime (gettimeofday wrappers)
FAUDES_OPTIONS += core_systime

# elementary networking (including headers, requires systime)
FAUDES_OPTIONS += core_network

# elementary thread support (mimic POXIS threads, requires systime)
FAUDES_OPTIONS += core_threads



###############################################################################
# Configure console output i.e. debug level
#
# Note: this only takes effect with the target "configure"
#
###############################################################################

# initialize with no console output
FAUDES_DEBUG=

#   core_checked
#      Turns on consistency tests on input data. Tests may introduce a slight
#      run-time overhead and through exceptions when a mismatch is detected.
#      If your application performs input data consistency, you may disable
#      this option. 

FAUDES_DEBUG += core_checked

#   core_code
#      Turns on consistency tests on internal data structures. Tests may introduce
#      a massive overhead and silently abort the application when inconsistency is
#      detected. This should be only activated during development.

#FAUDES_DEBUG += core_code

#   core_exceptions  
#      Write exceptions to stderr. For applications that catch exceptions and 
#      translate them a user friendly report, you may want to disable this option.

FAUDES_DEBUG += core_exceptions

#   core_compatibility
#      Enables code that is intended for backward compatibility. E.g. include
#      typedefs with pre 2.20b class names; read pre 2.18b token streams. Note, however,
#      that there is no attempt to achieve full backward compatibility. Changes in libFAUDES,
#      that are expected to affect applications/plug-ins are logged in the CHANGES file.
#      When developing new applications, you should disable this option. 

FAUDES_DEBUG += core_compatibility

#   core_function 
#      Print function debug messages (parallel, trim, etc)

#FAUDES_DEBUG += core_function

#   core_generator  
#      Print Generator debug messages (this is very verbose)

#FAUDES_DEBUG += core_generator

#   core_container
#      Print container (StateSet, EventSet, TransSet) debug messages.

#FAUDES_DEBUG += core_container

#   core_fregistry  
#      Report on type and function registration

#FAUDES_DEBUG += core_fregistry

#   core_interface  
#      Report on type and function definitions

#FAUDES_DEBUG += core_finterface

#   core_fverbose  
#      Print even more verbose debug messages (iterations, tokenio)

#FAUDES_DEBUG += core_fverbose

#   core_progress
#      Write function progress to console (only some particular functions support this)

#FAUDES_DEBUG += core_progress

#
#
###############################################################################


####################################
# Get version from file
####################################

include VERSION

####################################
# Include build configuration file 
# (FAUDES_PLUGINS, FAUDES_DEBUG, FAUDES_OPTIONS)
####################################

MAKECONFIG = Makefile.configuration

# if "configuration" is not goal, read make varaibles from file
ifneq (configure,$(findstring configure,$(MAKECMDGOALS)))
include $(MAKECONFIG)
endif


####################################
# compiler / linker / platform
####################################

### try to autoselect platform
ifeq ($(FAUDES_PLATFORM),)
FAUDES_PLATFORM := gcc_plain
# osx
FAUDES_OSTYPE := $(shell uname -s)
ifneq ($(findstring Darwin,$(FAUDES_OSTYPE)),)
FAUDES_PLATFORM := gcc_osx
endif
# linux
FAUDES_OSTYPE := $(shell uname -s)
ifneq ($(findstring Linux,$(FAUDES_OSTYPE)),)
FAUDES_PLATFORM := gcc_linux
endif
# windows
ifeq ($(findstring WINDOWS,$(SystemRoot)),WINDOWS)
FAUDES_PLATFORM := gcc_win
endif
endif

### sensible defaults: plain gcc compiler
CXX = g++
CC = gcc
LXX = g++
MAINOPTS = -O2
WARNINGS = -Wall 
PROFILING = 
LIBOPTS = -shared $(PROFILING)
LIBEXTENTION = so
LDFLAGS = 

### sensible defaults: external tools 
CP  = /bin/cp -p 
CPR = /bin/cp -pR
RM = /bin/rm -rf
MKDIR = /bin/mkdir
ECHOE = /bin/echo -e
TEMP ?= /tmp
DOXYGEN = doxygen
SHELL = /bin/bash
DIFF = diff -w --context=3 --show-function-line=mark 
SWIG = swig

# configure reference documentation
REF2HTML_CNAV ?= $(SRCDIR)/doxygen/faudes_navigation.include_fref
REF2HTML_CSS  ?= faudes.css
LUA2REF = $(CURDIR)/tools/lua2ref/lua2ref.pl
#LUA2REF = $(CURDIR)/bin/luafaudes $(CURDIR)/tools/lua2ref/lua2ref.lua

### adapt for gcc_linux: linux with gcc
ifeq ($(FAUDES_PLATFORM),gcc_linux)
MAINOPTS = -fpic -fstrict-aliasing -fmessage-length=0 -O3
WARNINGS = -pedantic -Wall
LDFLAGS = -Wl,--as-needed
PROFILING = 
endif

### adapt for lsb_linux: linux with lsb sdk
### variant for  sdk 4.1.7, using
###   ubuntu 10.04 lts with gcc 4.4.3 
###   debian 7.4 with gcc 4.7.2 
# note: dropped -fpic needed on debian 7.4 for lua 
ifeq ($(FAUDES_PLATFORM),lsb_linux)
CXX = /opt/lsb/bin/lsbc++ --lsb-target-version=3.2
CC = /opt/lsb/bin/lsbcc   --lsb-target-version=3.2
LXX = /opt/lsb/bin/lsbc++ --lsb-target-version=3.2 --lsb-besteffort
MAINOPTS =  -fPIC -fstrict-aliasing -fmessage-length=0 -O3
LDFLAGS = -Wl,--as-needed
WARNINGS = -Wall
PROFILING = 
endif

### adapt for gcc_osx: mac osx 10.04 and later
ifeq ($(FAUDES_PLATFORM),gcc_osx)
MAINOPTS = -fPIC -fstrict-aliasing -fmessage-length=0 -O3
WARNINGS = -pedantic 
PROFILING = 
LIBOPTS = -dynamiclib -single_module
LIBEXTENTION = dylib
DOXYGEN = /Applications/Doxygen.app/Contents/Resources/doxygen
ECHOE = echo -e
endif

### adapt for icc_linux: intel c++ on linux (not used since libFAUDES 1.0)
ifeq ($(FAUDES_PLATFORM),icc_linux)
CXX = icc
MAINOPTS = -fpic -fast -wd981 -cxxlib-gcc 
WARNINGS = 
PROFILING =
LDFLAGS = 
LIBOPTS = -shared
endif

### adapt for gcc_win: mingw on win32 
# (for user targets only)
ifeq ($(FAUDES_PLATFORM),gcc_win)
CP  = cmd /C echo ERROR RM NOT CONFIGURED
CPR = cmd /C echo ERROR RM NOT CONFIGURED
RM = cmd /C echo ERROR RM NOT CONFIGURED
SWIG = cmd /C echo ERROR SWIG NOT CONFIGURED
DIFF = fc /W
CXX = g++.exe
CC = gcc.exe
LXX = g++.exe
MAINOPTS = -O3 
WARNINGS = -pedantic -Wall 
PROFILING = 
LIBOPTS = -shared -enable-auto-import -export-all-symbols $(PROFILING)
LIBEXTENTION = dll
endif

### posix systems: link to pthreads
ifneq ($(FAUDES_PLATFORM),gcc_win)
ifeq (core_threads,$(findstring core_threads,$(FAUDES_OPTIONS)))
LDFLAGS += -lpthread 
endif
endif

### windows systems: link to winsock
ifeq ($(FAUDES_PLATFORM),gcc_win)
ifeq (core_network,$(findstring core_network,$(FAUDES_OPTIONS)))
LDFLAGS += -lwsock32
endif
endif


### summarize compiler flags in std variable
CFLAGS = $(MAINOPTS) $(PROFILING) $(WARNINGS) -I$(INCLUDEDIR) $(INCLUDES)


####################################
# Libfaudes directory structure
####################################

# where to find core sources (.cpp and doxygen input) 
SRCDIR = src
# where to place binaries 
BINDIR = bin
# where to place all .h files 
INCLUDEDIR = include
# where to place all .o files 
OBJDIR = obj
# where to place the distribution package 
DIST = dist
# where html docu is placed 
DOCDIR = doc
# where doxygen output is placed (via doxygen.conf)
DOXDOCDIR = doc/csource
# where to place html reference output 
REFDOCDIR = doc/reference
# where to luafaudes tutorials
LUADOCDIR = doc/luafaudes
# where to place images
IMGDOCDIR = doc/images
# where to place fref doc sources
REFSRCDIR = doc/refsrc

####################################
# Specify search path for sources
####################################

VPATH = $(SRCDIR)  $(SRCDIR)/registry 

####################################
# Corefaudes Files
####################################

CPPFILES = \
  cfl_platform.cpp  cfl_helper.cpp cfl_exception.cpp cfl_token.cpp cfl_tokenreader.cpp cfl_tokenwriter.cpp \
  cfl_types.cpp cfl_functions.cpp cfl_elementary.cpp cfl_registry.cpp \
  cfl_attributes.cpp cfl_symboltable.cpp \
  cfl_basevector.cpp cfl_baseset.cpp cfl_abaseset.cpp cfl_indexset.cpp cfl_symbolset.cpp \
  cfl_nameset.cpp cfl_transset.cpp \
  cfl_generator.cpp cfl_agenerator.cpp cfl_cgenerator.cpp cfl_localgen.cpp \
  cfl_graphfncts.cpp cfl_parallel.cpp cfl_determin.cpp cfl_project.cpp cfl_statemin.cpp\
  cfl_regular.cpp cfl_omega.cpp 


RTIDEFS = cfl_definitions.rti
RTIFREF = reference_index.fref reference_types.fref reference_functions.fref reference_literature.fref \
  corefaudes_index.fref corefaudes_elementary.fref \
  corefaudes_generator.fref corefaudes_alphabet.fref corefaudes_parallel.fref \
  corefaudes_reachability.fref corefaudes_vector.fref corefaudes_langboolean.fref corefaudes_genmisc.fref \
  corefaudes_regular.fref corefaudes_projection.fref corefaudes_statemin.fref

LIBEXECUTABLES = gen2dot fts2ftx ref2html rti2code flxinstall

HEADERS = $(CPPFILES:.cpp=.h) libfaudes.h configuration.h corefaudes.h allplugins.h cfl_definitions.h  
SOURCES = $(CPPFILES:%=$(SRCDIR)/%)
OBJECTS = $(CPPFILES:%.cpp=$(OBJDIR)/%.o) 
COREOBJECTS := $(patsubst %cfl_registry.o,%cfl_registry_mute.o,$(OBJECTS))
EXECUTABLES = $(LIBEXECUTABLES:%=$(BINDIR)/%)

RTIDEFS := $(RTIDEFS:%=$(SRCDIR)/registry/%)
RTIFREF := $(RTIFREF:%=$(SRCDIR)/registry/%)

LIBNAME = libfaudes

STATIC = $(LIBNAME).a

SHARED = $(LIBNAME).$(LIBEXTENTION)

DEPEND = .depend

CLEANFILES = $(OBJECTS) $(COREOBJECTS) $(DEPEND)

DISTCLEANFILES = $(DEPEND) $(MAKECONFIG)


####################################
# Two stages of source configuraton
# prepare: move files
# configure: run rti
####################################

PREPARETARGETS = $(MAKECONFIG) includes

CONFIGURETARGETS =  depend rti doc 


####################################
# Declare default target before including 
# other makefiles 
####################################

DEFAULTTARGETS = static shared bin 

default: default_after_include
	@echo " ============================== " 
	@echo "libFAUDES-make: default targets: done" 
	@echo "libFAUDES-make: you may now compile the tutorials by \"make tutorial\"" 
	@echo " ============================== " 

####################################
# Include generated dependency file
####################################

# if "clean" is goal, do not include a dependency file
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include $(DEPEND)
endif


####################################
# Setup plugin indicator variables
####################################

# helper 
emptystring := 
spacestring := $(emptystring) $(emptystring)

# ensure that luabindings comes last
ifneq ($(findstring luabindings,$(FAUDES_PLUGINS)),)
  FAUDES_PLUGINS := $(filter-out luabindings,$(FAUDES_PLUGINS)) 
  FAUDES_PLUGINS += luabindings
  FAUDES_PLUGINS := $(strip $(FAUDES_PLUGINS))
endif

# using plugins indicator string
pluginstringD = $(subst $(spacestring),-,$(FAUDES_PLUGINS))

# plugin makefiles
pluginstringM = $(patsubst %,./plugins/%/Makefile.plugin,$(FAUDES_PLUGINS))

# plugin tutorials
pluginstringT = $(patsubst %,./plugins/%/Makefile.plugin,$(FAUDES_PLUGINS))

# plugin directories
pluginstringC = $(patsubst %,./plugins/%,$(FAUDES_PLUGINS))

# plugin image directories
pluginstringI = $(patsubst %,./plugins/%/src/doxygen/faudes_images,$(FAUDES_PLUGINS))

# plugin tutorial directories
pluginstringT = $(patsubst %,./plugins/%/tutorial,$(FAUDES_PLUGINS))

# plugin registry directories
pluginstringR = $(patsubst %,./plugins/%/src/registry,$(FAUDES_PLUGINS))

# version with underscore
FILEVERSION = $(subst .,_,$(VERSION))

####################################
# Additional makefiles for plugins
####################################

include Makefile.tutorial

ifneq ($(pluginstringM),)
include $(pluginstringM)
endif

VPATH += $(pluginstringR)

default_after_include: $(ALLIENTARGETS) $(DEFAULTTARGETS)

# fix configuration variables (in particular FAUDES_OPTIONS)
ifneq (configure,$(findstring configure,$(MAKECMDGOALS)))
include $(MAKECONFIG)
endif

####################################
# Export variables to sub make
####################################

export FAUDES_DEBUG
export FAUDES_PLATFORM
export FAUDES_PLUGINS
export FAUDES_OPTIONS

####################################
# User Targets
####################################

all: dist-clean configure default tutorial tutorial test

includes: $(HEADERS:%=$(INCLUDEDIR)/%) $(INCLUDEDIR)/libfaudes.rti

prepare: $(PREPARETARGETS)

configure: prepare $(CONFIGURETARGETS)
	@echo " ============================== " 
	@echo "libFAUDES-make: configure: done" 
	@echo "libFAUDES-make: you may now compile the default targets by \"make\"" 
	@echo " ============================== " 

shared: $(SHARED)

static: $(STATIC)

bin: $(EXECUTABLES)

tutorial: $(TUTORIAL_EXECUTABLES)
	@echo " ============================== " 
	@echo "libFAUDES-make: tutorial targets: done" 
	@echo "libFAUDES-make: you may now run the provided test cases by \"make test\"" 
	@echo " ============================== " 

package: 
	$(RM) $(DIST) 
	mkdir $(DIST) 
	- rm -rf $(TEMP)/libfaudes-$(FILEVERSION) 
	- cp -pR . $(TEMP)/libfaudes-$(FILEVERSION) 
	- cp -pR $(TEMP)/libfaudes-$(FILEVERSION) $(DIST) 
	$(RM) $(DIST)/libfaudes-$(FILEVERSION)/plugins
	$(MKDIR) $(DIST)/libfaudes-$(FILEVERSION)/plugins
	- $(CPR)  $(pluginstringC) $(DIST)/libfaudes-$(FILEVERSION)/plugins
	- $(CPR)  plugins/example $(DIST)/libfaudes-$(FILEVERSION)/plugins
	cd $(DIST)/libfaudes-$(FILEVERSION) ; $(MAKE) dist-clean
	cd $(DIST)/libfaudes-$(FILEVERSION) ; $(MAKE) configure 
	cd $(DIST)/libfaudes-$(FILEVERSION) ; $(MAKE) 
	cd $(DIST)/libfaudes-$(FILEVERSION) ; $(MAKE) clean
	tar --verbose --create --gzip --directory="$(DIST)"  --exclude-from=$(SRCDIR)/TAR_EXCLUDES  --file="$(DIST)/libfaudes-$(FILEVERSION).tar.gz" libfaudes-$(FILEVERSION)


####################################
# Clean 
####################################

clean: $(CLEANTARGETS)
	$(RM) $(CLEANFILES) 
	$(RM) obj/*
	rm -rf tmp_valext 

dist-clean: doc-clean $(DISTCLEANTARGETS)
	rm -rf $(CLEANFILES) 
	rm -rf $(DISTCLEANFILES) 
	rm -rf $(EXECUTABLES) 
	rm -f $(SHARED) $(STATIC) 
	rm -f lib*faudes.a lib*faudes.dylib lib*faudes.so lib*faudes.dll 
	rm -rf $(INCLUDEDIR)/*
	rm -f *~  
	rm -f ._*  
	rm -f bin/._*
	rm -f bin/*
	rm -rf obj/*
	rm -f src/*~ 
	rm -f src/._* 
	rm -f src/registry/*~ 
	rm -f src/registry/*.bak 
	rm -f src/registry/._* 
	rm -f src/doxygen/*~ 
	rm -f src/doxygen/*.bak 
	rm -f src/doxygen/._* 
	rm -f tools/*~ 
	rm -f tools/._* 
	rm -f include/._* 
	rm -f tutorial/._* 
	rm -f tutorial/tmp_* 
	rm -f tutorial/*~ 
	rm -f tutorial/data/*~ 
	rm -f plugins/*/obj/* 
	rm -f plugins/*/src/*~ 
	rm -f plugins/*/src/._*
	rm -f plugins/*/src/registry/*~ 
	rm -f plugins/*/src/registry/*.bak
	rm -f plugins/*/src/registry/._*
	rm -f plugins/*/tutorial/*~ 
	rm -f plugins/*/tutorial/._* 
	rm -f plugins/*/tutorial/data/*~ 
	rm -f plugins/*/tutorial/tmp_* 
	rm -f plugins/*/tutorial/results/*.* 
	rm -f plugins/*/tutorial/results/*/*.* 
	rm -rf dist
	rm -rf tmp_valext 


####################################
# Configure source files
####################################

$(INCLUDEDIR)/allplugins.h: $(SRCDIR)/allplugins.h.template 
	cp $(SRCDIR)/allplugins.h.template $(INCLUDEDIR)/allplugins.h

$(INCLUDEDIR)/configuration.h: $(SRCDIR)/configuration.h.template 
	cp $(SRCDIR)/configuration.h.template $(INCLUDEDIR)/configuration.h
	echo "/* faudes core configuration */" >> $(INCLUDEDIR)/configuration.h
	echo "#define  FAUDES_VERSION \"libFAUDES $(VERSION)\"" >> $(INCLUDEDIR)/configuration.h
	echo "#define  FAUDES_PLUGINS \"$(pluginstringD)\"" >> $(INCLUDEDIR)/configuration.h
	echo "#define  FAUDES_PLUGINS_RTILOAD {$(FAUDES_PLUGINS_RTILOAD)}" >> $(INCLUDEDIR)/configuration.h
ifeq (core_systime,$(findstring core_systime,$(FAUDES_OPTIONS)))
	echo "#define  FAUDES_SYSTIME" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_network,$(findstring core_network,$(FAUDES_OPTIONS)))
	echo "#define  FAUDES_NETWORK" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_threads,$(findstring core_threads,$(FAUDES_OPTIONS)))
	echo "#define  FAUDES_THREADS" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_checked,$(findstring core_checked,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_CHECKED" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_code,$(findstring core_code,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_CODE" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_exceptions,$(findstring core_exceptions,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_EXCEPTIONS" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_compatibility,$(findstring core_compatibility,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_COMPATIBILITY" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_function,$(findstring core_function,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_FUNCTION" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_generator,$(findstring core_generator,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_GENERATOR" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_container ,$(findstring core_container,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_CONTAINER" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_fverbose,$(findstring core_fverbose,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_VERBOSE" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_progress ,$(findstring core_progress,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_WRITE_PROGRESS" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_fregistry ,$(findstring core_fregistry,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_REGISTRY" >> $(INCLUDEDIR)/configuration.h
endif
ifeq (core_finterface ,$(findstring core_finterface,$(FAUDES_DEBUG)))
	echo "#define  FAUDES_DEBUG_RUNTIMEINTERFACE" >> $(INCLUDEDIR)/configuration.h
endif
	echo " " >> $(INCLUDEDIR)/configuration.h

$(MAKECONFIG):
	rm -f $@
	touch $@
	echo "# libFAUDES build configuration" >> $@
	echo "# - do not edit this file manually" >> $@
	echo "# - see main Makefile for documentation" >> $@
	echo FAUDES_PLUGINS = $(FAUDES_PLUGINS) >> $@
	echo FAUDES_DEBUG = $(FAUDES_DEBUG) >> $@
	echo FAUDES_OPTIONS = $(FAUDES_OPTIONS) >> $@


####################################
# Run time interface
####################################

# run time interface target
rti: rtitools doc-reference doc-fref

# tools only
rtitools: $(INCLUDEDIR)/libfaudes.rti $(INCLUDEDIR)/rtiautoload.i $(BINDIR)/rti2code 

# clean
rti-clean:
	- rm -rf $(REFSRCDIR)  
	- rm -rf $(INCLUDEDIR)/rtiautoload*
	- rm -rf $(INCLUDEDIR)/libfaudes.rti

# have my muted registry object file
$(OBJDIR)/cfl_registry_mute.o: cfl_registry.cpp 
	$(CXX) -c $(CFLAGS) -DFAUDES_MUTE_RTIAUTOLOAD $(DEFINES) $< -o $@

# have my rti executabels
$(BINDIR)/rti2code: $(OBJDIR)/rti2code.o $(COREOBJECTS) 
	$(LXX) $^ $(LDFLAGS) -o $@

# merge rti files
$(INCLUDEDIR)/libfaudes.rti: $(BINDIR)/rti2code
	./bin/rti2code -merge $(RTIDEFS) $@

# have my auto register tools and produce includes
# note: we use .i as target since depend touches .h and .cpp
$(INCLUDEDIR)/rtiautoload.i: $(INCLUDEDIR)/libfaudes.rti $(BINDIR)/rti2code 
	./bin/rti2code $(INCLUDEDIR)/libfaudes.rti $(INCLUDEDIR)/rtiautoload


####################################
# Documentation: base
####################################

# all base documenation
BASEFREF = $(wildcard $(SRCDIR)/doxygen/*.fref)
BASEALL = $(BASEFREF) $(SRCDIR)/doxygen/faudes_navigation.include_fref
BASEHTML = $(foreach file,$(BASEFREF),$(DOCDIR)/$(basename $(notdir $(file))).html)
BASEHTML += $(DOCDIR)/index.html

# have fref source directory: time stamp
$(REFSRCDIR): $(REFSRCDIR)/.tstamp $(DOCDIR)/.tstamp

# have fref source directory: populate
$(REFSRCDIR)/.tstamp: $(BASEFREF) 
	- mkdir $(REFSRCDIR)
	- cp $(BASEALL) $(REFSRCDIR)
	- cp $(REF2HTML_CNAV) $(REFSRCDIR)/faudes_navigation.include_fref
	touch $@

# have a doc base directory: time stamp
$(DOCDIR): $(DOCDIR)/.tstamp

# have a doc base directory: populate
$(DOCDIR)/.tstamp: $(BASEALL) 
	- mkdir $(DOCDIR)
	- cp $(SRCDIR)/doxygen/faudes.css $(DOCDIR)
	touch $@

# copy index
$(DOCDIR)/index.html: $(DOCDIR)/faudes_about.html
	cp -f  $< $@

# build doc: run as script
doc-base: $(REFSRCDIR)


####################################
# Documentation: reference pages
####################################

# have reference documentation targets 
RTIHTML  = $(patsubst %.fref,$(REFDOCDIR)/%.html,$(notdir $(RTIFREF))) 
RTIHTML += $(REFDOCDIR)/index.html

# have fref source dir: time stamp
$(REFSRCDIR)/reference: $(REFSRCDIR)/reference/.tstamp

# have fref source dir: copy frefs  
$(REFSRCDIR)/reference/.tstamp: $(REFSRCDIR) $(RTIFREF) 
	- mkdir -p $(REFSRCDIR)/reference
	@echo copy frefs
	@ - cp -f $(RTIFREF) $(REFSRCDIR)/reference
	touch $@

# have dst directory: time stamp
$(REFDOCDIR): $(REFDOCDIR)/.tstamp

# have dst directory
$(REFDOCDIR)/.tstamp:
	- mkdir -p $(REFDOCDIR)
	touch $@

# registry main index
$(REFDOCDIR)/index.html: $(REFDOCDIR)/reference_index.html
	cp $^ $@ 

# plain copy
$(REFSRCDIR)/libfaudes.rti: $(INCLUDEDIR)/libfaudes.rti $(REFDOCDIR)
	cp $< $@
 
# target: copy fref source files
doc-reference: $(REFSRCDIR)/reference $(REFDOCDIR) $(REFSRCDIR)/libfaudes.rti 


####################################
# Documentaion: images 
####################################

# all images
IMAGES_ALL   = $(foreach dir,$(pluginstringI) $(SRCDIR)/doxygen/faudes_images,$(wildcard $(dir)/*)) 
IMAGES_FREF  = $(filter %.fref,$(IMAGES_ALL))
IMAGES_OTHER = $(filter-out %.fref,$(IMAGES_ALL))
IMAGES_HTML  = $(foreach file,$(IMAGES_FREF),$(IMGDOCDIR)/$(basename $(notdir $(file))).html)


# have destination directory
$(IMGDOCDIR): $(IMGDOCDIR)/.tstamp
$(IMGDOCDIR)/.tstamp:
	- mkdir -p $(IMGDOCDIR)
	touch $@

# have images fref source dir: time stamp
$(REFSRCDIR)/images: $(REFSRCDIR)/images/.tstamp

# copy images and fref to DOCDIR
$(REFSRCDIR)/images/.tstamp: $(REFSRCDIR) $(IMAGES_ALL) $(IMGDOCDIR)
	- mkdir -p $(REFSRCDIR)/images
	@echo copy images
	@ - cp -rf $(IMAGES_OTHER) $(IMGDOCDIR)
	@ - cp -rf $(IMAGES_FREF) $(REFSRCDIR)/images
	touch $@

# trigger (en-block copy if needed)
$(REFSRCDIR)/images/%.fref: $(REFSRCDIR)/images
	@echo trigger image copy    # need a recipie, otherwise the rule wont be applied

# target: make fref source files and copy images
doc-images: $(REFSRCDIR)/images


####################################
# Documentation lua tutorials
####################################

# if we have luabindings
ifeq (luabindings,$(findstring luabindings,$(FAUDES_PLUGINS)))

# all lua tutorials
LUATUTS  =$(foreach dir,$(pluginstringT),$(wildcard $(dir)/*.lua))
LUAFREF  = $(foreach file,$(LUATUTS),$(REFSRCDIR)/luafaudes/$(basename $(notdir $(file))).fref)
LUAFREF += $(REFSRCDIR)/luafaudes/faudes_luafaudes.fref
LUAFREF += $(REFSRCDIR)/luafaudes/faudes_luatech.fref
LUAFREF += $(REFSRCDIR)/luafaudes/faudes_luaext.fref
LUAHTML  = $(foreach file,$(LUAFREF),$(LUADOCDIR)/$(basename $(notdir $(file))).html)
LUAHTML += $(LUADOCDIR)/index.html

# have luafaudes doc dir: time stamp
$(LUADOCDIR): $(LUADOCDIR)/.tstamp

# have luafaudes doc dir: populate by defaults
$(LUADOCDIR)/.tstamp: 
	- mkdir -p $(LUADOCDIR)
	touch $@

# have luafaudes fref source dir: time stamp
$(REFSRCDIR)/luafaudes: $(REFSRCDIR)/luafaudes/.tstamp $(LUADOCDIR)

# have luafaudes fref source dir: copy tutorials
$(REFSRCDIR)/luafaudes/.tstamp: $(REFSRCDIR) $(LUATUTS) 
	- mkdir -p $(REFSRCDIR)/luafaudes
	@echo copy lua tutorials
	@ - cp -f $(LUATUTS) $(REFSRCDIR)/luafaudes
	touch $@

# process lua code to fref source  (trigger en-block if needed)
$(REFSRCDIR)/luafaudes/%.fref: $(REFSRCDIR)/luafaudes
	$(LUA2REF) $(subst .fref,.lua,$@) > $@

# copy static frefs
$(REFSRCDIR)/luafaudes/faudes_luafaudes.fref: plugins/luabindings/src/doxygen/faudes_luafaudes.fref
	cp -f  $< $@
$(REFSRCDIR)/luafaudes/faudes_luatech.fref: plugins/luabindings/src/doxygen/faudes_luatech.fref
	cp -f  $< $@
$(REFSRCDIR)/luafaudes/faudes_luaext.fref: plugins/luabindings/src/doxygen/faudes_luaext.fref
	cp -f  $< $@

# copy index
$(LUADOCDIR)/index.html: $(LUADOCDIR)/faudes_luafaudes.html
	cp -f  $< $@

# target: make fref source files
doc-luafaudes: $(REFSRCDIR)/luafaudes 
	make $(LUAFREF) 

# if we dont have luabindings
else

# static dummies
LUAFREF  = $(REFSRCDIR)/luafaudes/faudes_luafaudes.fref
LUAFREF += $(REFSRCDIR)/luafaudes/faudes_luatech.fref
LUAFREF += $(REFSRCDIR)/luafaudes/faudes_luaext.fref
LUAHTML  = $(foreach file,$(LUAFREF),$(LUADOCDIR)/$(basename $(notdir $(file))).html)
LUAHTML += $(LUADOCDIR)/index.html

# have luafaudes doc dir: time stamp
$(LUADOCDIR): $(LUADOCDIR)/.tstamp

# have luafaudes doc dir: populate by defaults
$(LUADOCDIR)/.tstamp: 
	- mkdir -p $(LUADOCDIR)
	touch $@

# have luafaudes fref source dir: time stamp
$(REFSRCDIR)/luafaudes: $(REFSRCDIR)/luafaudes/.tstamp $(LUADOCDIR)

# have luafaudes fref source dir: copy tutorials
$(REFSRCDIR)/luafaudes/.tstamp: $(LUATUTS) 
	- mkdir -p $(REFSRCDIR)/luafaudes
	@echo copy tutorial
	@ - cp -f $(LUATUTS) $(REFSRCDIR)/luafaudes
	touch $@

# copy static frefs
$(REFSRCDIR)/luafaudes/faudes_%.fref: $(SRCDIR)/doxygen/faudes_noluafaudes.fref $(REFSRCDIR)/luafaudes  
	cp -f  $< $@

# copy index
$(LUADOCDIR)/index.html: $(LUADOCDIR)/faudes_luafaudes.html
	cp -f  $< $@

# target: copy fref source files
doc-luafaudes: $(REFSRCDIR)/luafaudes 
	make $(LUAFREF) 

# end of luabindings dummy
endif



####################################
# Documentaion: compile frefs
####################################

# note: html is generated by ref2html via flxinstall

# have my tools
$(BINDIR)/flxinstall: $(OBJDIR)/flxinstall.o $(COREOBJECTS) 
	$(LXX) $^ $(LDFLAGS) -o $@

# have my tools
$(BINDIR)/ref2html: $(OBJDIR)/ref2html.o $(COREOBJECTS) 
	$(LXX) $^ $(LDFLAGS) -o $@

# tools target
reftools: $(BINDIR)/ref2html $(BINDIR)/flxinstall


# flxinstall command with luabindings
ifeq (luabindings,$(findstring luabindings,$(FAUDES_PLUGINS)))
FLXFILES = $(wildcard stdflx/*.flx)$
FLXCMD = bin/flxinstall -tcss $(REF2HTML_CSS) -i $(FLXFILES) .
# flxinstall command without luabindings
else
FLXCMD = bin/flxinstall -tcss $(REF2HTML_CSS) -r .
endif

# user target
doc-fref: reftools $(REFSRCDIR)/libfaudes.rti $(REFSRCDIR) $(REFSRCDIR)/images $(BASEFREF) $(LUAFREF) $(RTIFREF)
	$(FLXCMD)



####################################
# Documentation: overall doc target
####################################

doc-clean: 
	- rm -rf $(DOCDIR)
	- mkdir $(DOCDIR)

#convert command
REF2HTMLCMD = ./bin/ref2html -rti $(REFSRCDIR)/libfaudes.rti -css $(REF2HTML_CSS) -cnav $(REFSRCDIR)/faudes_navigation.include_fref -rel ../ -css doxygen.css 

# build doc: run as script
doc: doc-images doc-base doc-luafaudes doc-reference includes 
	- mkdir -p $(DOXDOCDIR)
	$(REF2HTMLCMD) -doxheader $(DOXDOCDIR)/doxygen_header.html
	$(REF2HTMLCMD) -doxfooter $(DOXDOCDIR)/doxygen_footer.html
	@echo running doxygen
	@ ( cat $(SRCDIR)/doxygen/doxygen.conf ; \
              echo "INPUT += $(VPATH)" ; \
	      echo "INCLUDE_PATH += $(INCLUDEDIR)" ; \
              echo "EXAMPLE_PATH += $(VPATH)" ; \
              echo "INCLUDE_PATH += $(SRCDIR)/doxygen" ; \
              echo "PROJECT_NAME = \"libFAUDES $(VERSION)\"" ; \
        ) | $(DOXYGEN) -
	cp $(SRCDIR)/doxygen/doxygen.css $(DOXDOCDIR)
	cat $(SRCDIR)/doxygen/faudes.css >> $(DOXDOCDIR)/doxygen.css	
	@echo processing fref to html
	make doc-fref


####################################
# Library targets
####################################

$(STATIC): $(OBJECTS)
	ar -sr $(STATIC) $^

$(SHARED): $(OBJECTS)
	$(LXX) $(LIBOPTS) $^ $(LDFLAGS) -o $@

####################################
# (Semi-) Automatic generation of dependencies
####################################

# explicit target
depend: $(SOURCES) includes
	touch $(INCLUDEDIR)/rtiautoload.h
	touch $(INCLUDEDIR)/rtiautoload.cpp
	@echo update dependencies
	@ $(CXX) -MM $(CFLAGS) $(DEFINES) $(SOURCES) | sed 's/\(^.*:\)/$(OBJDIR)\/\1/' > $(DEPEND)

# dont do this automatically
$(DEPEND):

####################################
# Implicit default rules 
# Note: no path specified, searches in VPATH
####################################

# .cpp -> .o
$(OBJDIR)/%.o: %.cpp $(HEADERS:%=$(INCLUDEDIR)/%)
	$(CXX) -c $(CFLAGS) $(DEFINES) $< -o $@

# copy headers to faudes include directory
$(INCLUDEDIR)/%.h: %.h
	$(CP) $< $@

####################################
# Executables
####################################

$(BINDIR)/%: $(OBJDIR)/%.o $(STATIC)
	$(LXX) $^ $(LDFLAGS) -o $@


####################################
# Test cases
####################################

# Protocols incl path
PROTODIRS = ./tutorial/data $(patsubst %,%/data,$(pluginstringT))
PROTOCOLS = $(foreach dir,$(PROTODIRS),$(wildcard $(dir)/*.prot)) 

# Formal targets
TESTTARGETS = $(patsubst %,TESTCASE%,$(PROTOCOLS))

# tools
ABSLUAFAUDES = $(CURDIR)/bin/luafaudes
ABSFLXINSTALL = $(CURDIR)/bin/flxinstall

# Conversion functions
FNCT_PROTOCOL = $(patsubst TESTCASE%,%,$(1))
FNCT_LUASCRIPT = $(patsubst %_lua.prot,%.lua,$(notdir $(call FNCT_PROTOCOL,$(1))))
FNCT_CPPBIN = $(patsubst %_cpp.prot,%,$(notdir $(call FNCT_PROTOCOL,$(1))))
FNCT_WORKDIR = $(patsubst %/data/,%,$(dir $(call FNCT_PROTOCOL,$(1))))
FNCT_TMPPROT = $(patsubst %,tmp_%,$(notdir $(call FNCT_PROTOCOL,$(1))))

# platform dependant script (... first experiments ...)
ifneq ($(FAUDES_PLATFORM),gcc_win)
FNCT_RUNCPPBIN = cd $(call FNCT_WORKDIR,$@) ; ./$(call FNCT_CPPBIN,$@) &> /dev/null
FNCT_RUNLUASCRIPT = cd $(call FNCT_WORKDIR,$@) ; $(ABSLUAFAUDES) $(call FNCT_LUASCRIPT,$@) &> /dev/null
FNCT_DIFFPROT = $(DIFF) $(call FNCT_PROTOCOL,$@) $(call FNCT_WORKDIR,$@)/$(call FNCT_TMPPROT,$@)
else
FNCT_RUNCPPBIN = $(subst /,\,cd $(call FNCT_WORKDIR,$(1)) & ./$(call FNCT_CPPBIN,$(1)) > NUL 2>&1 )
FNCT_RUNLUASCRIPT = $(subst /,\,cd $(call FNCT_WORKDIR,$@) & $(ABSLUAFAUDES) $(call FNCT_LUASCRIPT,$@) > NUL 2>&1)
FNCT_DIFFPROT = $(DIFF) $(subst /,\,$(call FNCT_PROTOCOL,$@) $(call FNCT_WORKDIR,$@)/$(call FNCT_TMPPROT,$@))
endif


# validate lua extensions (currently unix only)
ifneq ($(FAUDES_PLATFORM),gcc_win)
TESTTARGETSX = $(patsubst %,TESTCASE%,$(notdir $(wildcard stdflx/*.flx))) 
TESTTARGETS += $(TESTTARGETSX)
endif


# lua test cases
%_lua.prot: 
	@echo running test case $(call FNCT_LUASCRIPT,$@)
	@- $(call FNCT_RUNLUASCRIPT,$@)
	@ $(call FNCT_DIFFPROT,$@)

# cpp test cases
%_cpp.prot: 
	@echo running test case $(call FNCT_CPPBIN,$@)
	@- $(call FNCT_RUNCPPBIN,$@)
	@ $(call FNCT_DIFFPROT,$@)

# have temp dir
tmp_valext: 
	@- mkdir tmp_valext

# validate lua-extension 
TESTCASE%.flx: tmp_valext
	@echo running test case $(patsubst TESTCASE%,%,$@)
	@- rm -rf tmp_valext/data  ; rm -f tmp_valext/*
	@cd tmp_valext; $(ABSFLXINSTALL) -tbin ../bin -t ../stdflx/$(patsubst TESTCASE%,%,$@) . &> /dev/null

# all tests
test: tutorial $(TESTTARGETS) 
	@echo " ============================== " 
	@echo "libFAUDES-make: test cases: done" 
	@echo " ============================== " 


# more test cases: extensions





####################################
# Makefile debugging
####################################

report-platform:
	@echo ostype [$(FAUDES_OSTYPE)]
	@echo platform	[$(FAUDES_PLATFORM)]

report-targets:
	@echo $(TUTORIAL_EXECUTABLES)


### all phony targets
.PHONY : doc rti bin clean dist-clean package configure includes


###############################
# note:
#   $@ = target
#   $^ = prerequisites
#   $< = first prerequisite
###############################
