#
#  Makefile for SIMLIB
#  ===================
#
#  Target: Linux/GNU C++ (GCC > 3.0)
#  Make:   make (GNU make)
#
################################################################################
# How to install pure SimLib:
# edit Makefile to suit it to your system
# type "make clean" to remove binaries created by compiler
# type "make" or "make all" to compile sources
# type "make install" to install library 
#       variable PREFIX contains where (default: /usr/local)
#       installs files in subdirectories: bin, include, lib
# then you may type "make test" to check if all is OK
# type "make pack" to create archive SIMLIB*.tar.gz
################################################################################
# How to install SimLib with Fuzzy module:
# type "make MODULES="fuzzy" clean" to remove binaries created by compiler
# type 'make MODULES="fuzzy"' to compile sources
# type 'make MODULES="fuzzy" install' to install library (WARNING: this 
#          experimental Makefile installs into parent directory .. )
# then you may type "make MODULES="fuzzy" test" to check if all is OK
# type "make MODULES="fuzzy" pack" to create archive SIMLIB*.tar.gz
################################################################################
# How to install SimLib with XML analyzer module:
# First you must have library Xerces1.4 installed.
# You can find it on http://xml.apache.org/xerces-c/
#
# type "make MODULES="fuzzy analyzer" clean" to remove binaries created by compiler
# type 'make MODULES="fuzzy analyzer"' to compile sources
# type 'make MODULES="fuzzy analyzer" install' to install library (WARNING: this 
#          experimental Makefile installs into parent directory .. )
# then you may type "make MODULES="fuzzy analyzer" test" to check if all is OK
# type "make MODULES="fuzzy analyzer" pack" to create archive SIMLIB*.tar.gz
#############################################################################
# If you have Doxygen installed on your system, you may type
# 'make doc'
# or
# 'make MODULES="fuzzy" doc'
#
#############################################################################
#####  Definitions  #####
#############################################################################

.PHONY: all install uninstall clean distclean test

# to avoid troubles
SHELL=/bin/sh

# to add modules
MODULES=

# the name of the library
LIBNAME=simlib

# name of the compiler for C and C++ language
CC=gcc
CXX=g++ -Wall -std=c++98
#CXX=g++ -m32
#CXX=g++-3.4

# C++ compiler flags -- for development
#CXXFLAGS=-g -fPIC -O2 -Wall -Weffc++	# with debug info
CXXFLAGS=-g -fPIC -O2 -Wall         	# with debug info
#CXXFLAGS=-pg -fPIC -O2			# with profile support
# C++ compiler flags -- for PRODUCTION
#CXXFLAGS=-O2 -fPIC -Wall -Weffc++	# PRODUCTION CODE

# installing program
INSTALL=install -m0644
INSTALL_EXE=install -m0655

# directory where the files will be installed in
PREFIX=/usr/local

# program to remove files
RM=rm -f

# program providing a simple test of installed library functionality
TESTFILE=_test_

# archive file name (without extension)
ARCHIVE=SIMLIB

# files to pack into archive
ARCHIVE_FILES = README COPYING *.c *.doc *.txt \
                *.cc *.h dep.list Makefile.* *.config _test_.output--  \
                [a-z]*/*.cc [a-z]*/*.h [a-z]*/Makefile* \
                [a-z]*/*.txt [a-z]*/*.config [a-z]*/*.tar.gz\
		examples/reference-outputs examples/*.plt

# headers for dependencies
HEADERS = simlib.h errors.h internal.h

# headers for install
# TODO: merge delay.h zdelay.h optimize.h into simlib.h
SIMLIB_HEADERS = simlib.h \
                 delay.h zdelay.h \
                 simlib2D.h simlib3D.h \
                 optimize.h 

#############################################################################
# binaries which will be in the library
#############################################################################
BASEOBJFILES = atexit.o \
	calendar.o debug.o \
	entity.o error.o errors.o event.o \
	link.o list.o name.o \
	object.o \
	print.o run.o \
	sampler.o 

CONTIOBJFILES = delay.o zdelay.o simlib2D.o simlib3D.o\
	algloop.o cond.o \
	fun.o graph.o \
	intg.o continuous.o ni_abm4.o ni_euler.o \
	ni_fw.o ni_rke.o ni_rkf3.o ni_rkf5.o ni_rkf8.o numint.o \
	output1.o \
	stdblock.o 

DISCOBJFILES = \
	barrier.o \
	facility.o \
	histo.o \
	\
	output2.o process.o queue.o random1.o random2.o \
	semaphor.o stat.o store.o tstat.o waitunti.o

OPTOBJFILES = opt-hooke.o opt-simann.o opt-param.o

OBJFILES = $(BASEOBJFILES)  \
           $(CONTIOBJFILES) \
           $(OPTOBJFILES)   \
           $(DISCOBJFILES)

SIMLIBOBJFILES =  $(BASEOBJFILES)  \
           $(CONTIOBJFILES) \
           $(OPTOBJFILES)   \
           $(DISCOBJFILES)

#############################################################################
# Implicit Rule to compile modules
#############################################################################
%.o : %.cc
	$(CXX) $(CXXFLAGS) -c $<

#############################################################################
###  Create library
#############################################################################
WITHMODULES=$(SIMLIBOBJFILES)
SIMLIB_DOC=simlibdoc
ifeq (fuzzy, $(findstring fuzzy, $(MODULES)))
OBJFILES+=fuzzy/fuzzy.o fuzzy/fuzzyio.o fuzzy/fuzzymf.o fuzzy/fuzzyrul.o fuzzy/ruletree.o fuzzy/rules.o 
WITHMODULES+=fuzzymodule
SIMLIB_HEADERS+=fuzzy/fuzzy.h
ARCHIVE_FILES+=fuzzy/*.h fuzzy/*.cc fuzzy/Makefile fuzzy/*.config examples/*
SIMLIB_DOC+=fuzzydoc
endif

ifeq (analyzer, $(findstring analyzer, $(MODULES)))
OBJFILES+=analyzer/fuzzyanalyzer.o
WITHMODULES+=analyzermodule
SIMLIB_HEADERS+=analyzer/analyzer.h analyzer/fuzzyanalyzer.h
ARCHIVE_FILES+=analyzer/*.h analyzer/*.cc analyzer/Makefile
endif

#############################################################################
### main rule
#############################################################################
withmodules: $(WITHMODULES) all

all: $(LIBNAME).a  $(LIBNAME).so
special: $(LIBNAME)-c.a  $(LIBNAME)-c.so # $(LIBNAME)-d.a  $(LIBNAME)-d.so 

fuzzymodule:
	$(MAKE) -C fuzzy

fuzzydoc:
	$(MAKE) -C fuzzy doc

analyzermodule:
	$(MAKE) -C analyzer

#############################################################################
### rule for static library
#############################################################################

$(LIBNAME).a: $(OBJFILES) 
	$(RM) $(LIBNAME).a  # create new library
	ar rcv $(LIBNAME).a $(OBJFILES)
	ranlib $(LIBNAME).a
	nm --demangle $(LIBNAME).a > $(LIBNAME).nm

# continuous subset only
$(LIBNAME)-c.a: $(BASEOBJFILES) $(CONTIOBJFILES) 
	$(RM) $(LIBNAME)-c.a  # create new library
	ar rcv $(LIBNAME)-c.a $(BASEOBJFILES) $(CONTIOBJFILES)
	ranlib $(LIBNAME)-c.a
	nm --demangle $(LIBNAME)-c.a > $(LIBNAME)-c.nm

# discrete subset only
$(LIBNAME)-d.a: $(BASEOBJFILES) $(DISCOBJFILES) 
	$(RM) $(LIBNAME)-d.a  # create new library
	ar rcv $(LIBNAME)-d.a $(BASEOBJFILES) $(DISCOBJFILES)
	ranlib $(LIBNAME)-d.a
	nm --demangle $(LIBNAME)-d.a > $(LIBNAME)-d.nm

#############################################################################
##### rule for dynamic library
#############################################################################

$(LIBNAME).so: $(OBJFILES)
	$(CXX) -shared -fPIC $(OBJFILES) -o $(LIBNAME).so

# continuous subset only
$(LIBNAME)-c.so: $(BASEOBJFILES) $(CONTIOBJFILES)
	$(CXX) -shared -fPIC $(BASEOBJFILES) $(CONTIOBJFILES) -o $(LIBNAME)-c.so

# discrete subset only
$(LIBNAME)-d.so: $(BASEOBJFILES) $(DISCOBJFILES)
	$(CXX) -shared -fPIC $(BASEOBJFILES) $(DISCOBJFILES) -o $(LIBNAME)-d.so

#############################################################################
##### create error messages file
#############################################################################

generr: generr.c

errors.h errors.cc: generr errors.doc
	./generr errors.doc

#############################################################################
##### library modules - dependencies
#############################################################################

dep: errors.h
	$(CXX) -MM *.cc >dep.list

-include dep.list

#############################################################################
#####  Make documentation
#############################################################################

doc: $(SIMLIB_DOC)

simlibdoc:
	doxygen doxygen.config

#############################################################################
#####  Remove garbage from directory 
#############################################################################

# files to remove after compiling & install
GARBAGE=$(OBJFILES) *~ $(LIBNAME)*.a $(LIBNAME)*.nm $(LIBNAME)*.so \
	generr errors.h errors.cc $(TESTFILE) $(TESTFILE).output

clean:
	$(RM) $(GARBAGE)
	(cd examples; make clean-all)

#############################################################################
#####  Install library
#############################################################################

#TODO: add version and symlink
install: all
	@echo "You should have permissions to install in " $(PREFIX)/
	$(INSTALL) $(SIMLIB_HEADERS) $(PREFIX)/include
	$(INSTALL) $(LIBNAME).a $(PREFIX)/lib/lib$(LIBNAME).a
	$(INSTALL_EXE) $(LIBNAME).so $(PREFIX)/lib/lib$(LIBNAME).so
	$(INSTALL_EXE) scripts/SIMLIB-inst.txt $(PREFIX)/bin/SIMLIB

#############################################################################
#####  Uninstall library
#############################################################################

uninstall:
	@echo "You should have permissions to " $(PREFIX)/
	$(RM) $(foreach headerfile, $(SIMLIB_HEADERS), $(PREFIX)/include/$(headerfile))
	$(RM) $(PREFIX)/lib/lib$(LIBNAME).a
	$(RM) $(PREFIX)/lib/lib$(LIBNAME).so
	$(RM) $(PREFIX)/bin/SIMLIB

#############################################################################
#####  Make basic test of library
#############################################################################

test: all
	$(CXX) $(CXXFLAGS) -g -Wall  -o $(TESTFILE) $(TESTFILE).cc -lm simlib.a
	./$(TESTFILE) >$(TESTFILE).output
	rm ./$(TESTFILE)
	-diff $(TESTFILE).output-- $(TESTFILE).output
	@echo "Addresses can be different"
	echo `date` "by" `$(CXX) --version` >>TEST-BY.txt

#############################################################################
VERSION: simlib.h
	grep '// SIMLIB version: ' simlib.h | tr -dc '0-9.' >VERSION

#############################################################################
#####  Make archive
#############################################################################

pack: VERSION 
	(cd doc; make pack)
	cp Makefile Makefile.`uname`
	tar czvf $(ARCHIVE).tar.gz $(ARCHIVE_FILES)
	cp $(ARCHIVE).tar.gz "../BACKUP/$(ARCHIVE)-`cat VERSION`-`date +%Y%m%d`.tar.gz"

# end of Makefile  


syntax highlighted by Code2HTML, v. 0.9.1