# defines needed by the rest of the makefile
PROGRAM = bastard
BASTARD_VERSION = 0.17
TOP     = $(PWD)
INSTALL_DIR = /usr/local
export TOP PROGRAM BASTARD_VERSION INSTALL_DIR 

# tool/compiler defaults 
MAKE    = gmake
LIBDL   = -ldl
LSLIST  = `ls -1A | grep -v CVS`
CC      = cc
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
TERM    = -lcurses
# these are runtime defaults for the bastard
B_DEF_TGTPATH 	= 	.
B_DEF_TGT 		= 	a.out
B_DEF_ARCH		=	i386
B_DEF_ASM		=	intel
B_DEF_COMP		=	gcc
B_DEF_FMT		=	MAGIC
B_DEF_LANG		=	C
B_DEF_OS		=	linux
B_PREF_PAGER	=	less
B_PREF_EDITOR	=	vim
B_PREF_DEBUG	=	gdb

# override with OS-Specific options 
OSTYPE = $(shell uname -s)
CPUTYPE = $(shell uname -m)

ifeq ($(OSTYPE), Linux)
CC      = 	gcc
MAKE    = 	make
LSLIST  = 	`ls -1aA -ICVS`
TERM    = 	-lncurses
endif

ifeq ($(OSTYPE), FreeBSD)
CC      		= 	gcc
LIBDL			= 	-lc
TERM    		= 	-lncurses
B_DEF_ASM		=	att
B_DEF_OS		=	freebsd
B_PREF_EDITOR	=	vi
endif

ifeq ($(OSTYPE), SunOS)
CC      = cc
B_DEF_ARCH		=	SPARC
B_DEF_ASM		=	att
B_DEF_OS		=	solaris
B_PREF_EDITOR	=	vi
endif

# no, this isn't used yet :) 
ifeq ($(CPUTYPE), i386)
ENDIAN  = little
endif

ifeq ($(CPUTYPE), sun4u)
ENDIAN  = big
endif

export CC AR MAKE RM CP LN MKDIR TERM LIBDL LSLIST ENDIAN
export B_DEF_TGT B_DEF_ARCH B_DEF_ASM B_DEF_COMP B_DEF_FMT B_DEF_LANG
export B_DEF_OS B_PREF_PAGER B_PREF_EDITOR B_PREF_DEBUG


# Change INSTALL_DIR to customize!
INSTALL_BIN = $(INSTALL_DIR)/bin
INSTALL_LIB = $(INSTALL_DIR)/lib
INSTALL_MAN = $(INSTALL_DIR)/man
INSTALL_INC = $(INSTALL_DIR)/include/bastard
INSTALL_SHARE = $(INSTALL_DIR)/share/bastard
export INSTALL_LIB INSTALL_INC INSTALL_BIN INSTALL_SHARE INSTALL_MAN

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 		= $(TOP)/share/arch
ASMDIR 		= $(TOP)/share/asm
COMPDIR    		= $(TOP)/share/comp
ENGINEDIR    	= $(TOP)/share/engines
FORMATDIR    	= $(TOP)/share/formats
LANGDIR    		= $(TOP)/share/lang
OSDIR			= $(TOP)/share/os
PLUGINDIR    	= $(TOP)/share/plugins
MOD_SRCS   = 			\
	${SRCDIR}/arch 		\
	${SRCDIR}/asm 		\
	${SRCDIR}/comp 		\
	${SRCDIR}/engines 	\
	${SRCDIR}/formats 	\
	${SRCDIR}/lang 		\
	${SRCDIR}/os 		\
	${SRCDIR}/plugins 

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

EXTRA_SRCS = 		${SRCDIR}/bobjdump 	\
			${SRCDIR}/sob 		\
			${SRCDIR}/bda 		\
			${SRCDIR}/bdbdump 	\
			${SRCDIR}/bdbview 	\
			${SRCDIR}/libbsql 	\
			${SRCDIR}/lgb		\
			${SRCDIR}/qbastard
             

# ------------------------------------ Tarfile collections -----------
DOCS       = doc .license README.* TODO KNOWN_BUGS
XTRA       = src/EiC src/typhoon
SCRIPTS    = share/scripts
DBD_FILES  = share/db/bdb.dbd share/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) $(EXTRA_SRCS)  	\
             $(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)
	@([ -d $(TOP)/$(SHAREDIR)/bastard ]  && $(RM) $(TOP)/$(SHAREDIR)/bastard)\
		|| [ 1 ] 
	@[ -L $(TOP)/$(SHAREDIR)/bastard ]  || $(LN) $(TOP)/$(SHAREDIR)  \
		$(TOP)/$(SHAREDIR)/bastard
	@[ -L $(TOP)/$(INCDIR)/bastard ]  || $(LN) $(TOP)/$(INCDIR) \
		$(TOP)/$(INCDIR)/bastard
	@# cleanup dirs made by cvs
	@([ -d $(TOP)/asm ] && $(RM) $(TOP)/asm) || [ 1 ]
	@([ -d $(TOP)/arch ] && $(RM) $(TOP)/arch) || [ 1 ]
	@([ -d $(TOP)/comp ] && $(RM) $(TOP)/comp) || [ 1 ]
	@([ -d $(TOP)/db ] && $(RM) $(TOP)/db) || [ 1 ]
	@([ -d $(TOP)/engines ] && $(RM) $(TOP)/engines) || [ 1 ]
	@([ -d $(TOP)/formats ] && $(RM) $(TOP)/formats) || [ 1 ]
	@([ -d $(TOP)/lang ] && $(RM) $(TOP)/lang) || [ 1 ]
	@([ -d $(TOP)/os ] && $(RM) $(TOP)/os) || [ 1 ]
	@([ -d $(TOP)/plugins ] && $(RM) $(TOP)/plugins) || [ 1 ]
	@([ -d $(TOP)/scripts ] && $(RM) $(TOP)/scripts) || [ 1 ]

bastard-all: dirs
	@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: all release man-install
	@[ -d $(INSTALL_BIN) ] || $(MKDIR) $(INSTALL_BIN)
	@[ -d $(INSTALL_LIB) ] || $(MKDIR) $(INSTALL_LIB)
	@[ -d $(INSTALL_INC) ] || $(MKDIR) $(INSTALL_INC)
	@[ -d $(INSTALL_SHARE) ] || $(MKDIR) $(INSTALL_SHARE)
	@[ -L $(TOP)/$(SHAREDIR)/bastard ]  && rm $(TOP)/$(SHAREDIR)/bastard
	@[ -L $(TOP)/$(INCDIR)/bastard ]    && rm $(TOP)/$(INCDIR)/bastard 
	@cd src && $(MAKE) install
	@cp -r $(TOP)/include/* $(INSTALL_INC)
	@cp -r $(TOP)/share/* $(INSTALL_SHARE)
	@cp -r $(TOP)/.license $(INSTALL_SHARE)
	@[ -d $(INSTALL_SHARE)/utils ] || $(MKDIR) $(INSTALL_SHARE)/utils
	@cp -r $(TOP)/utils/* $(INSTALL_SHARE)/utils
	@[ -d $(INSTALL_SHARE)/doc ] || $(MKDIR) $(INSTALL_SHARE)/doc
	@cp -r $(TOP)/doc/* $(INSTALL_SHARE)/doc
	@cp $(TOP)/README* $(TOP)/KNOWN_BUGS $(TOP)/TODO $(INSTALL_SHARE)/doc
	@echo r00ting local machine...
	@ldconfig
	@echo j/k. Done with install.

uninstall:
	@echo You Bastard! 
	@cd src && $(MAKE) uninstall
	@echo Trashing /usr filesystem in retribution for our fallen comrade...
	@[ -d $(INSTALL_INC) ] && rm -r $(INSTALL_INC)
	@[ -d $(INSTALL_SHARE) ] && rm -r $(INSTALL_SHARE)
	@echo Done with uninstall.

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

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

typhoon-clean:
	@cd $(SRCDIR) && $(MAKE) typhoon-clean

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

eic-clean:
	@cd $(SRCDIR) && $(MAKE) eic-clean

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

qbastard:
	cd src/qbastard && $(MAKE)

qbastard-install:
	cd src/qbastard && $(MAKE) install


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

	
# Generate .bdb from .ddl 
bdb.dbd: src/bdb.ddl typhoon
	@utils/ddlp src/bdb.ddl
	@utils/fix_bdb.sh bdb.h include/bdb.h
	@mv bdb.dbd share/db/bdb.bdb
	@cp bdb.ddl share/db/bdb.ddl

dbd:	typhoon bdb.dbd
	
	

# ----------------------------- Cleanup
clean: 
	@echo Cleaning directories...
	@(cd $(SRCDIR) && $(MAKE) clean) || [ 1 ]
	@([ -L $(TOP)/$(SHAREDIR)/bastard ]  && rm $(TOP)/$(SHAREDIR)/bastard) || [ 1 ]
	@([ -L $(TOP)/$(INCDIR)/bastard ]    && rm $(TOP)/$(INCDIR)/bastard) || [ 1 ] 
	@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

