#
# Makefile - Generates corelib.vcproj, datastructs.vcproj, alg.vcproj, and
# network.vcproj, components.vcproj, dbgroup_utils.sln.  This makefile uses
# GNU make (NOT Microsoft's nmake), which is
# located in the 'utils' subdirectory, along with several other useful
# utilities.  These utilities are (mostly) from the UnxUtils package,
# available at:
#
#     http://unxutils.sourceforge.net/
#
# Visual Studio .NET 2003 (Visual C++ 7.10) required!!!
#
#
# @author Tony Novak (afn@cs.cornell.edu)
# @version 1.4
# @date 13 April 2004
#

############################################################################
# Parameters                                                               #
############################################################################

# Components to be built as libraries
LIBS = corelib xml datastructs alg network components server clp deweyid diskstructs

# Components to be built as executables (linked against ALL the libraries)
BINS =

# Top-level directory of dbgroup-utils
TOP_DIR = ../..

# Distribution directory
DISTRIB = $(TOP_DIR)/distrib/win32

# Directories to search for source files.  The $(NAME) parameter can be used
# to refer to the name of the current library (e.g. "corelib")
SRC = $(TOP_DIR)/$(NAME)/src

# Directories to search for include files.  This may also use $(NAME).
INC = $(TOP_DIR)/$(NAME)/src

# Distribution directory for include files.  This may also use $(NAME).
DISTRIB_INC = $(DISTRIB)/$(NAME)/inc/cudb/$(NAME)

# Files to exclude from source
EXCLUDE_SRC =

# Files to exclude from includes
EXCLUDE_INC =

# Valid extensions for source files
SRC_EXT = cpp cc

# Valid extensions for include files
INC_EXT = h hh

# Directories to exclude from both source and include files.  Any directory
# with any of these names, anywhere in the directory tree, will not be
# considered.
EXCLUDE_DIRS = t

# The name of the solution
SOLUTION_NAME = dbgroup_utils

# Additional include directories
INC_PATH = $(foreach NAME,$(COMPONENTS),$(DISTRIB)/$(NAME)/inc;)

# Custom action(s) to take after everything else is done
define CUSTOM
@echo "Copying header files to $(DISTRIB)..." | $(FORMAT)
$(foreach NAME,$(COMPONENTS),
	$(MKDIR) -p $(DISTRIB_INC)
	CMD /C 'XCOPY /Y/S/C $(subst /,\,$(SRC)/*.h $(DISTRIB_INC)) >NUL'
)
endef

# You shouldn't need to modify anything past this point...

############################################################################
# Environment                                                              #
############################################################################

# Directories
WIN32  = .
BIN    = $(WIN32)/utils

# Shell
SHELL := $(WIN32)\utils\sh.exe

# Various commands
RM      = $(BIN)/rm.exe
MKDIR   = $(BIN)/mkdir.exe
SED     = $(BIN)/sed.exe
FIND    = $(BIN)/find.exe
CAT     = $(BIN)/cat.exe
GAWK    = $(BIN)/gawk.exe
FLEX    = $(BIN)/flex.exe
BISON   = $(BIN)/bison.exe
GENGUID = $(BIN)/GenGUID.exe
ZIP     = $(BIN)/zip.exe
UNZIP   = $(BIN)/unzip.exe

# Path to template files
TEMPLATE   = $(WIN32)/templates

# Path to awk (and other) scripts
SCRIPTS    = $(WIN32)/scripts

# Used to make messages real pretty ;-b
FORMAT     = $(GAWK) '{ $$0 = "==> " $$0 " <=="; printf("\n%" (40-length($$0)/2) "s%s\n\n", "", $$0) }'

# AWK script used to create the solution file
SLN_FILE   = $(WIN32)/$(SOLUTION_NAME).sln
SLN_SCRIPT = $(SCRIPTS)/make_solution.af

# Project files
COMPONENTS = $(LIBS) $(BINS)
PROJECTS   = $(foreach p,$(COMPONENTS),$(p).vcproj)
export COMPONENTS

# Generate GUIDs for anything that needs one
GUIDVAR = GUID_$(subst -,,$(1))
GETGUID = $($(call GUIDVAR,$(1)))
$(foreach _,$(COMPONENTS),$(eval $(call GUIDVAR,$(_)) := $$(shell $(GENGUID))))

# Command used to expand macros in template files
EXPAND_MACROS = $(SED) -e 's/__VCVERSION__/$(VCVERSION)/g' \
                       -e 's/__VSVERSION__/$(VSVERSION)/g' \
                       -e 's/__NAME__/$(NAME)/g' \
                       $(foreach onelib, $(LIBS), -e 's/__LIBS__/$(onelib).lib __LIBS__ /g') \
                       -e 's/__LIBS__//g' \
                       -e 's/__GUID__/$(call GETGUID,$(NAME))/g' \
			           -e 's/__ADDITIONAL_DEPENDENCIES__/$(call GETDEPS,$(NAME))/g' \
			           -e 's/__ADDITIONAL_DEPENDENCIES_DEBUG__/$(call GETDEPS_DEBUG,$(NAME))/g'\
			           -e 's/__ADDITIONAL_LIBRARY_PATH__/$(subst /,\\,$(LIB_PATH) $(EXTLIB_LIB_PATH))/g'\
			           -e 's/__INCLUDE_PATH__/$(subst /,\\,$(INC_PATH) $(EXTLIB_INC_PATH))/g' \
                       $(foreach _,$(COMPONENTS),-e 's/__GUID_$(_)__/$(call GETGUID,$(_))/g')

EXPAND_MACROS_EX = $(if $(wildcard $(1)),$(EXPAND_MACROS) $(1) >> $(2),)

# Needed by bison...
export BISON_SIMPLE := $(BIN)/bison.simple

# Make targets
TARGETS = $(SLN_FILE) \
          $(PROJECTS)

CLEAN   = $(TARGETS) $(wildcard *.suo *.ncb)

# Command line to generate list of source files
FIND_SRC = $(FIND) $(subst /,\\,$(1)) \
           ! \( \( -false $(foreach ex,$(EXCLUDE_DIRS),-o -name '$(ex)') \) -prune \) \
           \( -false $(foreach ext,$(SRC_EXT),-o -name '*.$(ext)') \) \
           $(foreach ex,$(EXCLUDE_SRC),! -path '$(subst /,\\,$(SRC)/$(ex))') \
           -print

# Command line to generate list of include files
FIND_INC = $(FIND) $(subst /,\\,$(1)) \
           \( -false $(foreach ext,$(INC_EXT),-o -name '*.$(ext)') \) \
           ! \( \( -false $(foreach ex,$(EXCLUDE_DIRS),-o -name '$(ex)') \) -prune \) \
           $(foreach ex,$(EXCLUDE_INC),! -path '$(subst /,\\,$(SRC)/$(ex))') \
           -print

# The extlib libraries
EXTLIBS_DIR_LST = $(notdir $(filter-out %/CVS, $(wildcard ../../extlib/win32/* ) ))
EXTLIBS_INCZIP_LST = $(foreach  d, \
                                $(EXTLIBS_DIR_LST), \
                                $(if $(wildcard ../../extlib/win32/$(d)/inc.zip), $(d),) )
EXTLIBS_INCZIP_TARGETS = $(foreach d, $(EXTLIBS_INCZIP_LST), unzip-$(d))

# Value for "AdditionalDependencies" in the vcproj file
#DEPS_utils = rpcrt4.lib
#GETDEPS = $(DEPS_$(1))

GETDEPS = $(foreach NAME,$(DEPS_$(1)),$(NAME).lib)
GETDEPS_DEBUG = $(foreach NAME,$(DEPS_$(1)),$(NAME)_D.lib)
EXTLIB_INC_PATH = $(foreach NAME,$(EXTLIBS_DIR_LST),$(TOP_DIR)/extlib/win32/$(NAME)/inc;)
EXTLIB_LIB_PATH = $(foreach NAME,$(EXTLIBS_DIR_LST),$(TOP_DIR)/extlib/win32/$(NAME)/lib;)


# Version of Visual C++ / Visual Studio
VCVERSION      = 7.10
VSVERSION      = 8.00
VSVERSION_NAME = .NET 2003

############################################################################
# Basic rules                                                              #
############################################################################

all: clean project $(EXTLIBS_INCZIP_TARGETS)

clean:
	@echo "Cleaning up existing files..." | $(FORMAT)
	$(RM) -f $(CLEAN)

project: $(TARGETS)
	@echo EXTLIBS: $(EXTLIBS_DIR_LST)
	@echo EXTLIBS: $(EXTLIBS_INCZIP_LST)
	$(CUSTOM)
	@echo "Finished successfully!" | $(FORMAT)
	@echo "Set up for Visual Studio $(VSVERSION_NAME) (Visual C++ $(VCVERSION))" | $(FORMAT)

copy-msg:
	@echo "Copying files from template directory..." | $(FORMAT)

.PHONY: all clean project copy-msg $(COMPONENTS)

NAME = $(@:.vcproj=)
WHICH = $(if $(filter $(NAME),$(LIBS)),_LIB,_BIN)

$(PROJECTS):
	@echo "Generating project file $@..." | $(FORMAT)
	$(RM) -f $@
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/_DEFAULT.vcproj.inc1,$@)
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/$(WHICH).vcproj.inc1,$@)
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/$(NAME).vcproj.inc1,$@)
	$(call FIND_SRC,$(SRC)) | $(GAWK) -f $(SCRIPTS)/make_vcproj_filelist.af >> $@
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/_DEFAULT.vcproj.inc2,$@)
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/$(WHICH).vcproj.inc2,$@)
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/$(NAME).vcproj.inc2,$@)
	$(call FIND_INC,$(INC)) | $(GAWK) -f $(SCRIPTS)/make_vcproj_filelist.af >> $@
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/_DEFAULT.vcproj.inc3,$@)
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/$(WHICH).vcproj.inc3,$@)
	$(call EXPAND_MACROS_EX,$(TEMPLATE)/$(NAME).vcproj.inc3,$@)

$(firstword $(COPY_TO)): copy-msg

$(SLN_FILE): $(SLN_SCRIPT)
	$(GAWK) -f "$<" | $(EXPAND_MACROS) > "$@"

$(EXTLIBS_INCZIP_TARGETS): unzip-%:
	echo Updating $*/inc
	$(RM) -rf $(TOP_DIR)/extlib/win32/$*/inc
	cd $(TOP_DIR)/extlib/win32/$* && ../../../platforms/win32/$(UNZIP) -a -o inc.zip
