#######################################################################
# SWIG top level Makefile
#######################################################################

.PHONY: ccache source swig

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

#####################################################################
# Make options - override these to see more output
#####################################################################

RUNPIPE     = \>/dev/null
FLAGS       = -k -s

#####################################################################
# Compiler and system configuration
#####################################################################

SHELL       = /bin/sh
SWIG_LIB_INSTALL = @SWIG_LIB_INSTALL@
BIN_DIR     = @bindir@
ENABLE_CCACHE = @ENABLE_CCACHE@
TARGET_NOEXE= swig
TARGET      = $(TARGET_NOEXE)@EXEEXT@
SOURCE      = Source
CCACHE      = CCache
DOCS        = Doc/Manual

swig: libfiles source ccache

source:
	@$(MAKE) -C $(SOURCE)

ccache:
	test -z "$(ENABLE_CCACHE)" || $(MAKE) -C $(CCACHE)

libfiles: $(srcdir)/Lib/swigwarn.swg

# Files required just for the tarball
maintainer: libfiles
	@$(MAKE) -C $(SOURCE) CParse/parser.h

#####################################################################
# Documentation
#####################################################################

docs: docs-main

docs-main:
	@echo making docs
	@test ! -d $(DOCS) || $(MAKE) -C $(DOCS) all clean-baks

#####################################################################
# All the languages SWIG speaks (when it wants to)
#####################################################################

skip-c		= test -n "@SKIP_C@"
skip-csharp	= test -n "@SKIP_CSHARP@"
skip-d		= test -n "@SKIP_D@"
skip-go		= test -n "@SKIP_GO@"
skip-guile	= test -n "@SKIP_GUILE@"
skip-java	= test -n "@SKIP_JAVA@"
skip-javascript	= test -n "@SKIP_JAVASCRIPT@"
skip-lua    	= test -n "@SKIP_LUA@"
skip-ocaml      = test -n "@SKIP_OCAML@"
skip-octave     = test -n "@SKIP_OCTAVE@"
skip-perl5	= test -n "@SKIP_PERL5@"
skip-php	= test -n "@SKIP_PHP@"
skip-python	= test -n "@SKIP_PYTHON@"
skip-r		= test -n "@SKIP_R@"
skip-ruby	= test -n "@SKIP_RUBY@"
skip-scilab     = test -n "@SKIP_SCILAB@"
skip-tcl	= test -n "@SKIP_TCL@"

# Additional dependencies for some tests
skip-android    = test -n "@SKIP_ANDROID@"

# Special errors test-case
skip-errors	= test -n ""

check-%-enabled:
	@if $(skip-$*); then					\
	  echo skipping $* version;				\
	  exit 1;   \
	fi

#####################################################################
# CHECK
#####################################################################

ACTION = check
NOSKIP =

check-aliveness:
	test -x ./$(TARGET)
	./$(TARGET) -version
	./$(TARGET) -help
	@$(skip-c) 	  || ./$(TARGET) -c          -help
	@$(skip-csharp)   || ./$(TARGET) -csharp     -help
	@$(skip-d) 	  || ./$(TARGET) -d          -help
	@$(skip-go)	  || ./$(TARGET) -go         -help
	@$(skip-guile)    || ./$(TARGET) -guile      -help
	@$(skip-java)     || ./$(TARGET) -java       -help
	@$(skip-javascript) || ./$(TARGET) -javascript -help
	@$(skip-lua)      || ./$(TARGET) -lua        -help
	@$(skip-ocaml)    || ./$(TARGET) -ocaml      -help
	@$(skip-octave)   || ./$(TARGET) -octave     -help
	@$(skip-perl5)    || ./$(TARGET) -perl       -help
	@$(skip-php)      || ./$(TARGET) -php7       -help
	@$(skip-python)   || ./$(TARGET) -python     -help
	@$(skip-r) 	  || ./$(TARGET) -r          -help
	@$(skip-ruby)     || ./$(TARGET) -ruby       -help
	@$(skip-scilab)   || ./$(TARGET) -scilab     -help
	@$(skip-tcl)      || ./$(TARGET) -tcl        -help

check-ccache:
	test -z "$(ENABLE_CCACHE)" || $(MAKE) -C $(CCACHE) check

# Checks / displays versions of each target language
check-versions:					\
	check-android-version			\
	check-csharp-version			\
	check-d-version				\
	check-go-version			\
	check-guile-version			\
	check-java-version			\
	check-javascript-version		\
	check-lua-version			\
	check-ocaml-version			\
	check-octave-version			\
	check-perl5-version			\
	check-php-version			\
	check-python-version			\
	check-r-version				\
	check-ruby-version			\
	check-scilab-version			\
	check-tcl-version			\

# all examples
check-%-version :
	@if test -z "$(skip-$*)"; then				\
	  echo $* unknown;					\
	  exit 1;						\
	fi
	@if $(skip-$*); then					\
	  echo skipping $* version;				\
	else							\
	  echo showing $* version;				\
	  $(MAKE) -C Examples $(FLAGS) $*_version;		\
	fi

# Checks examples for compilation (does not run them)
check-examples:					\
	check-android-examples			\
	check-c-examples			\
	check-csharp-examples			\
	check-d-examples			\
	check-go-examples			\
	check-guile-examples			\
	check-java-examples			\
	check-javascript-examples		\
	check-lua-examples			\
	check-ocaml-examples			\
	check-octave-examples			\
	check-perl5-examples			\
	check-php-examples			\
	check-python-examples			\
	check-r-examples			\
	check-ruby-examples			\
	check-scilab-examples			\
	check-tcl-examples			\

android_examples   :=$(shell sed '/^\#/d' $(srcdir)/Examples/android/check.list)
c_examples         :=$(shell sed '/^\#/d' $(srcdir)/Examples/c/check.list)
csharp_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/csharp/check.list)
d_examples         :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list)
go_examples        :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list)
guile_examples     :=$(shell sed '/^\#/d' $(srcdir)/Examples/guile/check.list)
java_examples      :=$(shell sed '/^\#/d' $(srcdir)/Examples/java/check.list)
javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list)
lua_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/lua/check.list)
ocaml_examples     :=$(shell sed '/^\#/d' $(srcdir)/Examples/ocaml/check.list)
octave_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/octave/check.list)
perl5_examples     :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list)
php_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/php/check.list)
python_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/python/check.list)
r_examples         :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list)
ruby_examples      :=$(shell sed '/^\#/d' $(srcdir)/Examples/ruby/check.list)
scilab_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/scilab/check.list)
tcl_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list)

# Running tests using v8 or jsc involves creating a custom interpreter in
# Tools/javascript.  This causes problems for parallel builds (we attempt to
# update this interpreter when it's already running, resulting in a "Text file
# busy" error).  We can avoid this by ensuring we have built the custom
# interpreter before running the tests.
ifeq ($(ENGINE), $(filter $(ENGINE), jsc v8))
ifeq ($(ACTION), check)
check-javascript-prepare:
	@$(MAKE) $(FLAGS) -C Tools/javascript javascript
endif
endif

check-%-prepare:
	@:

# all examples
check-%-examples : check-%-prepare
	@if test -z "$(skip-$*)"; then				\
	  echo $* unknown;					\
	  exit 1;						\
	fi
	@if $(skip-$*); then					\
	  echo skipping $* $(ACTION);				\
	elif test -z "$($(strip $*_examples))"; then		\
	  echo empty $* $(ACTION);				\
	else							\
	  $(MAKE) $(FLAGS) $($*_examples:=.actionexample) LANGUAGE=$* ACTION=$(ACTION); \
	fi

# individual example
%.actionexample:
	@$(MAKE) -C Examples Makefile
	@echo $(ACTION)ing Examples/$(LANGUAGE)/$*
	@$(MAKE) -C Examples/$(LANGUAGE)/$* $(FLAGS) $(ACTION) RUNPIPE=$(RUNPIPE)

# Checks testcases in the test-suite excluding those which are known to be broken
check-test-suite:				\
	check-errors-test-suite			\
	check-c-test-suite			\
	check-csharp-test-suite			\
	check-d-test-suite			\
	check-go-test-suite			\
	check-guile-test-suite			\
	check-java-test-suite			\
	check-javascript-test-suite		\
	check-lua-test-suite			\
	check-ocaml-test-suite			\
	check-octave-test-suite			\
	check-perl5-test-suite			\
	check-php-test-suite			\
	check-python-test-suite			\
	check-r-test-suite			\
	check-ruby-test-suite			\
	check-scilab-test-suite			\
	check-tcl-test-suite			\

check-%-test-suite: check-%-prepare
	@if test -z "$(skip-$*)"; then					\
	  echo $* unknown;						\
	  exit 1;							\
	fi
	@passed=true;							\
	dir="Examples/test-suite/$*";					\
	if $(skip-$*) -a "$(NOSKIP)" != "1"; then			\
	  echo skipping $* test-suite $(ACTION);			\
	elif [ ! -d $$dir ]; then					\
	  echo warning: cannot $(ACTION) $* test-suite "(no dir $$dir)";\
	else								\
	  echo $(ACTION)ing $* test-suite;				\
	  $(MAKE) -C $$dir $(FLAGS) $(ACTION)				\
	  || passed=false;						\
	fi;								\
	test $$passed = true

# Partial test-suite check - it only invokes SWIG, ie no compilation and no runtime testing
partialcheck-test-suite:
	@$(MAKE) $(FLAGS) check-test-suite ACTION=partialcheck NOSKIP=1

partialcheck-%-test-suite:
	@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=partialcheck NOSKIP=1

check: check-aliveness check-ccache check-versions check-examples check-test-suite

# Run known-to-be-broken as well as not broken testcases in the test-suite
all-test-suite:					\
	all-c-test-suite			\
	all-csharp-test-suite			\
	all-d-test-suite			\
	all-go-test-suite			\
	all-guile-test-suite			\
	all-java-test-suite			\
	all-javascript-test-suite		\
	all-lua-test-suite			\
	all-ocaml-test-suite			\
	all-octave-test-suite			\
	all-perl5-test-suite			\
	all-php-test-suite			\
	all-python-test-suite			\
	all-r-test-suite			\
	all-ruby-test-suite			\
	all-scilab-test-suite   		\
	all-tcl-test-suite			\

all-%-test-suite:
	@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=all

# Run known-to-be-broken testcases in the test-suite
broken-test-suite:				\
	broken-c-test-suite			\
	broken-csharp-test-suite		\
	broken-d-test-suite			\
	broken-go-test-suite			\
	broken-guile-test-suite			\
	broken-java-test-suite			\
	broken-javascript-test-suite		\
	broken-lua-test-suite			\
	broken-ocaml-test-suite			\
	broken-octave-test-suite		\
	broken-perl5-test-suite			\
	broken-php-test-suite			\
	broken-python-test-suite		\
	broken-r-test-suite			\
	broken-ruby-test-suite			\
	broken-scilab-test-suite		\
	broken-tcl-test-suite			\

broken-%-test-suite:
	@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=broken

#####################################################################
# CLEAN
#####################################################################

clean: clean-objects clean-examples clean-test-suite

clean-objects: clean-source clean-ccache

clean-source:
	@echo cleaning Source
	@$(MAKE) -C $(SOURCE) $(FLAGS) clean
	@rm -f $(TARGET)

clean-examples:
	@$(MAKE) $(FLAGS) check-examples ACTION=clean

clean-test-suite:
	@$(MAKE) $(FLAGS) check-test-suite ACTION=clean NOSKIP=1

clean-%-examples:
	@$(MAKE) $(FLAGS) check-$*-examples ACTION=clean

clean-%-test-suite:
	@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=clean NOSKIP=1

clean-ccache:
	test -z "$(ENABLE_CCACHE)" || $(MAKE) -C $(CCACHE) $(FLAGS) clean

#####################################################################
# DISTCLEAN - clean what configure built
#####################################################################

DISTCLEAN-DEAD = config.status config.log config.cache Makefile mkmf.log preinst-swig

distclean-helper: distclean-test-suite distclean-examples distclean-tools distclean-dead

distclean: distclean-source distclean-ccache distclean-helper

distclean-source:
	@echo distcleaning Source
	@$(MAKE) -C $(SOURCE) $(FLAGS) distclean
	@rm -f $(TARGET)

distclean-test-suite:
	@echo distcleaning Examples/test-suite
	@$(MAKE) $(FLAGS) check-test-suite ACTION=distclean NOSKIP=1

distclean-examples:
	@echo distcleaning Examples
	@$(MAKE) $(FLAGS) clean-examples
	@$(MAKE) -C Examples $(FLAGS) distclean
	@if test "x$(srcdir)" != "x."; then \
		for mkfile in `cd $(srcdir) && find Examples/ -type f -name Makefile`; do \
			rm -f "$$mkfile"; \
		done; \
	fi

distclean-ccache:
	@test -z "$(ENABLE_CCACHE)" || $(MAKE) -C $(CCACHE) $(FLAGS) distclean

distclean-tools:
	@echo distcleaning Tools
	@$(MAKE) -C Tools/javascript $(FLAGS) distclean

distclean-dead:
	rm -f $(DISTCLEAN-DEAD)
	rm -rf autom4te.cache

#####################################################################
# MAINTAINER CLEAN - clean what the maintainer builds and ships in
# the distributed tarball - should not delete anything needed to run
# ./configure && make
#####################################################################

maintainer-clean:
	@echo maintainer-cleaning source
	@$(MAKE) -C $(SOURCE) $(FLAGS) maintainer-clean
	@echo maintainer-cleaning CCache
	@test -z "$(ENABLE_CCACHE)" || $(MAKE) -C $(CCACHE) $(FLAGS) maintainer-clean
	@echo maintainer-cleaning docs
	@test ! -d $(DOCS) || $(MAKE) -C $(DOCS) $(FLAGS) maintainer-clean
	@echo maintainer-cleaning Lib files
	@rm -f $(srcdir)/Lib/swigwarn.swg
	@echo distcleaning
	@$(MAKE) $(FLAGS) distclean-helper

check-maintainer-clean: maintainer-clean
	@if test "x$(srcdir)" = "x."; then \
		echo "skipping maintainer-clean check (in-source-tree build)"; \
		exit 0; \
	fi; \
	for file in `find . -type f`; do \
		echo "file missed by maintainer-clean: $$file"; \
	done; \
	test "x$$file" = x && echo "all files cleaned by maintainer-clean"

#####################################################################
# Update the Lib/swigwarn.swg file
# Note: Generated into the source tree rather than build tree
#####################################################################

$(srcdir)/Lib/swigwarn.swg: $(srcdir)/Source/Include/swigwarn.h
	mkdir -p Lib
	echo "/* SWIG warning codes - generated from swigwarn.h - do not edit */" > $@
	cat $? | grep "^#define WARN\|/\*.*\*/\|^[ \t]*$$" | sed 's/^#define \(WARN.*[0-9][0-9]*\)\(.*\)$$/%define SWIG\1 %enddef\2/' >> $@

#####################################################################
# TARGETS: install & friends
#####################################################################

INSTALL         = @abs_srcdir@/Tools/config/install-sh
INSTALL_DATA    = ${INSTALL} -c -m 644
INSTALL_PROGRAM = ${INSTALL} -c -m 755
MKINSTDIRS      = ${INSTALL} -m 0755 -d
# Use standard autoconf approach to transform executable name using --program-prefix and --program-suffix
transform	= @program_transform_name@

install: install-main install-lib install-ccache
	@echo "Installation complete"

install-main:
	@echo "Installing SWIG executable"
	@$(MKINSTDIRS) $(DESTDIR)$(BIN_DIR)
	@echo "Installing $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@"
	@$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@

lib-languages = typemaps tcl perl5 python guile java ruby php ocaml octave \
	csharp lua r c go d javascript javascript/jsc \
	javascript/v8 javascript/napi scilab xml

lib-modules = std


install-lib:
	@echo "Installing the SWIG library"
	@$(MKINSTDIRS) $(DESTDIR)$(SWIG_LIB_INSTALL)
	@for file in $(srcdir)/Lib/*.i $(srcdir)/Lib/*.swg ; do \
	    i=`basename $$file` ;				\
	    echo "Installing $(DESTDIR)$(SWIG_LIB_INSTALL)/$$i";	\
	    $(INSTALL_DATA) $$file $(DESTDIR)$(SWIG_LIB_INSTALL)/$$i;	\
	    done;
	@for lang in $(lib-languages) $(lib-modules);		\
	    do							\
	    echo "Installing language specific files for $$lang"; \
	    dst=$(DESTDIR)$(SWIG_LIB_INSTALL)/$$lang;			\
	    $(MKINSTDIRS) $$dst;				\
	     (doti="`cd $(srcdir)/Lib/$$lang && ls *.i 2>/dev/null || echo ''`"; \
	      dotswg="`cd $(srcdir)/Lib/$$lang && ls *.swg 2>/dev/null || echo ''`"; \
	      if [ -f $(srcdir)/Lib/$$lang/extra-install.list ]; then	\
		  extra="`sed '/^#/d' $(srcdir)/Lib/$$lang/extra-install.list`";	\
	      fi;						\
	      files="`echo $$doti $$dotswg $$extra`";		\
	      if [ x"$$files" = x ]; then			\
		  echo "Installing nothing from Lib/$$lang";	\
	      else for file in $$doti $$dotswg $$extra;		\
		  do						\
		  echo "Installing $$dst/$$file";		\
		  $(INSTALL_DATA) $(srcdir)/Lib/$$lang/$$file $$dst/$$file; \
		  done;						\
	      fi) ; 						\
	done

install-ccache:
	@test -z "$(ENABLE_CCACHE)" || $(MAKE) -C $(CCACHE) install


#####################################################################
# TARGETS: uninstall & friends
#####################################################################

uninstall: uninstall-main uninstall-lib uninstall-ccache
	@echo "Uninstall complete"

uninstall-main:
	@echo "Uninstalling SWIG executable $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@"
	rm -f $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@

uninstall-lib:
	@echo "Uninstalling the SWIG library"
	rm -rf $(DESTDIR)$(SWIG_LIB_INSTALL)/

uninstall-ccache:
	test -z "$(ENABLE_CCACHE)" || $(MAKE) -C $(CCACHE) uninstall

############################################################################
# DIST and other maintenance
############################################################################

dist:
	@echo "'make dist' not implemented - use Tools/mkdist.py instead - e.g.:"
	@echo "Tools/mkdist.py @VERSION@ master"
	@false

# Update the autoconf files for detecting host/targets. Automake will do this in
# version 1.10 for our case of not having a top level Makefile.am. Until then we
# can fetch them manually and will have to commit them to Git.
configfiles:
	wget 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess' -O Tools/config/config.guess
	chmod a+x Tools/config/config.guess
	wget 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub' -O Tools/config/config.sub
	chmod a+x Tools/config/config.sub

# Regenerate Makefile if Makefile.in or config.status have changed.
Makefile: $(srcdir)/Makefile.in config.status
	$(SHELL) ./config.status

# This target is usually called from Source/Makefile when configure.ac has
# changed.
am--refresh: $(srcdir)/configure

$(srcdir)/configure: $(srcdir)/configure.ac
	@echo "Build system is out of date.  If the following commands fail, please reconfigure by hand (rerun: ./autogen.sh && ./configure)"
	cd $(srcdir) && ./autogen.sh
	$(SHELL) ./config.status --recheck

############################################################################
# Tools
############################################################################

# Coverity static code analyser build and submit - EMAIL and PASSWORD need specifying
# See http://scan.coverity.com/start/
EMAIL=wsf@fultondesigns.co.uk
PASSWORD=
coverity:
	test -n "$(PASSWORD)" || (echo "PASSWORD not set" && false)
	$(MAKE) clean-source
	rm -rf cov-int
	cov-build --dir cov-int $(MAKE) source
	tar czvf swig-coverity.tgz cov-int
	curl --form file=@swig-coverity.tgz --form project=swig --form password=$(PASSWORD) --form email=$(EMAIL) http://scan5.coverity.com/cgi-bin/upload.py

# Makefile ends here
