#
#    This source code is free software; you can redistribute it
#    and/or modify it in source code form under the terms of the GNU
#    Library General Public License as published by the Free Software
#    Foundation; either version 2 of the License, or (at your option)
#    any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Library General Public License for more details.
#
#    You should have received a copy of the GNU Library General Public
#    License along with this program; if not, write to the Free
#    Software Foundation, Inc.,
#    59 Temple Place - Suite 330
#    Boston, MA 02111-1307, USA
#
SHELL = /bin/sh

# The interesting make targets are:
#
#   make version
#      Force the version_tag.h file to be rebuilt. Otherwise, it will only
#      be built if it is missing.
#
#   make all
#   make install
#
# The "suffix" is used as an installation suffix. It modifies certain
# key install paths/files such that a build and install of Icarus Verilog
# with the same $(prefix) but a different $(suffix) will not interfere.
# The normal configuration leaves suffix empty
suffix = @install_suffix@

prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
datarootdir = @datarootdir@

SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
          tgt-vhdl driver
# Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog

ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
NOTUSED += driver-vpi
endif

# To get the version headers to build correctly we only want to look
# for C++ files in the source directory. All other files will require
# an explicit $(srcdir). The one exception to this is if we need to
# rebuild the lexor_keyword.cc file. If we do, then we want to use the
# local version instead of the one is $(srcdir).
vpath lexor_keyword.cc .
vpath %.cc $(srcdir)

bindir = @bindir@
libdir = @libdir@
# This is actually the directory where we install our own header files.
# It is a little different from the generic includedir.
includedir = @includedir@/iverilog$(suffix)
mandir = @mandir@

dllib=@DLLIB@

CC = @CC@
HOSTCC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
LEX = @LEX@
YACC = @YACC@
MAN = @MAN@
PS2PDF = @PS2PDF@
GIT = @GIT@

CPPFLAGS = @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@

all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
	$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true

# In the windows world, the installer will need a dosify program to
# dosify text files.
ifeq (@MINGW32@,yes)
all: dep dosify.exe
dosify.exe: $(srcdir)/dosify.c
	$(CC) -o dosify.exe $(srcdir)/dosify.c
endif

# This rule rules the compiler in the trivial hello.vl program to make
# sure the basics were compiled properly.
check: all
	$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
	test -r check.conf || cp $(srcdir)/check.conf .
	driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
ifeq (@WIN32@,yes)
ifeq (@install_suffix@,)
	vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
else
	# On Windows if we have a suffix we must run the vvp part of
	# the test with a suffix since it was built/linked that way.
	ln vvp/vvp.exe vvp/vvp$(suffix).exe
	vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
	rm vvp/vvp$(suffix).exe
endif
else
	vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
endif

clean:
	$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
	rm -f *.o parse.cc parse.h lexor.cc
	rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps parse.output
	rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
	rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
	rm -rf dep
	rm -f version.exe

distclean: clean
	$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
	$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
	rm -f Makefile config.status config.log config.cache
	rm -f stamp-config-h config.h
	rm -f stamp-_pli_types-h _pli_types.h
ifneq (@srcdir@,.)
	rm -f version_tag.h check.conf
	rmdir $(SUBDIRS) $(NOTUSED)
endif
	rm -rf autom4te.cache

TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o

O = main.o async.o design_dump.o discipline.o dup_expr.o \
elaborate.o elab_expr.o elaborate_analog.o \
elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \
elab_sig.o elab_sig_analog.o emit.o eval.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_analog.o net_assign.o \
net_design.o net_event.o net_expr.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_tran.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_analog.o pform_disciplines.o \
pform_dump.o pform_types.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o PGenerate.o PScope.o PSpec.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o AStatement.o StringHeap.o \
$(FF) $(TT)

Makefile: $(srcdir)/Makefile.in config.status
	./config.status --file=$@

stamp-config-h: $(srcdir)/config.h.in config.status
	@rm -f $@
	./config.status config.h
config.h: stamp-config-h

stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
	@rm -f $@
	./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h

$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
	cd $(srcdir) && autoconf

config.status: $(srcdir)/configure
	./config.status --recheck
	./config.status

ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
# The first step makes an ivl.exe that dlltool can use to make an
# export and import library, and the last link makes a, ivl.exe
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O $(srcdir)/ivl.def
	$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
	dlltool --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
		--output-lib libivl.a --output-exp ivl.exp
	$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
	$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif

ifeq (@MINGW32@,no)
all: dep iverilog-vpi

iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
	sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
	    -e 's;@SUFFIX@;$(suffix);' \
	    -e 's;@IVCC@;$(CC);' \
	    -e 's;@IVCXX@;$(CXX);' \
	    -e 's;@IVCFLAGS@;$(CXXFLAGS);' \
	    -e 's;@INCLUDEDIR@;$(includedir);' \
	    -e 's;@LIBDIR@;@libdir@;' $< > $@
	chmod +x $@
endif

version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
	$(HOSTCC) @WARNING_FLAGS@ -o version.exe -I. -I$(srcdir) $(srcdir)/version.c

dep:
	mkdir dep

%.o: %.cc config.h
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
	mv $*.d dep/$*.d

# Here are some explicit dependencies needed to get things going.
main.o: main.cc version_tag.h

lexor.o: lexor.cc parse.h

parse.o: parse.cc

parse.cc parse.h: $(srcdir)/parse.y
	$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
	mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h

syn-rules.cc: $(srcdir)/syn-rules.y
	$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y

lexor.cc: $(srcdir)/lexor.lex
	$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex

lexor_keyword.o: lexor_keyword.cc parse.h

lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
	gperf -o -i 7 -C -k 1-4,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)

iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
	./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
	tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@

iverilog-vpi.ps: iverilog-vpi.man
	$(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps

iverilog-vpi.pdf: iverilog-vpi.ps
	$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf

# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version_tag.h file in the source tree (included in snapshots and releases),
# and finally use nothing.

# "true" and "false" in the next few lines are Unix shell command names
ifeq ($(GIT),none)
GIT_PRESENT = false
else
GIT_PRESENT = true
endif
version_tag.h version:
	@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
	    echo "Using git-describe for VERSION_TAG"; \
	    tag=`$(GIT) --git-dir $(srcdir)/.git describe`; \
	    tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"$$tag\"\n#endif\n"`; \
	    echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
	elif test -r $(srcdir)/version_tag.h; then \
	    echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
	    diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
	else \
	    echo "Using empty VERSION_TAG"; \
	    tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"\"\n#endif\n"`; \
	    echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
	fi

ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
else
INSTALL_DOC = $(prefix)/iverilog-vpi$(suffix).pdf $(mandir)/man1/iverilog-vpi$(suffix).1
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
INSTALL_DOCDIR = $(mandir)/man1
endif

ifeq (@MINGW32@,yes)
WIN32_INSTALL =
else
WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
endif

install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@  $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
	$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true

$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
	$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"

$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
	$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"

$(libdir)/ivl$(suffix)/include/constants.vams: $(srcdir)/constants.vams
	$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"

$(libdir)/ivl$(suffix)/include/disciplines.vams: $(srcdir)/disciplines.vams
	$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"

$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
	$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"

$(includedir)/_pli_types.h: _pli_types.h
	$(INSTALL_DATA) $< "$(DESTDIR)$(includedir)/_pli_types.h"

$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
	$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"

$(includedir)/acc_user.h: $(srcdir)/acc_user.h
	$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"

$(includedir)/veriuser.h: $(srcdir)/veriuser.h
	$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"

$(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
	$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"

$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
	$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"


installdirs: $(srcdir)/mkinstalldirs
	$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
	    "$(DESTDIR)$(includedir)" \
	    "$(DESTDIR)$(libdir)/ivl$(suffix)" \
	    "$(DESTDIR)$(libdir)/ivl$(suffix)/include" \
	    "$(DESTDIR)$(mandir)" \
	    "$(DESTDIR)$(mandir)/man1"

uninstall:
	$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
	for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
	    do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
	-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
	-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)"
	for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \
	    do rm -f "$(DESTDIR)$(bindir)/$$f"; done
	for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
	    do rm -f "$(DESTDIR)$(includedir)/$$f"; done
	-test X$(suffix) = X || rmdir "$(DESTDIR)/$(includedir)"
	rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"


-include $(patsubst %.o, dep/%.d, $O)
-include $(patsubst %.o, dep/%.d, vpithunk.o)
