# This file is part of the Coral project.
# Please read the copyright notice in the LICENSE file.

QMAKE=qmake
PYTHON=python
PYTHON_VER=$(shell python -c 'import sys; s = sys.version_info; print "%d.%d" % (s[0], s[1])')
export PYTHONPATH=$(PWD):$PYTHONPATH
XARGS_R:=xargs -r
LN:=ln
FIND:=find
INSTALL:=install
STRIP_LIBRARY=strip

PYUIC:=$(PWD)/build/pyuic_wrapper


DOCTOOL=happydoc
DOCDIR:=$(PWD)/coral/
DOCDEST:=$(PWD)/doc/
# Add files/folders to ignore into DOCIGNORE
# The dlg and propertyeditors.py is ignored because of a
# bug in HappyDoc
DOCIGNORE:=-i unittest -i dlg -i propertyeditors.py


INC:=$(PWD)

# Libraries needed to compile Coral programms
coral_LIBS := -L $(PWD)/coral -lcoral
coral_LIBS += -ldl -lpthread -lutil


coral_OSLIBS :=  
OSTYPE :=linux

# OS-dependent section

# Cygwin
ifneq (,$(findstring CYGWIN,$(shell uname)))

OSTYPE:=cygwin
coral_OSLIBS += -liconv
ifeq ($(QMAKESPEC),)
QMAKESPEC :=/opt/qt3/mkspecs/cygwin-g++
export QMAKESPEC
endif

endif
#end of Cygin


### Try to use dynamic python library if we can find it
_got_dynpython = $(shell ls -1 /usr/lib/$(PYTHON)$(PYTHON_VER)/config/lib$(PYTHON)$(PYTHON_VER).so || ls -1 /usr/lib/lib$(PYTHON)$(PYTHON_VER).so)
ifneq "$(_got_dynpython)" ""
coral_OSLIBS += $(_got_dynpython)
else
# Put .a into _LIBS instead of _OSLIBS
# That way, libcoral.so does not have a copy of the .a file,
# and python user's don't need it. C++ users must then explicitely
# link with the .a file
#
coral_LIBS += /usr/lib/$(PYTHON)$(PYTHON_VER)/config/lib$(PYTHON)$(PYTHON_VER).a
####coral_OSLIBS += /usr/lib/$(PYTHON)$(PYTHON_VER)/config/lib$(PYTHON)$(PYTHON_VER).a

endif

prefix:=/usr

EXTRA_CXXFLAGS := \
$(shell build/check_cpp_visibility.sh) \
$(shell build/check_iconv_const_char.sh) \


ifeq ($(MAKECMDGOALS),install)
INSTALLATION_PATH=$(prefix)/lib
# Duh, coral/kernel.py has to be recreated on "make install",
# so force it by removing version.py :(
$(shell rm coral/version.py)
else
INSTALLATION_PATH=$(PWD)
endif

export INSTALLATION_PATH
export EXTRA_CXXFLAGS
export INC coral_LIBS coral_OSLIBS PYTHON PYTHON_VER PYUIC

all: coralcore modeler uml14_editors manage10_editors fsm10_editors coralex10_editors  esmd10_editors diml10_editors  smd01_editors xmidi20_editors constraint_editors cquery_editors



ifeq ($(MAKECMDGOALS),install)
.PHONY: coral/core/config.cpp
endif

.PHONY: doc coralcore

ifeq ($(CORAL_VERSION),)
CORAL_VERSION:=0.$(shell date '+%Y%m%d')
endif
export CORAL_VERSION

BUILD_DATE:=$(shell date '+%Y-%m-%d')
export BUILD_DATE

coral/core/config.cpp:
	echo '#include "config.h"' > $@
	echo "namespace coral {" >> $@
	echo "        const char* installation_path=\"$(INSTALLATION_PATH)\";" >> $@
	echo "        const char* const version = \"$(CORAL_VERSION)\";" >> $@
	echo "}" >> $@

coralcore: coral/core/config.cpp
	@if ! $(PYTHON) build/pythonversion.py; then \
		echo "You need python 2.3 to run coral"; \
		false; \
	fi
	$(MAKE) -C coral/bin
	$(MAKE) -C packaging/pkgconfig
	$(MAKE) -C coral -f makefile.swig
	# The cd...qmake has to be called that way, due to differences in
	# how different qmakes behave.
	@echo OSLIBS=$(coral_OSLIBS)
	cd coral; $(QMAKE) coral.pro -o makefile.coral
	$(MAKE) -C coral -j4 -f makefile.coral
	# cygwin needs this
	cd coral; ln -sf libcoral.so libcoral.dll
	$(MAKE) -C coral/lang -j || true

	$(MAKE) -C coral/lang -j

uml14_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/UML14

esmd10_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/ESMD10

# Remove this later if we want to separate it
fsm10_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/FSM10

manage10_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/Manage10

coralex10_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/CoralEx10

diml10_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/DIML10

smd01_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/SMD01

xmidi20_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/XMIDI20

constraint_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/constraint

cquery_editors: modeler coralcore
	CORALINSTALLATIONPATH=$$PWD $(MAKE) -C coral/addins/CQUERY10

tests:
	# Create project files for the tests
	$(FIND) . -name TESTS -print | while read i; do \
		for t in $$(cat $$i); do \
			build/genqmaketest $$t > $$(dirname $$i)/$$(basename $$t .cpp).exe.pro; \
		done; \
	done
	# Create the actual makefiles for the tests
	# we could use $(FIND) . -maxdepth here, but it might be
	# a bit nonportable?
	$(FIND) . -name unittests -print | while read d; do (cd $$d; \
		for i in $$($(FIND) . -name "*.pro" -print | sed -e 's/^..//'); do \
			$(QMAKE) $$i -o .makefile.$$i; \
			$(MAKE) -f .makefile.$$i; \
		done; \
		) \
	done

modeler:
	$(MAKE) -C coral/modeler/dlg

########## TEST

__dotests: all tests
	@echo
	@echo "*** NOTE NOTE NOTE ***"
	@echo "I'm setting \$$LD_LIBRARY_PATH before running"
	@echo "any tests. See ./makefile for details."
	@echo
	LD_LIBRARY_PATH=$$PWD/coral $$TESTDRIVER
	@echo "Test run finished: " `date`

test:
	if [ "$$TESTDRIVER" == "" ]; then \
		DISTTEST_HOSTS="localhost" TESTDRIVER="disttest $$CORAL_ACCEPTANCE_TESTS" make __dotests; \
	else \
		make __dotests; \
	fi

test_v:
	make test

test_p_v:
	CORAL_ACCEPTANCE_TESTS=-p make test_v

test_d:
	TESTDRIVER=disttest make test

test_d_v:
	TESTDRIVER=disttest make test_v

test_d_p_v:
	TESTDRIVER="disttest -p" make test_v

############### TEST COVERAGE

# Creates a test coverage
# Complicated chdir stuff thanks to python import semantics + tracing + whathaveyou
#
%.py.coverage: %.py
	cd $(dir $^); pycov --replace="|/var/tmp/[^/]*/|/|" --coverage=$(notdir $@) $(notdir $^)

__testcoverage:
	$(FIND) . -type f -name "*.py" -print | grep -e unittests/ | grep -v -e '__init__.py' | cut -c 3- | while read file; do \
		$(MAKE) $$file.coverage ; \
	done

############### DOCUMENTATION
doc:
	@echo "Creating documentation for Coral"
	@echo "Requires HappyDoc 3.0 or higher"
	$(DOCTOOL) $(DOCIGNORE) -d $(DOCDEST) -t Coral $(DOCDIR)


########## CLEAN


modelerclean:
	-rm coral/*.pyc
	$(MAKE) -C coral/modeler/dlg clean

testclean:
	-$(FIND) . -name ".*.pro" -print | $(XARGS_R) rm
	-$(FIND) . -name ".makefile.*" -print | $(XARGS_R) rm

clean: testclean modelerclean
	-rm -rf coral/libcoral* coral/coral.py \
	    coral/coral.i coral/coral_wrap.cxx \
	    coral/core/config.cpp \
	    coral/kernel.py coral/kernel_old.py coral/kernel_wrap* \
	    coral/kernel.i coral/version.py \
            coral/lang/XMIDI20/metamodel.py
	-rm coral/kernel.i.tmp coral/modeler/doc/license.html
	-rm coral/bin/coral coral/bin/coral-start coral/bin/coral-diff
	-$(FIND) . \( -name "*.o" -o -name "*.pyc" -o -name "*.pyo" -o -name "*.exe" -o -name "*.log" \) -print | $(XARGS_R) rm
	$(MAKE) -C coral/addins/UML14 clean
	$(MAKE) -C coral/addins/ESMD10 clean
	$(MAKE) -C coral/addins/FSM10 clean
	$(MAKE) -C coral/addins/Manage10 clean
	$(MAKE) -C coral/addins/CoralEx10 clean
	$(MAKE) -C coral/addins/XMIDI20 clean
	$(MAKE) -C coral/addins/constraint clean
	$(MAKE) -C coral/addins/CQUERY10 clean		

	-rm -rf debian/coral






################ INSTALLING

# Obey DESTDIR when installing files!
#
UID := $(shell id -un)
GID := $(shell id -gn)
i := $(INSTALL) -o $(UID) -g $(GID)

install: all
	$(INSTALL) -d \
	  $(DESTDIR)$(prefix) \
	  $(DESTDIR)$(prefix)/bin \
	  $(DESTDIR)$(prefix)/lib \
	  $(DESTDIR)$(prefix)/lib/ \
	  $(DESTDIR)$(prefix)/lib/coral

	#
	# Install the application shortcut into the
	# correct place. /usr/share/applications is the
	# new and shiny XDG location, /usr/share/applnk
	# is the old location which Coral does not support any longer.
	# A new version of Gnome also supports this location
	#
	$(INSTALL) -d \
	$(DESTDIR)$(prefix)/share \
	$(DESTDIR)$(prefix)/share/applications
	(cd packaging/kde; make)
	$(i) packaging/kde/coral.desktop \
	     $(DESTDIR)$(prefix)/share/applications/coral.desktop
	#
	# Stupid icons
	#
	$(i) -D packaging/install_logos/coral_logo_16x16.xpm \
		$(DESTDIR)$(prefix)/share/icons/hicolor/16x16/apps/coral.xpm
	$(i) -D packaging/install_logos/coral_logo_24x24.xpm \
		$(DESTDIR)$(prefix)/share/icons/hicolor/24x24/apps/coral.xpm
	$(i) -D packaging/install_logos/coral_logo_32x32.xpm \
		$(DESTDIR)$(prefix)/share/icons/hicolor/32x32/apps/coral.xpm
	$(i) -D packaging/install_logos/coral_logo_48x48.xpm \
		$(DESTDIR)$(prefix)/share/icons/hicolor/48x48/apps/coral.xpm
	$(i) -D packaging/install_logos/coral_logo_16x16.xpm \
		$(DESTDIR)$(prefix)/share/icons/locolor/16x16/apps/coral.xpm
	$(i) -D packaging/install_logos/coral_logo_24x24.xpm \
		$(DESTDIR)$(prefix)/share/icons/locolor/24x24/apps/coral.xpm
	$(i) -D packaging/install_logos/coral_logo_32x32.xpm \
		$(DESTDIR)$(prefix)/share/icons/locolor/32x32/apps/coral.xpm
	$(i) -D packaging/install_logos/coral_logo_48x48.xpm \
		$(DESTDIR)$(prefix)/share/icons/locolor/48x48/apps/coral.xpm



	cd coral && $(FIND) . -name "*.py" -print \
	| grep -v -e unittests \
	| grep -v -e __add_to_kernel-pre.py \
	| grep -v -e version.py \
	| grep -v -e __add_to_kernel-post.py \
	| grep -v _extra.py$ \
	| grep -v /def/ \
	| grep -v _old.py$ \
	| $(XARGS_R) -i $(i) -D \{\} $(DESTDIR)$(prefix)/lib/coral/\{\}
	$(i) coral/modeler/dmanifest.xmi $(DESTDIR)$(prefix)/lib/coral/modeler/dmanifest.xmi
	cd coral && $(FIND) . \( -name "manifest*.txt" -o -name "*.mnf.xmi" \) -print \
	| $(XARGS_R) -i $(i) -D \{\} $(DESTDIR)$(prefix)/lib/coral/\{\}
	# Documentation available at run-time in Coral
	$(FIND) coral/modeler/doc -type f -name "*.html" -print \
	| $(XARGS_R) -i $(i) -D \{\} $(DESTDIR)$(prefix)/lib/\{\}
	# Icons
	cd coral && $(FIND) . \( -name "*.png" -o -name "*.gif" \) -print \
	| $(XARGS_R) -i $(i) -D \{\} $(DESTDIR)$(prefix)/lib/coral/\{\}
	# libcoral goes here
	$(FIND) coral -maxdepth 1 -type f -print | egrep 'lib.*.so' \
	| $(XARGS_R) -i $(i) \{\} $(DESTDIR)$(prefix)/lib/coral
	$(FIND) coral -maxdepth 1 -type l -print | egrep 'lib.*.so' \
	| $(XARGS_R) -i cp -d \{\} $(DESTDIR)$(prefix)/lib/coral
	# Strip library to reduce space usage
	$(FIND) $(DESTDIR)$(prefix)/lib/coral -maxdepth 1 -type f -print \
	| egrep 'lib.*.so' | $(XARGS_R) $(STRIP_LIBRARY)
	# Metamodel libraries here
	cd coral && $(FIND) lang -type f -print | egrep -e 'lib.*.so' \
	| $(XARGS_R) -i $(i) -D \{\} $(DESTDIR)$(prefix)/lib/coral/\{\}
	cd coral && $(FIND) lang -type l -print | egrep 'lib.*.so' \
	| $(XARGS_R) -i cp -d \{\} $(DESTDIR)$(prefix)/lib/coral/\{\}
	cd coral && $(FIND) lang -type f -name "*.xmi" -print \
	| $(XARGS_R) -i $(i) -D \{\} $(DESTDIR)$(prefix)/lib/coral/\{\}
	$(i) -D coral/core/CORE01.xmi $(DESTDIR)$(prefix)/lib/coral/core/CORE01.xmi
	$(i) -D coral/core/XMI12.xmi $(DESTDIR)$(prefix)/lib/coral/core/XMI12.xmi
	# Usage license
	$(i) LICENSE $(DESTDIR)$(prefix)/lib/coral/LICENSE
	# Authors file, should it be in share/doc/coral?
	$(i) AUTHORS $(DESTDIR)$(prefix)/lib/coral/AUTHORS
	# Binaries
	$(i) -D coral/bin/coral $(DESTDIR)$(prefix)/bin/coral
	$(i) -D coral/bin/coral-start $(DESTDIR)$(prefix)/bin/coral-start
	$(i) -D coral/bin/coral-diff $(DESTDIR)$(prefix)/bin/coral-diff
	$(i) -D packaging/pkgconfig/coral.pc $(DESTDIR)$(prefix)/lib/pkgconfig/coral.pc
	# Examples
	$(FIND) examples -type f | grep -v .svn \
	| $(XARGS_R) -i $(i) -D \{\} $(DESTDIR)$(prefix)/lib/coral/\{\}



