# /*------------------------------------------------------------\
# |                                                             |
# | Tool   :                   systemcass                       |
# |                                                             |
# | File   :                    Makefile                        |
# |                                                             |
# | Author :                                                    |
# |                                                             |
# | Date    :                  08_07_2004                       |
# |                                                             |
# \------------------------------------------------------------*/
ifndef SYSTEMCASS
$(error SYSTEMCASS is not defined. This variable has to be defined to install \
SystemCASS and to run any system built with.)
endif
#ifndef SOCVIEW
#$(error SOCVIEW is not defined.)
#endif
#################################
#
# SYSTEMC
#
#################################

TARGET_ARCH     =$(shell ./guess_os.sh)
TARGET_OS       =${TARGET_ARCH}
TARGET_PLATFORM =$(shell uname -p)# -i doesn't work on MACOSX
TARGET_KERNEL   =$(shell uname -s | tr '[A-Z]' '[a-z]')

include Options.def

##################################
#### DIRECTORIES
##################################
#CURRENT_DIR           = $(shell pwd)
#SYSTEMCASS_INSTALLDIR = ${CURRENT_DIR}/${TARGET_PLATFORM}-${TARGET_OS}
SYSTEMCASS_INSTALLDIR = ${SYSTEMCASS}
SYSTEMCASS_INCLUDEDIR = ${SYSTEMCASS_INSTALLDIR}/include
SYSTEMCASS_LIBDIR     = ${SYSTEMCASS_INSTALLDIR}/lib
SYSTEMCASS_DOCDIR     = ${SYSTEMCASS_INSTALLDIR}/docs

INSTALLDIR_OK = $(shell (test -d ${SYSTEMCASS_INSTALLDIR}/) ; echo $$?)
ifneq (${INSTALLDIR_OK},0)
$(shell (mkdir ${SYSTEMCASS_INSTALLDIR}/))
endif

INCLUDEDIR_OK = $(shell (test -d ${SYSTEMCASS_INCLUDEDIR}/) ; echo $$?)
ifneq (${INCLUDEDIR_OK},0)
$(shell (mkdir ${SYSTEMCASS_INCLUDEDIR}))
endif

DOCDIR_OK = $(shell (test -d ${SYSTEMCASS_DOCDIR}/) ; echo $$?)
ifneq (${DOCDIR_OK},0)
$(shell (mkdir ${SYSTEMCASS_DOCDIR}))
endif

##################################
#### FLAGS
##################################
#SYSTEMC  = /users/outil/systemc/systemcass/systemcass/latest
#SYSTEMCASS  = $(SYSTEMC)/latest
#ALLIANCE    = /asim/alliance

PROF_ARG     = -pg # gcc
#PROF_ARG     = -qp # icc
OPT         = -O2 -DCFLAGS="\"-O2 \"" $(NETLIST_DEBUGGING) $(SCHEDULING_OPTIONS) $(OTHERS)
DEBUG       = -g  -DCFLAGS="\"-g \"" $(NETLIST_DEBUGGING-d) $(SCHEDULING_OPTIONS-d) $(OTHERS-d) -Wunused -Werror
PROF        = -O2 ${PROF_ARG} -DCFLAGS="\"-O2 ${PROF_ARG} \"" $(NETLIST_DEBUGGING) $(SCHEDULING_OPTIONS) $(OTHERS)

#-Wall disable using icc instead of g++

#CXX         = g++
#CXX         = icc -w1
CFLAGS      = -I./internal_include        \
              -I${SYSTEMCASS_INCLUDEDIR}  \
              -I${ALLIANCE}/include       \
              -ansi                       \
              -pedantic                   \
              -Wno-long-long              \
              -D${TARGET_PLATFORM}        \
              -D${TARGET_KERNEL}          \
              -Wunused-function  # to clean up the code \

#-D${TARGET_ARCH}  # disabled because that macro name gets error messages

LDFLAGS     = -L.                     \
              -L${SYSTEMCASS}/lib-${TARGET_PLATFORM}-${TARGET_OS} \
              -L${ALLIANCE}/lib       \

##################################
## DOCUMENTATION
##################################

FIGURES     = figures/SystemeType.fig \
              figures/Automate.fig

tex_files   = SystemCASS.tex
pdf_files   = $(tex_files:.tex=.pdf)
ps_files    = $(tex_files:.tex=.ps)
eps_figures = $(FIGURES:.fig=.eps)
dvi_files   = $(tex_files:.tex=.dvi)
log_files   = $(tex_files:.tex=.log)
aux_files   = $(tex_files:.tex=.aux)
out_files   = $(tex_files:.tex=.out)
blg_files   = $(tex_files:.tex=.blg)
bbl_files   = $(tex_files:.tex=.bbl)

DOCS        = \
              ${SYSTEMCASS_DOCDIR}/SystemCASS.ps  \
              ${SYSTEMCASS_DOCDIR}/SystemCASS.pdf \
              ${SYSTEMCASS_DOCDIR}/How-to-Use.txt

##################################
## OBJECTS
##################################
OBJECTS     = \
		alias.o \
		bit2string.o \
    dump_dot.o \
    dump_used_env.o \
    dump_used_options.o \
		entity.o   \
    gen_code.o \
    global_functions.o \
		graph.o \
		graph_cass.o \
		graph_signals.o \
		hex2string.o \
    methodprocess_dependency.o \
    module_hierarchy.o \
    module_hierarchy2dot.o \
    mouchard_scheduling.o \
    port_dependency.o \
    process_dependency.o \
    sc_clock.o            \
		sc_event.o \
		sc_event_finder.o \
		sc_interface.o \
		sc_logic.o \
    sc_main.o \
    sc_module.o \
		sc_numrep.o \
		sc_object.o \
		sc_pat_trace.o \
    sc_port.o \
    sc_sensitive.o \
    sc_time.o \
		sc_trace.o \
		sc_uint_subref_r.o \
    sc_vcd_trace.o \
    sc_ver.o \
    schedulers.o \
    serialization.o \
    signal_dependency.o \
    simplify_string.o \


OBJECTS-d   = $(OBJECTS:.o=-d.o)
OBJECTS-prof= $(OBJECTS:.o=-prof.o)

##################################
## LIBRARIES
##################################
SYSTEMCASS_LIB        = ${SYSTEMCASS_LIBDIR}/libsystemc_$(firstword $(CXX)).a
SYSTEMCASS-d_LIB      = ${SYSTEMCASS_LIBDIR}/libsystemc_$(firstword $(CXX))-d.a
SYSTEMCASS-prof_LIB   = ${SYSTEMCASS_LIBDIR}/libsystemc_$(firstword $(CXX))-prof.a

## PAT trace output is enable when ALLIANCE is defined
EXT_TMP_DIR = $(if ${ALLIANCE}, \
              libPgn.temp       \
              libMut.temp       \
              libPpt.temp       \
              libPat.temp       \
              )

EXT_OBJ     = $(EXT_TMP_DIR:.temp=.temp/*.o)

##################################
## SOURCES
##################################
LINKS       = $(OBJECTS-d:.o=.cc) $(OBJECTS-prof:.o=.cc)

EXTERNAL_INCLUDES = \
              ${SYSTEMCASS_INCLUDEDIR}/systemc \
              ${SYSTEMCASS_INCLUDEDIR}/systemc.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_fwd.h\
              ${SYSTEMCASS_INCLUDEDIR}/global_functions.h \
              ${SYSTEMCASS_INCLUDEDIR}/serialization_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_time.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_nbdefs.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_ver_ext.h\
              ${SYSTEMCASS_INCLUDEDIR}/systemcass_version_ext.h\
              ${SYSTEMCASS_INCLUDEDIR}/sc_module_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/module_hierarchy_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_module_name.h \
              ${SYSTEMCASS_INCLUDEDIR}/internal_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/casc.h \
              ${SYSTEMCASS_INCLUDEDIR}/fsm_rules.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_object.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_sensitive.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_event.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_interface.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_port_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_event_finder.h \
              ${SYSTEMCASS_INCLUDEDIR}/port_dependency_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_signal.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_clock_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_unit.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_bit.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_logic.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_bv.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_unsigned.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_signed.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_uint.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_numrep.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_string.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_int.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_lv.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_biguint.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_bigint.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_trace_ext.h \
              ${SYSTEMCASS_INCLUDEDIR}/alias.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_localvar.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_vcd_trace.h \
              ${SYSTEMCASS_INCLUDEDIR}/sc_pat_trace.h \
              ${SYSTEMCASS_INCLUDEDIR}/endianness.h \
              ${SYSTEMCASS_INCLUDEDIR}/data_field.h \

##################################
## RULES  
##################################
.SECONDARY:
.PHONY: help figures debug opt prof docs path all clean realclean

##########
#### RULES
help :
	@echo "rules         Description"
	@echo "---------     ------------------------------"
	@echo "debug         Create debug library"
	@echo "opt           Create optimized library"
	@echo "prof          Create a library for profiling"
	@echo "docs          Create PDF documentation"
	@echo "path          Print the path to libraries, documentation..."
	@echo "all           Create all the libraries and documentation files"
	@echo "clean         Delete temporary files"
	@echo "realclean     Delete libraries,  documentation files and temporary files."

#@echo "nolib         Compile only source files and don't generate any library" => this rules is not possible because we need to overwrite external includes

path :
	@echo "debug library : ${SYSTEMCASS_LIB}"
	@echo "optimized library : ${SYSTEMCASS-d_LIB}"
	@echo "profiling library : ${SYSTEMCASS-prof_LIB}"
	@echo "PDF documentation : ${SYSTEMCASS_DOCDIR}"

all : debug opt prof
	@echo Type make docs

opt : ${EXTERNAL_INCLUDES} systemcass

debug : ${EXTERNAL_INCLUDES} systemcass-d

prof : ${EXTERNAL_INCLUDES} systemcass-prof

cvs : recent_changes
	gvim recent_changes &
	cvs ci

mark :
	make clean	
	echo -n '#define SYSTEMC_VERSION "SystemCASS : ' > systemcass_version_ext.h
	date | head -c 28 >> systemcass_version_ext.h
	echo '"' >> systemcass_version_ext.h

recent_changes : ${SYSTEMCASS_LIB} ${SYSTEMCASS-d_LIB} mark
	-cvs diff > recent_changes

docs : ${DOCS}

includes : ${EXTERNAL_INCLUDES}

###########################
#### EXPORTING FILES
${SYSTEMCASS_INCLUDEDIR}/%.h: %.h
	cp $*.h ${SYSTEMCASS_INCLUDEDIR}/$*.h

${SYSTEMCASS_INCLUDEDIR}/systemc: systemc
	cp $< $@

${SYSTEMCASS_DOCDIR}/%.pdf: %.pdf
	cp $*.pdf ${SYSTEMCASS_DOCDIR}/$*.pdf

${SYSTEMCASS_DOCDIR}/%.ps: %.ps
	cp $*.ps ${SYSTEMCASS_DOCDIR}/$*.ps

${SYSTEMCASS_DOCDIR}/%.txt: %.txt
	cp $*.txt ${SYSTEMCASS_DOCDIR}/$*.txt

########################
#### COMPILING & LINKING
systemcass: ${SYSTEMCASS_LIB}

systemcass-d: ${SYSTEMCASS-d_LIB}

systemcass-prof: ${SYSTEMCASS-prof_LIB}

${SYSTEMCASS_LIB} : $(OBJECTS) ${EXT_OBJ}
	mkdir -p ${SYSTEMCASS_LIBDIR}
	ar -rv ${SYSTEMCASS_LIB} $(OBJECTS) $(EXT_OBJ)
	ranlib ${SYSTEMCASS_LIB}

${SYSTEMCASS-d_LIB}: $(OBJECTS-d) ${EXT_OBJ}
	mkdir -p ${SYSTEMCASS_LIBDIR}
	ar -rv ${SYSTEMCASS-d_LIB} $(OBJECTS-d) $(EXT_OBJ)
	ranlib ${SYSTEMCASS-d_LIB}

${SYSTEMCASS-prof_LIB}: $(OBJECTS-prof) ${EXT_OBJ}
	mkdir -p ${SYSTEMCASS_LIBDIR}
	ar -rv ${SYSTEMCASS-prof_LIB} $(OBJECTS-prof) $(EXT_OBJ)
	ranlib ${SYSTEMCASS-prof_LIB}

%-d.cc : %.cc
	ln -s $*.cc $*-d.cc

%-prof.cc : %.cc
	ln -s $*.cc $*-prof.cc

%-d.o : %-d.cc
	$(CXX) $(CFLAGS) -MM $*-d.cc >> Makefile.deps
	$(CXX) $(CFLAGS) $(DEBUG) -c $< -o $@

%-prof.o : %-prof.cc
	$(CXX) $(CFLAGS) -MM $*-prof.cc >> Makefile.deps
	$(CXX) $(CFLAGS) $(PROF) -c $< -o $@

%.o : %.cc 
	$(CXX) $(CFLAGS) -MM $*.cc >> Makefile.deps
	$(CXX) $(CFLAGS) $(OPT) -c $< -o $@

lib%.temp/*.o : ${ALLIANCE}/lib/lib%.a
	(mkdir lib$*.temp ; cd lib$*.temp ; ar -x ${ALLIANCE}/lib/lib$*.a)

guess_endianness.x : guess_endianness.cc
	${CXX} -o guess_endianness.x guess_endianness.cc

${SYSTEMCASS_INCLUDEDIR}/endianness.h : guess_endianness.x
	./guess_endianness.x > ${SYSTEMCASS_INCLUDEDIR}/endianness.h

-include Makefile.deps

##################
#### DOCUMENTATION
%.dvi : %.tex

%.pdf : %.ps
	ps2pdf $*.ps	

%.ps: %.dvi
	dvips -o $*.ps $*.dvi                                                                                
%.dvi %.bbl : %.tex %.bib $(eps_figures)
	latex $*.tex
	bibtex $*
	latex $*.tex
	latex $*.tex

figures : $(eps_figures)
	@echo OK

%.eps : %.fig
	fig2dev -L eps $*.fig $*.eps

##################
#### CLEANING
clean :
	rm -f Makefile.deps
	rm -f *~
	rm -f $(OBJECTS)
	rm -f $(OBJECTS-d)
	rm -f $(OBJECTS-prof)
	rm -rf $(EXT_TMP_DIR)
	-for i in $(LINKS) ; do unlink $$i ; done 2> /dev/null
	rm -f $(eps_figures)
	rm -f $(dvi_files) $(log_files) 
	rm -f $(out_files) $(aux_files) $(blg_files) $(bbl_files)
	rm -f $(pdf_files) $(ps_files)

realclean: clean
	rm -f ${EXTERNAL_INCLUDES}
	rm -rf ${SYSTEMCASS_LIBDIR}
	rm -f ${SYSTEMCASS_LIB} ${SYSTEMCASS-d_LIB} ${SYSTEMCASS-prof_LIB}
	rm -f guess_endianness.x
	#rm -f $(DOCS) # DONT do it. ${DOCS} includes txt files...
