##############################################################################
##
## Crytek Source File.
## Copyright (C), Crytek Studios, 2007.
## ---------------------------------------------------------------------------
## Description:
## De-virtualization tool.
##
##############################################################################

# Set $(HOST_TYPE) to either 'win32' or 'linux'.
#HOST_TYPE := win32
#HOST_TYPE := cygwin
HOST_TYPE := linux

DEBUG := 0

ifeq ($(HOST_TYPE),win32)
  HOST_PREFIX := i586-mingw32msvc-
  EXT_O := obj
  EXT_D := dep
  DEVIRT := devirt.exe
endif

ifeq ($(HOST_TYPE),cygwin)
  HOST_PREFIX := 
  EXT_O := obj
  EXT_D := dep
  DEVIRT := devirt.exe
  GCC_SUFFIX := 
endif 

ifeq ($(HOST_TYPE),linux)
  HOST_PREFIX :=
  EXT_O := o
  EXT_D := d
  DEVIRT := devirt
  GCC_SUFFIX := -4.3
endif

USE_CCACHE := 0
USE_DISTCC := 0

CCACHE = ccache
DISTCC = distcc

ifeq ($(USE_CCACHE),1)
  ifeq ($(USE_DISTCC),1)
    CXX = CCACHE_PREFIX=$(DISTCC) $(CCACHE) $(HOST_PREFIX)g++$(GCC_SUFFIX)
    CC = CCACHE_PREFIX=$(DISTCC) $(CCACHE) $(HOST_PREFIX)gcc$(GCC_SUFFIX)
  else
    CXX = $(CCACHE) $(HOST_PREFIX)g++$(GCC_SUFFIX)
    CC = $(CCACHE) $(HOST_PREFIX)gcc$(GCC_SUFFIX)
  endif
else
  ifeq ($(USE_DISTCC),1)
    CXX = $(DISTCC) $(HOST_PREFIX)g++$(GCC_SUFFIX)
    CC = $(DISTCC) $(HOST_PREFIX)gcc$(GCC_SUFFIX)
  else
    CXX = $(HOST_PREFIX)g++$(GCC_SUFFIX)
    CC = $(HOST_PREFIX)gcc$(GCC_SUFFIX)
  endif
endif
DOT = dot
P4 = p4
INSTALL = install

BUILD_DIR := Build/$(HOST_TYPE)

WARNING_FLAGS_C = -Wall
WARNING_FLAGS_CXX = \
	$(WARNING_FLAGS_C) \
	-Woverloaded-virtual
ifeq ($(HOST_TYPE),linux)
  WARNING_FLAGS_CXX += -Wno-variadic-macros
endif

#HOST_FLAGS = -m32
ifeq ($(DEBUG),1)
  OPT_FLAGS := -O0
else
  OPT_FLAGS := -O3 -DNDEBUG
endif

CFLAGS = $(HOST_FLAGS) -g $(OPT_FLAGS)
CXXFLAGS = $(CFLAGS) -fno-exceptions
LDFLAGS = $(HOST_FLAGS) -fno-exceptions
CPPFLAGS = -I$(ZLIB_DIR) -I$(REGEX_DIR) -DSTDC_HEADERS

DEVIRT_SOURCES = \
	DeVirt.h \
	DeVirt.cpp \
	Parse.cpp \
	Write.cpp \
	Mangle.cpp \
	Util.h \
	Util.cpp \
	Getopt.h \
	Getopt.cpp \
	Main.cpp

SOURCES = $(DEVIRT_SOURCES)

SOURCES_C = $(filter %.c, $(SOURCES))
SOURCES_CPP = $(filter %.cpp, $(SOURCES))
SOURCES_H = $(filter %.h, $(SOURCES))

OBJECTS = \
	$(SOURCES_CPP:%.cpp=$(BUILD_DIR)/%.$(EXT_O)) \
	$(SOURCES_C:%.c=$(BUILD_DIR)/%.$(EXT_O))

all: $(DEVIRT)

$(DEVIRT): $(OBJECTS)
	@$(RM) $@
	$(CXX) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LDLIBS)

clean:
	$(RM) $(OBJECTS)
	$(RM) $(DEVIRT)

wc:
	wc $(DEVIRT_SOURCES)

ls:
	@echo $(DEVIRT_SOURCES)

define include_deps
-include $(patsubst %.$(EXT_O),%.$(EXT_D),$(1))
endef
$(foreach file, $(OBJECTS), $(eval $(call include_deps,$(file))))

.SUFFIXES: c cpp $(EXT_O) dot ps png

$(BUILD_DIR)/%.$(EXT_O): %.cpp
	@$(RM) $@
	@mkdir -p $(dir $@)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(WARNING_FLAGS_CXX) \
		-MMD -MP -MQ $@ -MF $(patsubst %.$(EXT_O),%.$(EXT_D),$@) \
		$< -c -o $@

$(BUILD_DIR)/%.$(EXT_O): %.c
	@$(RM) $@
	@mkdir -p $(dir $@)
	$(CC) $(CPPFLAGS) $(CFLAGS) $(WARNING_FLAGS_C) \
		-MMD -MP -MQ $@ -MF $(patsubst %.$(EXT_O),%.$(EXT_D),$@) \
		$< -c -o $@

%.ps: %.dot
	@$(RM) $@
	$(DOT) -Tps -o $@ $<

%.png: %.dot
	@$(RM) $@
	$(DOT) -Tpng -o $@ $<

%.svg: %.dot
	@$(RM) $@
	$(DOT) -Tsvg -o $@ $<



ifeq ($(HOST_TYPE),linux)
ifdef DEPOT_MAIN
MAKE_ROOT = $(DEPOT_MAIN)/Code/Tools/Make

install: $(DEVIRT)
	$(P4) edit -t xbinary '$(MAKE_ROOT)/Tools/host-linux/devirt'
	$(INSTALL) -s $(DEVIRT) '$(MAKE_ROOT)/Tools/host-linux/devirt'
endif
endif # HOST_TYPE == linux

.PHONY: tags
tags:
	ctags -R --extra=fq .

.PHONY: etags
etags:
	rm -vf TAGS
	@ctags -ea --extra=+q --fields=+fksaiSz $(DEVIRT_SOURCES)


# vim:ts=8:sw=2

