### Modular Reachability Analyzer -*- makefile -*-

### User-configurable section begins

# Installation directory prefix for Debian GNU/Linux
DESTDIR =
# Generic installation directory prefix
PREFIX = /usr

# Where to find GraphViz lefty?
LEFTYBIN = $(PREFIX)/bin/lefty
# Where to put binaries on 'make install'?
BINDIR = $(PREFIX)/bin
# Where to put architecture-independent runtime files on 'make install'?
RTDIR = $(PREFIX)/share/maria/runtime
# Where to put architecture-independent example files on 'make install'?
EXDIR = $(PREFIX)/share/maria/examples
# Where to put on-line documentation on 'make installinfo'?
INFODIR = $(PREFIX)/share/info
# Where to put manual pages on 'make installman'?
MANDIR = $(PREFIX)/share/man/man1

## Extra definitions
### use mmap(2) if available, to optimise performance
EXTRA_DEFINES = -DUSE_MMAP
### emulate mmap(2) with malloc(3) to obtain reliable memory usage statistics
#EXTRA_DEFINES := $(EXTRA_DEFINES) -DUSE_MMAP -DNO_MMAP
### in modular analysis, enable the caching of local successor states
#EXTRA_DEFINES := $(EXTRA_DEFINES) -DSYNC_CACHE
### in modular analysis, enable the caching of pre-synchronisation states
#EXTRA_DEFINES := $(EXTRA_DEFINES) -DADD_CACHE

## Debugging
### -DNDEBUG omits assert(3) macros
### -DYYDEBUG enables grammar debugging if DEBUG=1 (see parser/maria.C)
### -g includes debugging symbols in the objects and the executable
DEBUG = -DNDEBUG
#DEBUG = -g # -DYYDEBUG
## Profiling
#PROF = -pg
PROF =

### Installation commands
INSTALLDIR = install -d
INSTALLBIN = install -c
INSTALLDATA = install -c -m 444
RM = rm -f

### User-configurable section ends

LTL_INCLUDES = $(BUILTIN_LTL:yes=-IAutomata/Ltl)
LTL_DEFINES = $(BUILTIN_LTL:yes=-DBUILTIN_LTL)

COMP_INCLUDES = $(EXPR_COMPILE:yes=-ICompilation/base)
COMP_DEFINES = $(EXPR_COMPILE:yes=-DEXPR_COMPILE)

CPPFLAGS = $(EXTRA_INCLUDES) $(INCLUDES) $(LTL_INCLUDES) $(COMP_INCLUDES) \
	$(DEFINES) $(EXTRA_DEFINES) $(LTL_DEFINES) $(COMP_DEFINES) $(DEBUG)

LEX=flex
LFLAGS=-o$@
YACC=bison
YFLAGS=-d

TARGET = maria

COMMONSRCS = \
	parser/util.C \
	parser/StringBuffer.C \
	parser/VariableStackMap.C \
	parser/Printer.C \
	parser/NameList.C

AUTSRCS = \
	Automata/Property.C \
	Automata/PropertyState.C \
	Automata/BitVector.C \
	Automata/SetList.C \
	Automata/Product.C

GRAPHSRCS = \
	Graph/Graph.C \
	Graph/ComponentGraph.C \
	Graph/Search.C \
	Graph/BitBuffer.C \
	Graph/ByteBuffer.C \
	Graph/BTree.C \
	Graph/States.C \
	Graph/StateReporter.C \
	Graph/StateSetReporter.C \
	Graph/GraphReporter.C \
	Graph/DummyReporter.C \
	Graph/SyncStates.C \
	Graph/StateSet.C \
	Graph/FullSet.C \
	Graph/ParSet.C \
	Graph/CompactSet.C \
	Graph/HashGraph.C \
	Graph/StateList.C \
	Graph/LSTS.C

EXPRSRCS = \
	Expression/Function.C \
	Expression/Substitution.C \
	Expression/ExpressionList.C \
	Expression/ExpressionSet.C \
	Expression/ExpressionMSet.C \
	Expression/Expression.C \
	Expression/Typecast.C \
	Expression/Variable.C \
	Expression/Constant.C \
	Expression/Undefined.C \
	Expression/StructExpression.C \
	Expression/StructComponent.C \
	Expression/StructAssign.C \
	Expression/UnionExpression.C \
	Expression/UnionComponent.C \
	Expression/UnionTypeExpression.C \
	Expression/VectorExpression.C \
	Expression/VectorIndex.C \
	Expression/VectorAssign.C \
	Expression/VectorShift.C \
	Expression/UnopExpression.C \
	Expression/BinopExpression.C \
	Expression/BufferExpression.C \
	Expression/BufferWrite.C \
	Expression/BufferUnop.C \
	Expression/BufferRemove.C \
	Expression/BufferIndex.C \
	Expression/IfThenElse.C \
	Expression/BooleanBinop.C \
	Expression/NotExpression.C \
	Expression/RelopExpression.C \
	Expression/SetExpression.C \
	Expression/TemporalUnop.C \
	Expression/TemporalBinop.C \
	Expression/CardinalityExpression.C \
	Expression/TransitionQualifier.C \
	Expression/PlaceContents.C \
	Expression/Submarking.C \
	Expression/Mapping.C \
	Expression/EmptySet.C \
	Expression/Quantifier.C \
	Expression/Marking.C \
	Expression/Token.C \
	Expression/VariableSet.C

NETSRCS = \
	Net/LNet.C \
	Net/Net.C \
	Net/Place.C \
	Net/Transition.C \
	Net/Arc.C \
	Net/PlaceMarking.C \
	Net/GlobalMarking.C \
	Net/VariableDefinition.C

TYPESRCS = \
	Type/Type.C \
	Type/IntType.C \
	Type/CardType.C \
	Type/BoolType.C \
	Type/CharType.C \
	Type/EnumType.C \
	Type/IdType.C \
	Type/StructType.C \
	Type/UnionType.C \
	Type/VectorType.C \
	Type/BufferType.C \
	Type/ComponentList.C \
	Type/Range.C \
	Type/Constraint.C

VALUESRCS = \
	Value/Value.C \
	Value/ValueList.C \
	Value/LeafValue.C \
	Value/StructValue.C \
	Value/UnionValue.C \
	Value/VectorValue.C \
	Value/BufferValue.C \
	Value/Valuation.C

LTLSRCS = \
	Automata/Ltl/Ltl.C \
	Automata/Ltl/LtlGraph.C \
	Automata/Ltl/LtlBitVector.C
LTLOPTSRCS = \
	$(BUILTIN_LTL:yes=Automata/Ltl/Ltl.C) \
	$(BUILTIN_LTL:yes=Automata/Ltl/LtlGraph.C) \
	$(BUILTIN_LTL:yes=Automata/Ltl/LtlBitVector.C)

COMPSRCS = \
	Compilation/base/CExpression.C \
	Compilation/base/Compilation.C
COMPOPTSRCS = \
	$(EXPR_COMPILE:yes=Compilation/base/CExpression.C) \
	$(EXPR_COMPILE:yes=Compilation/base/Compilation.C)

PARSERSRCS = \
	parser/maria.tab.C parser/lex.pn.C \
	parser/marde.tab.C parser/lex.de.C
PARSERHDRS = \
	parser/maria.tab.h parser/marde.tab.h

AUX = $(PARSERSRCS) $(PARSERHDRS)

CSRCS = parser/cmdline.c
CORESRCS = $(COMMONSRCS) $(EXPRSRCS) $(NETSRCS) $(TYPESRCS) $(VALUESRCS) \
	 $(GRAPHSRCS) $(AUTSRCS) $(LTLOPTSRCS) $(COMPOPTSRCS)
CXXSRCS = $(CORESRCS) parser/maria.C parser/server.C parser/Dotty.C

SRCS = $(CXXSRCS) $(PARSERSRCS) $(CSRCS)
OBJS = $(CXXSRCS:.C=.o) $(PARSERSRCS:.C=.o) $(CSRCS:.c=.o)
LIBS = $(EXTRA_LIBS) $(LIBREADLINE)

INCLUDES = -Iparser -IExpression -INet -IType -IValue \
	-IGraph -IAutomata $(INCREADLINE)

INFO = doc/maria.info
MANPAGES = maria.1 maria-cso.1 maria-vis.1

error:
	@echo "Type 'make -f Makefile.`uname`' to compile Maria"; exit 1

real-all: $(TARGET)

clean:
	$(RM) $(OBJS) $(LTLSRCS:.C=.o) $(COMPSRCS:.C=.o)

reallyclean: clean
	$(RM) $(TARGET) $(AUX) $(INFO)

install: $(TARGET)
	$(INSTALLDIR) $(DESTDIR)$(BINDIR)
	$(INSTALLDIR) $(DESTDIR)$(RTDIR)
	$(INSTALLDIR) $(DESTDIR)$(EXDIR)
	$(INSTALLBIN) maria $(DESTDIR)$(BINDIR)
	$(INSTALLBIN) maria-vis $(DESTDIR)$(BINDIR)
	$(INSTALLBIN) maria-cso $(DESTDIR)$(BINDIR)
	sed -e 's:^#!/.*/lefty$$:#!$(LEFTYBIN):' maria-vis > $(DESTDIR)$(BINDIR)/maria-vis
	sed -e 's:^ *INCLUDES=.*:INCLUDES="-I$(RTDIR)":' maria-cso > $(DESTDIR)$(BINDIR)/maria-cso
	for i in Compilation/runtime/*.h; do $(INSTALLDATA) "$$i" $(DESTDIR)$(RTDIR); done
	for i in parser/test/*.pn; do $(INSTALLDATA) "$$i" $(DESTDIR)$(EXDIR); done

installinfo: $(INFO)
	$(INSTALLDIR) $(DESTDIR)$(INFODIR)
	$(INSTALLDATA) $(INFO) $(DESTDIR)$(INFODIR)

installman: $(MANPAGES)
	$(INSTALLDIR) $(DESTDIR)$(MANDIR)
	for i in $(MANPAGES); do $(INSTALLDATA) "$$i" $(DESTDIR)$(MANDIR); done

info: $(INFO)

depend:
	touch $@ && makedepend -f$@ -Y $(CPPFLAGS) $(SRCS) 2> /dev/null

$(TARGET): $(OBJS)
	$(CXX) $(LDFLAGS) $(PROF) -o $@ $(OBJS) $(LIBS)

parser/maria.tab.C parser/maria.tab.h: parser/maria.y
	(cd parser && $(YACC) $(YFLAGS) -p pn maria.y)
	mv parser/maria.tab.c parser/maria.tab.C

parser/marde.tab.C parser/marde.tab.h: parser/marde.y
	(cd parser && $(YACC) $(YFLAGS) -p de marde.y)
	mv parser/marde.tab.c parser/marde.tab.C

parser/lex.pn.C: parser/maria.lex parser/maria.tab.h
	$(LEX) $(LFLAGS) parser/maria.lex

parser/lex.de.C: parser/marde.lex parser/marde.tab.h
	$(LEX) $(LFLAGS) parser/marde.lex

.phony: all clean reallyclean install installinfo installman info

.SUFFIXES:
.SUFFIXES: .o .c .C .info .texinfo

.c.o:
	$(CC) $(CPPFLAGS) $(PROF) $(CFLAGS) -c $< -o $@
.C.o:
	$(CXX) $(CPPFLAGS) $(PROF) $(CXXFLAGS) -c $< -o $@
.texinfo.info:
	makeinfo --no-split $< -o $@

include depend
