###########################################################################
#
#	makefile
#
#	Core makefile for building SDLMAME and derivatives
#
#	Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
#	Visit http://mamedev.org for licensing and usage restrictions.
#
#	SDLMAME & SDLMESS by Olivier Galibert and R. Belmont
#	Copyright (c) 2003-2007 Olivier Galibert and R. Belmont.
#
#	Tip:
#	   Parameters passed to make/gmake override the values set in a makefile.
#	   So, for instance for a G4 optimized debug OS X build leave this makefile
#	   unaltered and type:
#	   make -f makefile.sdl TARGET=mess SUBARCH=macosx PM= G4=1 DEBUG=1
#
###########################################################################

###########################################################################
#################	BEGIN USER-CONFIGURABLE OPTIONS   #####################
###########################################################################

#-------------------------------------------------
# specify core target: mame, mess, etc.
# specify subtarget: mame, mess, tiny, etc.
# build rules will be included from
# $(TARGET)/$(SUBTARGET).mak
#-------------------------------------------------

ifndef TARGET
TARGET = mame
endif

ifndef SUBTARGET
SUBTARGET = $(TARGET)
endif

#-------------------------------------------------
# specify operating system: windows, msdos, etc.
# build rules will be includes from
# src/osd/$(MAMEOS)/$(MAMEOS).mak
#-------------------------------------------------

# for SDLMAME, MAMEOS is always "sdl"
ifndef MAMEOS
MAMEOS = sdl
endif

#------------------------------------------------------------------------------------
# for SDLMAME, set this to unix, win32, or macosx (lowercase is important!)
#------------------------------------------------------------------------------------

SUBARCH = os2


#-------------------------------------------------
# specify program options; see each option below
# for details
#-------------------------------------------------

# uncomment next line to include the debugger
# DEBUG = 1

# uncomment next line to use DRC MIPS3 engine
X86_MIPS3_DRC = 1

# uncomment next line to use DRC PowerPC engine
X86_PPC_DRC = 1

#-------------------------------------------------
# specify build options; see each option below
# for details
#-------------------------------------------------

# uncomment one of the next lines to build a target-optimized build
# ATHLON = 1
I686 = 1
# P4 = 1
# PM = 1
# AMD64 = 1
# G4 = 1
# G5 = 1
# CELL = 1

# uncomment next line if you are building for a 64-bit target
# PTR64 = 1

# uncomment next line to build expat as part of MAME build
BUILD_EXPAT = 1

# uncomment next line to build zlib as part of MAME build
BUILD_ZLIB = 1

# uncomment next line to include the symbols
# SYMBOLS = 1

# uncomment next line to generate a link map for exception handling in windows
# MAP = 1

# uncomment next line to build without OpenGL support
# NO_OPENGL = 1

# specify optimization level or leave commented to use the default
# (default is OPTIMIZE = 3 normally, or OPTIMIZE = 0 with symbols)
# OPTIMIZE = 3

###########################################################################
##################	 END USER-CONFIGURABLE OPTIONS	 ######################
###########################################################################


#-------------------------------------------------
# sanity check the configuration
#-------------------------------------------------

# disable DRC cores for PowerPC builds
ifdef G4
PPC = 1
endif

ifdef G5
PPC = 1
endif

ifdef CELL
PPC = 1
endif

ifdef PPC
X86_MIPS3_DRC =
X86_PPC_DRC =
endif

# disable DRC cores for 64-bit builds
ifdef PTR64
X86_MIPS3_DRC =
X86_PPC_DRC =
endif

# Mac builds always need EXPAT and ZLIB built
ifeq ($(SUBARCH),macosx)
BUILD_EXPAT = 1
BUILD_ZLIB = 1
endif

# ...as does MinGW
ifeq ($(SUBARCH),win32)
BUILD_EXPAT = 1
BUILD_ZLIB = 1
endif

ifeq ($(SUBARCH),os2)
BUILD_EXPAT = 1
BUILD_ZLIB = 1
NO_OPENGL = 1
endif

# specify a default optimization level if none explicitly stated
ifndef OPTIMIZE
ifndef SYMBOLS
OPTIMIZE = 3
else
OPTIMIZE = 0
endif
endif

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

# extension for executables
EXE =

ifeq ($(SUBARCH),win32)
EXE = .exe
endif

ifeq ($(SUBARCH),os2)
EXE = .exe
endif

# compiler, linker and utilities
AR = @ar
CC = @gcc
LD = @gcc
MD = -mkdir
RM = @rm -f



#-------------------------------------------------
# form the name of the executable
#-------------------------------------------------

# check if this is MESS
ifeq ($(TARGET),mess)
MESS=1
endif

# by default, don't compile for a specific target CPU
NAME = $(PREFIX)$(TARGET)
ARCH =

# architecture-specific builds get extra options
ifdef ATHLON
NAME = $(PREFIX)$(TARGET)at
ARCH = -march=athlon
endif

ifdef I686
NAME = $(PREFIX)$(TARGET)pp
ARCH = -march=pentiumpro
endif

ifdef P4
NAME = $(PREFIX)$(TARGET)p4
ARCH = -march=pentium4
endif

ifdef AMD64
NAME = $(PREFIX)$(TARGET)64
ARCH = -march=athlon64
endif

ifdef PM
NAME = $(PREFIX)$(TARGET)pm
ARCH = -march=pentium3 -msse2
endif

ifdef G4
NAME = $(PREFIX)$(TARGET)g4
ARCH = -mcpu=G4
endif

ifdef G5
NAME = $(PREFIX)$(TARGET)g5
ARCH = -mcpu=G5
endif

ifdef CELL
NAME = $(PREFIX)$(TARGET)cbe
ARCH =
endif

# debug builds just get the 'd' suffix and nothing more
ifdef DEBUG
NAME = $(PREFIX)$(TARGET)d
endif

EMULATOR = $(NAME)$(EXE)

# build the targets in different object dirs, since mess changes
# some structures and thus they can't be linked against each other.
OBJ = obj/$(NAME)

SRC = src


#-------------------------------------------------
# compile-time definitions
#-------------------------------------------------

ifdef PPC
DEFS = -DPPC_ASM -DINLINE="static __inline__" -Dasm=__asm__ -DPI=M_PI -Dstrnicmp=strncasecmp -D_scalb=scalb -DCRLF=2 -DGL_GLEXT_PROTOTYPES=1 -Dbool=int
else
ifdef PTR64
DEFS = -DLSB_FIRST -DINLINE="static __inline__" -Dasm=__asm__ -DPI=M_PI -Dstrnicmp=strncasecmp -D_scalb=scalb -DCRLF=2 -DGL_GLEXT_PROTOTYPES=1
else
DEFS = -DX86_ASM -DLSB_FIRST -DINLINE="static __inline__" -Dasm=__asm__ -DPI=M_PI -Dstrnicmp=strncasecmp -D_scalb=scalb -DCRLF=2 -DGL_GLEXT_PROTOTYPES=1
endif
endif

ifdef PTR64
DEFS += -DPTR64
endif

ifdef DEBUG
DEFS += -DMAME_DEBUG
endif

#-------------------------------------------------
# compile and linking flags
#-------------------------------------------------

CFLAGS = \
	$(OPT_FLAGS) \
	-std=gnu89 \
	-I$(SRC)/$(TARGET) \
	-I$(SRC)/$(TARGET)/includes \
	-I$(OBJ)/$(TARGET)/layout \
	-I$(SRC)/emu \
	-I$(OBJ)/emu \
	-I$(OBJ)/emu/layout \
	-I$(SRC)/lib/util \
	-I$(SRC)/osd \
	-I$(SRC)/osd/$(MAMEOS) \

ifdef MESS
CFLAGS += \
	-I$(SRC)/mame \
	-I$(SRC)/mame/includes \
	-I$(SRC)/mess/osd/$(MAMEOS)
endif

ifdef SYMBOLS
ifdef PPC
ifeq ($(SUBARCH),macosx)
CFLAGS += -g -mlong-branch
endif	# macosx
else
CFLAGS += -g
endif	# PPC
endif	# SYMBOLS

CFLAGS += $(ARCH) \
	-Wall \
	-Wpointer-arith \
	-Wbad-function-cast \
	-Wcast-align \
	-Wstrict-prototypes \
	-Wundef \
	-Wformat-security \
	-Wwrite-strings

ifneq ($(SUBARCH),os2)
CFLAGS += -Wdeclaration-after-statement
endif

ifneq ($(OPTIMIZE),0)
CFLAGS += -DNDEBUG $(ARCH) -fno-strict-aliasing
endif

CFLAGS += -O$(OPTIMIZE)

# extra options needed *only* for the osd files
CFLAGSOSDEPEND = $(CFLAGS)

LDFLAGS = -WO

ifdef SYMBOLS
LDFLAGS =
else
LDFLAGS += -s
endif

ifdef MAP
MAPFLAGS = -Wl,-Map,$(NAME).map
else
MAPFLAGS =
endif

#-------------------------------------------------
# define the standard object directory; other
# projects can add their object directories to
# this variable
#-------------------------------------------------

OBJDIRS = $(OBJ)

#-------------------------------------------------
# define standard libarires for CPU and sounds
#-------------------------------------------------

LIBEMU = $(OBJ)/libemu.a
LIBCPU = $(OBJ)/libcpu.a
LIBSOUND = $(OBJ)/libsound.a
LIBUTIL = $(OBJ)/libutil.a
LIBOCORE = $(OBJ)/libocore.a
LIBOSD = $(OBJ)/libosd.a

VERSIONOBJ = $(OBJ)/version.o


#-------------------------------------------------
# either build or link against the included
# libraries
#-------------------------------------------------

# start with an empty set of libs
LIBS =
# and here's flags that are applied only to linking the main executable
MAINLDFLAGS =

# add expat XML library
ifdef BUILD_EXPAT
CFLAGS += -I$(SRC)/lib/expat
EXPAT = $(OBJ)/libexpat.a
else
LIBS += -lexpat
EXPAT =
endif

# add ZLIB compression library
ifdef BUILD_ZLIB
CFLAGS += -I$(SRC)/lib/zlib
ZLIB = $(OBJ)/libz.a
else
LIBS += -lz
ZLIB =
endif

# add SDLMAME subarch definitions
ifeq ($(SUBARCH),linux)
SUBARCH = unix
endif

ifeq ($(SUBARCH),freebsd)
SUBARCH = unix
endif

ifeq ($(SUBARCH),unix)
CFLAGS += -DSDLMAME_UNIX -DSDLMAME_X11
endif

ifeq ($(SUBARCH),macosx)
CFLAGS += -DSDLMAME_UNIX -DSDLMAME_MACOSX
MAINLDFLAGS = -Xlinker -all_load
endif

ifeq ($(SUBARCH),win32)
CFLAGS += -DSDLMAME_WIN32
endif

ifeq ($(SUBARCH),os2)
CFLAGS += -DSDLMAME_OS2
endif


#-------------------------------------------------
# 'all' target needs to go here, before the
# include files which define additional targets
#-------------------------------------------------

all: maketree emulator tools



#-------------------------------------------------
# include the various .mak files
#-------------------------------------------------

# include OS-specific rules first
include $(SRC)/osd/$(MAMEOS)/$(MAMEOS).mak

# include OS-specific MESS stuff if we're MESS
ifdef MESS
include $(SRC)/mess/osd/$(MAMEOS)/$(MAMEOS).mak
endif

# then the various core pieces
include $(SRC)/$(TARGET)/$(SUBTARGET).mak
include $(SRC)/emu/emu.mak
include $(SRC)/lib/lib.mak
include $(SRC)/tools/tools.mak

# combine the various definitions to one
CDEFS = $(DEFS) $(COREDEFS) $(CPUDEFS) $(SOUNDDEFS)


#-------------------------------------------------
# primary targets
#-------------------------------------------------

emulator: maketree $(EMULATOR)

tools: maketree $(TOOLS)

maketree: $(sort $(OBJDIRS))

clean:
	@echo Deleting object tree $(OBJ)...
	$(RM) -r $(OBJ)
	@echo Deleting $(EMULATOR)...
	$(RM) $(EMULATOR)
	@echo Deleting $(TOOLS)...
	$(RM) $(TOOLS)

#-------------------------------------------------
# directory targets
#-------------------------------------------------

$(sort $(OBJDIRS)):
	$(MD) -p $@



#-------------------------------------------------
# executable targets and dependencies
#-------------------------------------------------

$(EMULATOR): $(VERSIONOBJ) $(DRVLIBS) $(LIBOSD) $(LIBEMU)  $(LIBCPU) $(LIBSOUND) $(LIBUTIL) $(EXPAT) $(ZLIB) $(LIBOCORE)
# always recompile the version string
	$(CC) $(CDEFS) $(CFLAGS) -c $(SRC)/version.c -o $(VERSIONOBJ)
	@echo Linking $@...
	$(LD) $(LDFLAGS) $(MAINLDFLAGS) $^ $(LIBS) -o $@ $(MAPFLAGS)

#-------------------------------------------------
# generic rules
#-------------------------------------------------

$(OBJ)/osd/$(MAMEOS)/%.o: $(SRC)/osd/$(MAMEOS)/%.c | $(OSPREBUILD)
	@echo Compiling $<...
	$(CC) $(CDEFS) $(CFLAGSOSDEPEND) -c $< -o $@

$(OBJ)/%.o: $(SRC)/%.c | $(OSPREBUILD)
	@echo Compiling $<...
	$(CC) $(CDEFS) $(CFLAGS) -c $< -o $@

$(OBJ)/%.pp: $(SRC)/%.c | $(OSPREBUILD)
	@echo Compiling $<...
	$(CC) $(CDEFS) $(CFLAGS) -E $< -o $@

$(OBJ)/%.s: $(SRC)/%.c | $(OSPREBUILD)
	@echo Compiling $<...
	$(CC) $(CDEFS) $(CFLAGS) -S $< -o $@

$(OBJ)/%.lh: $(SRC)/%.lay $(FILE2STR)
	@echo Converting $<...
	@$(FILE2STR)  $< $@ layout_$(basename $(notdir $<))

$(OBJ)/%.fh: $(SRC)/%.png $(PNG2BDC)
	@echo Converting $<...
	@$(PNG2BDC) $< $(OBJ)/temp.bdc
	@$(FILE2STR) $(OBJ)/temp.bdc $@ font_$(basename $(notdir $<)) UINT8

$(OBJ)/%.a:
	@echo Archiving $@...
	$(RM) $@
	$(AR) -cr $@ $^

$(OBJ)/%.o: src/%.m
	@echo Objective-C compiling $<...
	$(CC) $(CDEFS) $(CFLAGS) -c $< -o $@

