#############################################################################
#############################################################################
###***********************************************************************###
###* .oO0Oo.oO0Oo.oO0Oo.oO(:T:H:E: :B:A:S:T:A:R:D:)Oo.oO0Oo.oO0Oo.oO0Oo. *###
###*                                                                     *###
###*                                                                     *###
###*    Chief Makefile Architect : the grugq                             *###
###*    other people that did something:                                 *###
###*                                    mammon_ ReZiDeNt MO_K FBJ        *###
###*                                                                     *###
###*                                                                     *###
###***********************************************************************###
#############################################################################
#############################################################################


PROGRAM = bastard
BASTARD_VERSION = 0.16
TOP     = $(PWD)
export TOP PROGRAM BASTARD_VERSION


# ------------------------------------ Initialization -----------------
CC      = gcc
AR      = ar
TAR     = tar --exclude CVS -chf
UNTAR   = tar -xf
ZIP     = gzip -f
RM      = rm -rf
CP      = cp -r
LN      = ln -sf
MKDIR   = mkdir -p


INSTALL_DIR = /usr/local/bastard
INSTALL_BIN = /usr/local/bin
INSTALL_LIB = /usr/local/lib
INSTALL_MAN = /usr/local/man
INSTALL_SHARE = /usr/local/share
export INSTALL_LIB INSTALL_DIR INSTALL_BIN INSTALL_SHARE

BINDIR   = bin
LIBDIR   = lib
SRCDIR   = src
INCDIR   = include
OBJDIR   = src
SHAREDIR = share

# ----------------------- File List for Tarballs ---------------
SRCS    =       \
                ${SRCDIR}/cli/bastard.c     		\
                ${SRCDIR}/cli/cli_cmd.c      		\
                ${SRCDIR}/cli/cli_db.c      		\
                ${SRCDIR}/cli/parser.c    
HDRS    =       \
                ${INCDIR}/cli/bastard_main.h       \
                ${INCDIR}/cli/cli_cmd.h       \
                ${INCDIR}/cli/cli_db.h       \
                ${INCDIR}/cli/parser.h      

LIB_SRCS    =       \
		 ${SRCDIR}/api/api_address.c		\
		 ${SRCDIR}/api/api_code.c			\
		 ${SRCDIR}/api/api_disasm.c			\
		 ${SRCDIR}/api/api_env.c				\
		 ${SRCDIR}/api/api_functions.c		\
		 ${SRCDIR}/api/api_importexport.c	\
		 ${SRCDIR}/api/api_intcode.c			\
		 ${SRCDIR}/api/api_loadsave.c		\
		 ${SRCDIR}/api/api_macros.c			\
		 ${SRCDIR}/api/api_namecomment.c	\
             ${SRCDIR}/api/api_search.c			\
		 ${SRCDIR}/api/api_section.c		\
		 ${SRCDIR}/api/api_strings.c		\
		 ${SRCDIR}/api/api_structconst.c	\
		 ${SRCDIR}/api/api_system.c			\
		 ${SRCDIR}/api/api_xref.c			\
             ${SRCDIR}/db.c          		\
             ${SRCDIR}/db/db_query.c         \
		 ${SRCDIR}/eic_wrappers.c     \
             ${SRCDIR}/extension.c            \
             ${SRCDIR}/macro.c            \
             ${SRCDIR}/vm.c            \
             ${SRCDIR}/util.c

LIB_HDRS    =       \
                ${INCDIR}/api/api_main.h           \
                ${INCDIR}/api/api_error.h     \
                ${INCDIR}/api/api_addr.h     \
                ${INCDIR}/api/api_addrexp.h     \
                ${INCDIR}/api/api_code.h     \
                ${INCDIR}/api/api_comment.h     \
                ${INCDIR}/api/api_const.h     \
                ${INCDIR}/api/api_db.h     \
                ${INCDIR}/api/api_disasm.h     \
                ${INCDIR}/api/api_dtype.h     \
                ${INCDIR}/api/api_env.h     \
                ${INCDIR}/api/api_exp.h     \
                ${INCDIR}/api/api_fincode.h     \
                ${INCDIR}/api/api_func.h     \
                ${INCDIR}/api/api_imp.h     \
                ${INCDIR}/api/api_inline.h     \
                ${INCDIR}/api/api_intcode.h     \
                ${INCDIR}/api/api_lib.h     \
                ${INCDIR}/api/api_macro.h     \
                ${INCDIR}/api/api_name.h     \
                ${INCDIR}/api/api_plugin.h     \
                ${INCDIR}/api/api_search.h     \
                ${INCDIR}/api/api_section.h     \
                ${INCDIR}/api/api_string.h     \
                ${INCDIR}/api/api_struct.h     \
                ${INCDIR}/api/api_sys.h     \
                ${INCDIR}/api/api_target.h     \
                ${INCDIR}/api/api_xref.h     \
                ${INCDIR}/bastard.h       \
                ${INCDIR}/bdb.h           \
                ${INCDIR}/debug.h            \
                ${INCDIR}/db/db.h            \
                ${INCDIR}/db/db_bdb.h            \
                ${INCDIR}/db/db_query.h            \
                ${INCDIR}/db/db_def.h            \
                ${INCDIR}/db/db_int.h            \
                ${INCDIR}/db/environ.h       \
                ${INCDIR}/db/typhoon.h \
                ${INCDIR}/script/eic.h        \
                ${INCDIR}/script/eicval.h        \
                ${INCDIR}/script/macro.h         \
                ${INCDIR}/script/script_main.h   \
                ${INCDIR}/extension.h            \
                ${INCDIR}/vm.h            \
                ${INCDIR}/util.h         

ARCHDIR = arch
ASMDIR = asm
COMPDIR    = comp
ENGINEDIR    = engines
FORMATDIR    = formats
LANGDIR    = lang
OSDIR    = os
PLUGINDIR    = plugins
MOD_SRCS   = 			\
	${SRCDIR}/${ARCHDIR} 	\
	${SRCDIR}/${ASMDIR} 	\
	${SRCDIR}/${COMPDIR} 	\
	${SRCDIR}/${ENGINEDIR} 	\
	${SRCDIR}/${FORMATDIR} 	\
	${SRCDIR}/${LANGDIR} 	\
	${SRCDIR}/${OSDIR} 	\
	${SRCDIR}/${PLUGINDIR} 

MOD_DIRS   = $(PLUGINDIR) $(LANGDIR) $(ASMDIR) $(ARCHDIR) $(FORMATDIR) \
             $(ENGINEDIR) $(OSDIR) $(COMPDIR)


# ------------------------------------ LibDisasm Tarball Files -------
LIBDIS_SRC = ${SRCDIR}/arch/i386/libdisasm/i386.c \
             ${SRCDIR}/arch/i386/libdisasm/i386_invariant.c \
             ${SRCDIR}/arch/i386/libdisasm/libdis.c \
             ${SRCDIR}/arch/i386/libdisasm/bin_from_dump.pl \
             ${SRCDIR}/arch/i386/libdisasm/quikdis.c \
             ${SRCDIR}/arch/i386/libdisasm/testdis.c \
             ${SRCDIR}/arch/i386/libdisasm/Makefile 

LIBDIS_HDR = ${SRCDIR}/arch/i386/libdisasm/bastard.h \
             ${SRCDIR}/arch/i386/libdisasm/extension.h \
             ${SRCDIR}/arch/i386/libdisasm/i386.h \
             ${SRCDIR}/arch/i386/libdisasm/i386_opcode.h \
             ${SRCDIR}/arch/i386/libdisasm/i386.opcode.map \
             ${SRCDIR}/arch/i386/libdisasm/libdis.h \
             ${SRCDIR}/arch/i386/libdisasm/vm.h 

LIBDIS_BIN = ${SRCDIR}/arch/i386/libdisasm/libdisasm.so \
             ${SRCDIR}/arch/i386/libdisasm/libdis.h \
             ${SRCDIR}/arch/i386/libdisasm/quikdis.c \
             ${SRCDIR}/arch/i386/libdisasm/quikdis
             
# ------------------------------------ Tarfile collections -----------
DOCS       = doc .license README.* TODO KNOWN_BUGS
XTRA       = src/EiC src/typhoon
SCRIPTS    = scripts
DBD_FILES  = db/bdb.dbd db/cfg.dbd $(SRCDIR)/bdb.ddl $(SRCDIR)/cfg.ddl
REQ_FILES  = utils Makefile src/Makefile src/cli/Makefile $(DBD_FILES) \
		$(SCRIPTS) ${INCDIR} 
BAST_SRC   = $(SRCS) $(HDRS)\
             $(LIB_SRCS) $(LIB_HDRS) \
             $(MOD_SRCS) ${SRCDIR}/bobjdump ${SRCDIR}/sob ${SRCDIR}/bda \
		 ${SRCDIR}/bdbdump ${SRCDIR}/bdbview ${SRCDIR}/libbsql \
             $(REQ_FILES) $(DOCS) $(XTRA)
BAST_BIN   = $(BINDIR) $(MOD_DIRS) $(REQ_FILES) $(DOCS) ${INCDIR}/script/eic \
				 ./share ./lib/libbastard.so
ARCH_SRC   =  $(LIBDIS_SRC)  $(LIBDIS_HDR) doc/libi386.txt \
             utils/op-conv.pl
ARCH_BIN   = $(LIBDIS_BIN) doc/libi386.txt  





# ------------------------------------ Actual Makefile Rulesets ------
# This makefile really just builds tarballs, handles the install, 
# and calls other makefiles

all:            dirs bastard-all 

	@cd $(SRCDIR) && make extras-clean

dirs:
	@[ -d $(TOP)/include/script/eic ] || $(MKDIR) $(TOP)/include/script/eic
	@[ -d $(TOP)/$(LIBDIR) ]          || $(MKDIR) $(TOP)/$(LIBDIR)
	@[ -d $(TOP)/$(BINDIR) ]          || $(MKDIR) $(TOP)/$(BINDIR)
	@[ -d $(TOP)/$(SHAREDIR) ]        || $(MKDIR) $(TOP)/$(SHAREDIR)

bastard-all:
	@cd $(SRCDIR) && make all

extras: 
	@cd $(SRCDIR) && make extras

extras-clean: 
	@cd $(SRCDIR) && make extras-clean

man-install:
	@[ -d $(INSTALL_MAN)/man1 ] || $(MKDIR) $(INSTALL_MAN)/man1
	@[ -d $(INSTALL_MAN)/man3 ] || $(MKDIR) $(INSTALL_MAN)/man3
	@[ -d $(INSTALL_MAN)/man5 ] || $(MKDIR) $(INSTALL_MAN)/man5
	@[ -d $(INSTALL_MAN)/man7 ] || $(MKDIR) $(INSTALL_MAN)/man7
	@cp $(TOP)/doc/man/*.1  $(INSTALL_MAN)/man1/
	@cp $(TOP)/doc/man/*.3  $(INSTALL_MAN)/man3/
	@cp $(TOP)/doc/man/*.5  $(INSTALL_MAN)/man5/
	@cp $(TOP)/doc/man/*.7  $(INSTALL_MAN)/man7/

install: release man-install
	# cheat using tar
	$(MKDIR) $(INSTALL_DIR)
	@$(TAR) tmp_$(PROGRAM)-$(BASTARD_VERSION).tar $(BAST_BIN)
	@$(UNTAR) tmp_$(PROGRAM)-$(BASTARD_VERSION).tar -C$(INSTALL_DIR)
	@$(RM) tmp_$(PROGRAM)-$(BASTARD_VERSION).tar
	@echo Installing bastardly binaries...
	$(LN) $(INSTALL_DIR)/$(BINDIR)/$(PROGRAM) $(INSTALL_BIN)/$(PROGRAM)
	$(LN) $(INSTALL_DIR)/$(BINDIR)/lgb $(INSTALL_BIN)/lgb
	@cd src && make install
	@echo Installing bastardly libraries...
	$(LN) $(INSTALL_DIR)/lib/libbastard.so $(INSTALL_LIB)/libbastard.so
	@echo r00ting local machine...
	@ldconfig
	@echo j/k. Done with install.

uninstall:
	@echo You Bastard! 
	@echo Removing vital binaries...
	@$(RM) $(INSTALL_BIN)/$(PROGRAM) $(INSTALL_BIN)/lgb
	@echo Removing vital libraries...
	@$(RM) $(INSTALL_LIB)/libbastard.so
	@echo Trashing /usr filesystem in retribution for our fallen comrade...
	@$(RM) $(INSTALL_DIR) 
	@echo Done with uninstall.

third_party:
	@cd $(SRCDIR) && make third_party

typhoon:
	@cd $(SRCDIR) && make typhoon

eic:
	@cd $(SRCDIR) && make eic

extensions:
	@cd $(SRCDIR) && make extensions

ext-clean:
	@cd $(SRCDIR) && make ext-clean

libdisasm:
	@cd $(SRCDIR)/arch/i386/libdisasm && make

libdisasm-clean:
	@cd $(SRCDIR)/arch/i386/libdisasm && make clean

libbastard.a: $(LIBDIR)/libbastard.a

$(LIBDIR)/libbastard.a:
	@cd $(SRCDIR) && make ${TOP}/lib/libbastard.a
	
libbastard.so: $(LIBDIR)/libbastard.so
$(LIBDIR)/libbastard.so:
	@cd $(SRCDIR) && make ${TOP}/lib/libbastard.so

$(BINDIR)/$(PROGRAM):
	@cd $(SRCDIR) && make ${TOP}/bin/$(PROGRAM)

sob: bin/sob

bin/sob:
	@cd $(SRCDIR) && make sob

sob-install: dirs bin/sob
	@cd $(SRCDIR) && make sob-install

sob-uninstall: 
	@cd $(SRCDIR) && make sob-uninstall

sob-clean:
	@cd $(SRCDIR) && make sob-clean


# =============================== Utility Rules ===================
release: $(BINDIR)/$(PROGRAM)
	@strip $(BINDIR)/$(PROGRAM)
	@strip ./utils/ddlp
	@strip ./utils/dbdview
	@strip ./utils/tyexport
	@strip ./utils/tyimport

# ----------------------------- Cleanup
clean: 
	@echo Cleaning directories...
	@cd $(SRCDIR) && make clean
	@echo _____________________________________________________________
	@echo Done.

distclean: clean 
	@cd $(SRCDIR) && make distclean
	@$(RM) doc/man/catl/*
	@$(RM) doc/.*.swp
	@$(RM) doc/*~

# ----------------------------- Tarballs
tgz: tgz_bin tgz_src 
	@mv $(PROGRAM)-$(BASTARD_VERSION).tar.gz $(PROGRAM)-$(BASTARD_VERSION).tgz
	@mv $(PROGRAM)_bin-$(BASTARD_VERSION).tar.gz \
       $(PROGRAM)_bin-$(BASTARD_VERSION).tgz
	@mv libdisasm-$(BASTARD_VERSION).tar.gz libdisasm-$(BASTARD_VERSION).tgz
	@mv libdisasm_bin-$(BASTARD_VERSION).tar.gz \
       libdisasm_bin-$(BASTARD_VERSION).tgz
	@echo _____________________________________________________________
	@echo Done.

tgz_bin: $(ARCH_ARS) release libdisasm sob
	@echo _____________________________________________________________
	@echo Making binary tarballs...
	@$(TAR) $(PROGRAM)_bin-$(BASTARD_VERSION).tar $(BAST_BIN)
	@$(MKDIR) ./$(PROGRAM)-$(BASTARD_VERSION)
	@$(UNTAR) $(PROGRAM)_bin-$(BASTARD_VERSION).tar -C./$(PROGRAM)-$(BASTARD_VERSION)
	@$(RM) $(PROGRAM)_bin-$(BASTARD_VERSION).tar
	@$(TAR) $(PROGRAM)_bin-$(BASTARD_VERSION).tar $(PROGRAM)-$(BASTARD_VERSION)
	@$(RM) ./$(PROGRAM)-$(BASTARD_VERSION)
	@$(ZIP) $(PROGRAM)_bin-$(BASTARD_VERSION).tar

	@$(TAR) libdisasm_bin-$(BASTARD_VERSION).tar $(ARCH_BIN) 
	@$(MKDIR) ./libdisasm-$(BASTARD_VERSION)
	@$(UNTAR) libdisasm_bin-$(BASTARD_VERSION).tar -C./libdisasm-$(BASTARD_VERSION)
	@$(RM) libdisasm-$(BASTARD_VERSION).tar
	$(TAR) libdisasm_bin-$(BASTARD_VERSION).tar ./libdisasm-$(BASTARD_VERSION)
	@$(RM) ./libdisasm-$(BASTARD_VERSION)
	@$(ZIP) libdisasm_bin-$(BASTARD_VERSION).tar


tgz_src: distclean libdisasm-clean sob-clean
	@echo _____________________________________________________________
	@echo Making source tarballs...
	@$(TAR) $(PROGRAM)-$(BASTARD_VERSION).tar $(BAST_SRC)
	@$(MKDIR) ./$(PROGRAM)_src-$(BASTARD_VERSION)
	@$(UNTAR) $(PROGRAM)-$(BASTARD_VERSION).tar -C./$(PROGRAM)_src-$(BASTARD_VERSION)
	@$(RM) $(PROGRAM)-$(BASTARD_VERSION).tar 
	@$(TAR) $(PROGRAM)-$(BASTARD_VERSION).tar $(PROGRAM)_src-$(BASTARD_VERSION)
	@$(RM) ./$(PROGRAM)_src-$(BASTARD_VERSION)
	@$(ZIP) $(PROGRAM)-$(BASTARD_VERSION).tar

	@$(TAR) libdisasm-$(BASTARD_VERSION).tar $(ARCH_SRC) 
	@$(MKDIR) ./libdisasm_src-$(BASTARD_VERSION)
	@$(UNTAR) libdisasm-$(BASTARD_VERSION).tar -C./libdisasm_src-$(BASTARD_VERSION)
	@$(RM) libdisasm-$(BASTARD_VERSION).tar
	@$(TAR) libdisasm-$(BASTARD_VERSION).tar ./libdisasm_src-$(BASTARD_VERSION)
	@$(RM) ./libdisasm_src-$(BASTARD_VERSION)
	@$(ZIP) libdisasm-$(BASTARD_VERSION).tar

