#
#  Shared makefile for building the Allegro library. Requires GNU make.
#
#  Available options:
#
#     Environment variables:
#        DEBUGMODE=1        selects a debug build.
#        DEBUGMODE=2        selects a build intended to debug Allegro itself.
#        PROFILEMODE=1      selects a profiling build.
#        WARNMODE=1         selects strict compiler warnings.
#        STATICLINK=1       use static linking (MinGW32, MSVC, BeOS).
#        TARGET_ARCH_COMPAT optimize for the given processor while preserving backwards
#                           compatibility with older processors (GCC-based platforms).
#        TARGET_ARCH_EXCL   optimize for the given processor; this will cause the library
#                           to *NOT* be backwards compatible (GCC-based platforms, MSVC).
#        TARGET_OPTS        allows you to customize general optimizations (GCC-based platforms).
#        CROSSCOMPILE=1     cross-build under Linux (DJGPP, MinGW32).
#        ALLEGRO_USE_C=1    use C drawing code instead of asm (GCC-based platforms).
#        UNIX_TOOLS=1       use Unix-like tools instead of DOS tools.
#
#     Targets: 
#        default:           build library version, docs, and programs.
#        all:               build all versions and programs.
#        lib:               build a single library only, no programs.
#        programs:          build all programs
#        install:           install single library version.
#        installall:        install all library versions.
#        uninstall:         remove Allegro from system directories.
#        docs:              convert documentation from ._tx sources.
#        chm-docs:          generate additinal docs in CHM format.
#        clean:             remove object files.
#        distclean:         remove objects and executables.
#        veryclean:         remove all generated files.
#        compress:          compress the executable files (DJGPP, MinGW32, MSVC).
#        depend:            regenerate the dependency files.



# -------- read version information --------

include makefile.ver



# -------- check environment to see what type of library to build --------

ifdef DEBUGMODE

# -------- build a debugging library --------
VERSION = alld
SHORT_VERSION = ald
VERY_SHORT_VERSION = ad
DESCRIPTION = debugging

else
ifdef PROFILEMODE

# -------- build a profiling library --------
VERSION = allp
SHORT_VERSION = alp
VERY_SHORT_VERSION = ap
DESCRIPTION = profiling

else

# -------- build a release library --------
VERSION = alleg
SHORT_VERSION = all
VERY_SHORT_VERSION = al
DESCRIPTION = optimised

endif
endif

ifdef STATICLINK
DESCRIPTION += statically linked
endif



# -------- list of what files we need to build --------

include makefile.lst

COMMON_OBJECTS = $(basename $(notdir $(ALLEGRO_SRC_FILES)))
C_OBJECTS = $(basename $(notdir $(ALLEGRO_SRC_C_FILES)))
I386_OBJECTS = $(basename $(notdir $(ALLEGRO_SRC_I386_FILES)))



# -------- include platform-specific definitions --------

ifneq (,$(findstring $(suffix $(MAKEFILE_INC)),.be .dj .mgw .osx .qnx))
   ifndef GCC_MTUNE
      gcc_version = $(subst ., ,$(shell gcc -dumpversion))
      ifeq (2,$(word 1,$(gcc_version)))
         GCC_MTUNE = -mcpu
      else
         ifeq (3,$(word 1,$(gcc_version)))
            ifneq (,$(filter 0% 1% 2% 3%,$(word 2,$(gcc_version))))
               GCC_MTUNE = -mcpu
            endif
         endif
      endif
      ifndef GCC_MTUNE
         GCC_MTUNE = -mtune
      endif
   endif
endif

include $(MAKEFILE_INC)

# rm doesn't support -v on Darwin
ifndef RM_OPTS
RM_OPTS = -fv
endif



# -------- list what objects and programs we need to build --------

VPATH += src demo docs examples setup tests tools tools/plugins docs/src/makedoc

OBJECTS = $(addprefix $(OBJ_DIR)/, $(addsuffix $(OBJ), $(OBJECT_LIST)))

OBJECTS_DOC = $(addprefix $(OBJ_DIR)/, $(addsuffix $(OBJ), $(basename $(notdir $(ALLEGRO_MAKEDOC_SOURCES)))))
OBJECTS_DEMO = $(addprefix $(OBJ_DIR)/, $(addsuffix $(OBJ), $(basename $(notdir $(ALLEGRO_DEMO_SOURCES)))))

PROGRAMS += $(notdir $(ALLEGRO_LIB_EXES) $(ALLEGRO_DATAFILE_EXES))

ifneq (,$(wildcard $(PLATFORM_DIR)/cpp-yes))
   CPP_PROGRAMS = $(notdir $(ALLEGRO_LIB_CPP_EXES))
else
ifeq (,$(wildcard $(PLATFORM_DIR)/cpp-tested))
   CPP_PROGRAMS = maybe-cpp-programs 
endif
endif

PROGRAMS += $(CPP_PROGRAMS) demo examples makedoc

EXAMPLES = $(basename $(notdir $(ALLEGRO_EXAMPLE_FILES)))

EXAMPLE_FILES = $(addprefix examples/, $(addsuffix $(EXE), $(EXAMPLES)))

ifdef HTML
# XXX this is duplicated in makefile.in
DOCBASEFILES = ahack changes faq mistakes help thanks allegro const abi api packfile \
               readme makedoc datafile grabber dat dat2c dat2s license
DOCBUILDFILES = bcc32 beos darwin djgpp dmc linux macosx mingw32 msvc qnx unix watcom
DOCTXTBUILDFILES = $(addprefix docs/build/,$(addsuffix .txt,$(DOCBUILDFILES)))

DOCS  = $(addprefix docs/txt/,$(addsuffix .txt,$(filter-out changes thanks readme, $(DOCBASEFILES))))
DOCS += $(addprefix docs/rtf/,$(addsuffix .rtf,$(DOCBASEFILES)))
DOCS += $(addprefix docs/html/,$(addsuffix .$(HTML),index $(DOCBASEFILES)))
DOCS += $(addprefix docs/html/build/,$(addsuffix .$(HTML),$(DOCBUILDFILES)))
DOCS += CHANGES AUTHORS THANKS readme.txt
DOCS += docs/scite/allegro.api
CHMDOCS  = $(addprefix docs/chm/,$(addsuffix .$(HTML),$(DOCBASEFILES)))
CHMDOCS += $(addprefix docs/chm/build/,$(addsuffix .$(HTML),$(DOCBUILDFILES)))

endif

ifdef INFO
DOCS += docs/texi/allegro.$(TEXI) docs/info/allegro.$(INFO)
endif



# -------- top level boss targets like "default" and "all" --------

.PHONY: default all msg lib install installall uninstall docs chm-docs \
        clean distclean veryclean create-install-dirs depend \
        $(PROGRAMS) $(CPP_PROGRAMS)

.PRECIOUS: $(OBJ_DIR)/%$(OBJ)

default: msg lib $(PROGRAMS) docs
	@echo The $(DESCRIPTION) $(PLATFORM) library has been compiled.
ifdef UNIX_TOOLS
	@echo Run \"make install\" with the options you passed to \"make\"
	@echo in order to complete the installation.
else
	@echo Run "make install" with the options you passed to "make"
	@echo in order to complete the installation.
endif

all:
	$(MAKE) msg lib
	$(MAKE) msg lib DEBUGMODE=1
	$(MAKE) msg lib PROFILEMODE=1
	@echo Compiling utilities, examples and test programs. Please wait...
	$(MAKE) $(PROGRAMS) docs
	@echo All $(PLATFORM) library versions have been compiled.
ifdef UNIX_TOOLS
	@echo Run \"make installall\" with the options you passed to \"make all\"
	@echo in order to complete the installation.
else
	@echo Run "make installall" with the options you passed to "make all"
	@echo in order to complete the installation.
endif

installall:
	$(MAKE) msg lib install
	$(MAKE) msg lib install DEBUGMODE=1
	$(MAKE) msg lib install PROFILEMODE=1
	@echo All $(PLATFORM) library versions have been installed.

msg:
	@echo Compiling Allegro for $(PLATFORM), $(DESCRIPTION). Please wait...

ifdef CROSSCOMPILE

docs:
	@echo Cannot build docs when cross-compiling.
else

docs: $(DOCS) $(DOCTXTBUILDFILES)
	@echo HTML help files have been generated.
ifdef UNIX_TOOLS
	@echo To generate a .CHM version, run \"make chm-docs\".
else
	@echo To generate a .CHM version, run "make chm-docs".
endif

endif # CROSSCOMPILE

lib: $(LIB_NAME)

$(LIB_NAME): $(OBJECTS) $(RUNNER)
	$(MAKE_LIB)

programs:
	$(MAKE) $(PROGRAMS)

# -------- rules for deleting the generated files --------

clean:
ifdef UNIX_TOOLS
	-rm $(RM_OPTS) $(OBJ_CLEAN_FILES)
	-rm $(RM_OPTS) $(OTHER_CLEAN_FILES)
else
   define RM_CLEAN
      $(foreach file, $(wildcard $(OBJ_CLEAN_FILES)), -del $(subst /,\,$(file))
      )
      $(foreach file, $(wildcard $(OTHER_CLEAN_FILES)), -del $(subst /,\,$(file))
      )
   endef
	-$(RM_CLEAN)
endif

distclean: clean
ifdef UNIX_TOOLS
	-rm $(RM_OPTS) $(DISTCLEAN_FILES)
else
   define RM_DISTCLEAN
      $(foreach file, $(wildcard $(DISTCLEAN_FILES)), -del $(subst /,\,$(file))
      )
   endef
	-$(RM_DISTCLEAN)
endif

veryclean: distclean
ifdef UNIX_TOOLS
	-rm $(RM_OPTS) $(VERYCLEAN_FILES)
else
   define RM_VERYCLEAN
      $(foreach file, $(wildcard $(VERYCLEAN_FILES)), -del $(subst /,\,$(file))
      )
   endef
	-$(RM_VERYCLEAN)
endif



# -------- rules for installing and removing the generic library files --------

INSTALL_DIRS := \
    $(INSTALLDIR)/$(LIBDIR) \
    $(INSTALLDIR)/$(INCDIR) \
    $(INSTALLDIR)/$(INCDIR)/allegro \
    $(INSTALLDIR)/$(INCDIR)/allegro/platform \
    $(INSTALLDIR)/$(INCDIR)/allegro/internal \
    $(INSTALLDIR)/$(INCDIR)/allegro/inline

ifdef BINDIR
    INSTALL_DIRS += $(INSTALLDIR)/$(BINDIR)
endif

ifdef UNIX_TOOLS
   INSTALL_DIRS := $(subst $(strip \),/,$(INSTALL_DIRS))
else
   INSTALL_DIRS := $(subst /,$(strip \),$(INSTALL_DIRS))
endif

create-install-dirs:
ifdef UNIX_TOOLS
	misc/mdhelper.sh $(INSTALL_DIRS)
else
   define MKDIRS
   $(foreach dir,$(INSTALL_DIRS),\
      misc\mdhelper.bat $(dir)
   )
   endef
	$(MKDIRS)
endif


INSTALLDIR_U = $(subst \,/,$(INSTALLDIR))
INSTALLDIR_D = $(subst /,\,$(INSTALLDIR))

LIBDIR_U = $(subst \,/,$(LIBDIR))
LIBDIR_D = $(subst /,\,$(LIBDIR))

INCDIR_U = $(subst \,/,$(INCDIR))
INCDIR_D = $(subst /,\,$(INCDIR))


ifdef UNIX_TOOLS

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/platform/%.h: include/allegro/platform/%.h
	cp $< $@

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/internal/%.h: include/allegro/internal/%.h
	cp $< $@

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/inline/%.inl: include/allegro/inline/%.inl
	cp $< $@

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/%.h: include/allegro/%.h
	cp $< $@

$(INSTALLDIR_U)/$(INCDIR_U)/%.h: include/%.h
	cp $< $@

else

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/platform/%.h: include/allegro/platform/%.h
	copy $(subst /,\,$< $@)

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/internal/%.h: include/allegro/internal/%.h
	copy $(subst /,\,$< $@)

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/inline/%.inl: include/allegro/inline/%.inl
	copy $(subst /,\,$< $@)

$(INSTALLDIR_U)/$(INCDIR_U)/allegro/%.h: include/allegro/%.h
	copy $(subst /,\,$< $@)

$(INSTALLDIR_U)/$(INCDIR_U)/%.h: include/%.h
	copy $(subst /,\,$< $@)

endif


INSTALL_FILES += $(INSTALLDIR_U)/$(INCDIR_U)/allegro.h                                                                         \
                 $(addprefix $(INSTALLDIR_U)/$(INCDIR_U)/allegro/,$(notdir $(wildcard include/allegro/*.h)))                   \
                 $(addprefix $(INSTALLDIR_U)/$(INCDIR_U)/allegro/internal/,$(notdir $(wildcard include/allegro/internal/*.h))) \
                 $(addprefix $(INSTALLDIR_U)/$(INCDIR_U)/allegro/inline/,$(notdir $(wildcard include/allegro/inline/*.inl)))

generic-install: create-install-dirs $(INSTALL_FILES)


UNINSTALL_FILES := \
    $(wildcard \
        $(filter-out \
            $(INSTALLDIR_U)/$(INCDIR_U)/allegro/platform/%, \
            $(UNINSTALL_FILES) \
        ) \
    ) \
    $(filter \
        $(INSTALLDIR_U)/$(INCDIR_U)/allegro/platform/%, \
        $(UNINSTALL_FILES) \
    ) \
    $(INSTALLDIR_U)/$(INCDIR_U)/allegro.h \
    $(wildcard \
        $(INSTALLDIR_U)/$(INCDIR_U)/allegro/*.h \
        $(INSTALLDIR_U)/$(INCDIR_U)/allegro/inline/*.inl \
        $(INSTALLDIR_U)/$(INCDIR_U)/allegro/internal/*.h \
    )

generic-uninstall:
ifdef UNIX_TOOLS
	-rm -fv $(UNINSTALL_FILES)
	-rmdir $(INSTALLDIR_U)/$(INCDIR_U)/allegro/platform
	-rmdir $(INSTALLDIR_U)/$(INCDIR_U)/allegro/inline
	-rmdir $(INSTALLDIR_U)/$(INCDIR_U)/allegro/internal
	-rmdir $(INSTALLDIR_U)/$(INCDIR_U)/allegro
else
   define RM_FILES
      $(foreach file, $(UNINSTALL_FILES), del $(subst /,\,$(file))
      )
   endef
	-$(RM_FILES)
	-rd $(INSTALLDIR_D)\$(INCDIR_D)\allegro\platform
	-rd $(INSTALLDIR_D)\$(INCDIR_D)\allegro\inline
	-rd $(INSTALLDIR_D)\$(INCDIR_D)\allegro\internal
	-rd $(INSTALLDIR_D)\$(INCDIR_D)\allegro
endif



# -------- rules for converting the documentation --------

MAKEDOC = docs/makedoc$(EXE)

docs/makedoc$(EXE): $(OBJECTS_DOC)
	$(LINK_WITHOUT_LIB)

ifdef HTML

chm-docs: docs/chm/allegro.chm

docs/chm/allegro.chm: $(filter %.$(HTML),$(CHMDOCS)) docs/src/allegro._tx $(OBJECTS_DOC) $(MAKEDOC)
	$(MAKEDOC) -chm docs/chm/allegro.$(HTML) docs/src/allegro._tx
	-hhc docs/chm/allegro.hhp

$(filter %.txt,$(filter-out readme.txt, $(DOCS))): docs/txt/%.txt: docs/src/%._tx $(MAKEDOC)
	$(MAKEDOC) -ascii $@ $<

$(DOCTXTBUILDFILES): docs/build/%.txt: docs/src/build/%._tx $(MAKEDOC)
	$(MAKEDOC) -ascii $@ $<

$(filter %.rtf,$(DOCS)): docs/rtf/%.rtf: docs/src/%._tx $(MAKEDOC)
	$(MAKEDOC) -rtf $@ $<

$(filter %.$(HTML),$(DOCS)): docs/html/%.$(HTML): docs/src/%._tx $(MAKEDOC)
	$(MAKEDOC) -$(HTML) $@ $<

$(filter %.$(HTML),$(CHMDOCS)): docs/chm/%.$(HTML): docs/src/%._tx $(MAKEDOC)
	$(MAKEDOC) -ochm -$(HTML) $@ $<

$(filter %.api,$(DOCS)): docs/scite/%.api: docs/src/%._tx $(MAKEDOC)
	$(MAKEDOC) -scite $@ $<

AUTHORS: docs/src/thanks._tx $(MAKEDOC)
	$(MAKEDOC) -part -ascii $@ $<
ifdef UNIX_TOOLS
	cp AUTHORS docs/txt/authors.txt
else
	copy AUTHORS docs\txt\authors.txt
endif

THANKS: docs/src/thanks._tx $(MAKEDOC)
	$(MAKEDOC) -part -ascii $@ $<
ifdef UNIX_TOOLS
	cp THANKS docs/txt/thanks.txt
else
	copy THANKS docs\txt\thanks.txt
endif

CHANGES: docs/src/changes._tx $(MAKEDOC)
	$(MAKEDOC) -ascii $@ $<
ifdef UNIX_TOOLS
	cp CHANGES docs/txt/changes.txt
else
	copy CHANGES docs\txt\changes.txt
endif

readme.txt: docs/src/readme._tx $(MAKEDOC)
	$(MAKEDOC) -ascii $@ $<
ifdef UNIX_TOOLS
	cp readme.txt docs/txt/readme.txt
else
	copy readme.txt docs\txt\readme.txt
endif

endif

ifdef INFO

$(filter %.$(TEXI),$(DOCS)): docs/texi/%.$(TEXI): docs/src/%._tx $(MAKEDOC)
	$(MAKEDOC) -$(TEXI) $@ $<

$(filter %.$(INFO),$(DOCS)): docs/info/%.$(INFO): docs/texi/%.$(TEXI) $(MAKEDOC)
	-makeinfo --no-split -o $@ $<

endif



# -------- special rules for linking win32 console applications --------

ifdef LINK_CONSOLE

tests/gfxinfo$(EXE): $(OBJ_DIR)/gfxinfo$(OBJ) $(LINK_CONSOLE_DEPS)
	$(LINK_CONSOLE)

tools/colormap$(EXE): $(OBJ_DIR)/colormap$(OBJ) $(LINK_CONSOLE_DEPS)
	$(LINK_CONSOLE)

tools/dat2c$(EXE): $(OBJ_DIR)/dat2c$(OBJ) $(LINK_CONSOLE_DEPS)
	$(LINK_CONSOLE)

tools/exedat$(EXE): $(OBJ_DIR)/exedat$(OBJ) $(LINK_CONSOLE_DEPS)
	$(LINK_CONSOLE)

tools/pack$(EXE): $(OBJ_DIR)/pack$(OBJ) $(LINK_CONSOLE_DEPS)
	$(LINK_CONSOLE)

tools/rgbmap$(EXE): $(OBJ_DIR)/rgbmap$(OBJ) $(LINK_CONSOLE_DEPS)
	$(LINK_CONSOLE)

tools/textconv$(EXE): $(OBJ_DIR)/textconv$(OBJ) $(LINK_CONSOLE_DEPS)
	$(LINK_CONSOLE)

endif



# -------- special rules for linking the datafile plugins --------

PLUGIN_SOURCES = $(wildcard tools/plugins/*.c)
PLUGIN_OBJS = $(OBJ_DIR)/datedit$(OBJ) $(addprefix $(OBJ_DIR)/,$(addsuffix $(OBJ),$(basename $(notdir $(PLUGIN_SOURCES)))))
PLUGIN_SCRIPTS = $(wildcard tools/plugins/*.$(PLUGIN_SCR))

ifneq ($(PLUGIN_SCRIPTS),)
PLUGIN_DEPS += $(PLUGIN_SCRIPTS)
endif

$(PLUGINS_H): $(wildcard tools/plugins/*.inc)
	$(GENERATE_PLUGINS_H)

$(PLUGIN_LIB): $(PLUGIN_OBJS)
	$(MAKE_PLUGIN_LIB)

ifndef LINK_CONSOLE_WITH_PLUGINS
LINK_CONSOLE_WITH_PLUGINS = $(LINK_WITH_PLUGINS)
endif

tools/dat$(EXE): $(OBJ_DIR)/dat$(OBJ) $(PLUGIN_DEPS)
	$(LINK_CONSOLE_WITH_PLUGINS)

tools/dat2s$(EXE): $(OBJ_DIR)/dat2s$(OBJ) $(PLUGIN_DEPS)
	$(LINK_CONSOLE_WITH_PLUGINS)

tools/grabber$(EXE): $(OBJ_DIR)/grabber$(OBJ) $(PLUGIN_DEPS)
	$(LINK_WITH_PLUGINS)

tools/pat2dat$(EXE): $(OBJ_DIR)/pat2dat$(OBJ) $(PLUGIN_DEPS)
	$(LINK_CONSOLE_WITH_PLUGINS)



# -------- dependencies for the demo game --------

demo/demo$(EXE): $(OBJECTS_DEMO)


# -------- special rules for C++ programs --------

maybe-cpp-programs: $(PLATFORM_DIR)/cpp-tested
	$(MAKE) cpp-programs

cpp-programs: $(CPP_PROGRAMS)



# -------- shortcuts for building various programs --------

demo: demo/demo$(EXE)
makedoc: docs/makedoc$(EXE)
keyconf: setup/keyconf$(EXE)
setup: setup/setup$(EXE)
afinfo: tests/afinfo$(EXE)
akaitest: tests/akaitest$(EXE)
cpptest: tests/cpptest$(EXE)
digitest: tests/digitest$(EXE)
filetest: tests/filetest$(EXE)
gfxinfo: tests/gfxinfo$(EXE)
mathtest: tests/mathtest$(EXE)
miditest: tests/miditest$(EXE)
play: tests/play$(EXE)
playfli: tests/playfli$(EXE)
test: tests/test$(EXE)
vesainfo: tests/vesainfo$(EXE)
colormap: tools/colormap$(EXE)
dat: tools/dat$(EXE)
dat2c: tools/dat2c$(EXE)
dat2s: tools/dat2s$(EXE)
exedat: tools/exedat$(EXE)
grabber: tools/grabber$(EXE)
pack: tools/pack$(EXE)
pat2dat: tools/pat2dat$(EXE)
rgbmap: tools/rgbmap$(EXE)
textconv: tools/textconv$(EXE)
examples: $(EXAMPLE_FILES)



# -------- automatic source dependencies --------

-include $(OBJ_DIR)/makefile.dep

