# This Makefile is partially based on "a completely generic Makefile",
# originally created by Justin Husted <husted@cs>
#
# Rewrite and sane dependencies support by Petr Baudis <pasky@ucw.cz>
# Cygwin support and configuration by Jaen Saul <slowbyte@hot.ee>
#
# Last modified by: $Author: strigeus $
# On: $Date: 2004/03/11 19:15:06 $


##############################################################################
#
# Usage
#

# Synopsis:
#
# make WITH_ZLIB=1 UNIX=1 MANUAL_CONFIG=1
#
# (See below for the list of possible options.)
#
# Alternately, you can run make without the MANUAL_CONFIG part. It then
# generates Makefile.config, where you can customize all the options.
# However beware that for all subsequent calls the option values from
# Makefile.config take precedence to the commandline options.
#
# (That means that you probably want to either specify the options on command
# line together with MANUAL_CONFIG=1 or you want to specify no commandline
# options at all.)

# Targets:
#
# Defaults to building binary
# clean: remove intermediate build files
# mrproper: remove intermediate files and makefile configuration
# upgradeconf: add new options to old Makefile.config
# osx: OS X application

# Options:
#
# Summary of OS choice defines
# WIN32: building on Windows
# UNIX: building on *nix derivate (Linux)
# OSX: building on Mac OS X
#
# Summary of library choice defines
# WITH_ZLIB: savegames using zlib
# WITH_PNG: screenshots using PNG
# WITH_SDL: SDL video driver support
#
# Summary of other defines:
# MANUAL_CONFIG: do not use Makefile.config, config options set manually
# DEBUG: build in debug mode
# TRANSLATOR: build in translator mode (untranslated strings are prepended by
#             a <TODO> mark)
# RELEASE: (OSX only) This will be diplayed as version in the get info window
#                     if it is not set, it will display the revision number
# STATIC: link statically
# CYGWIN: build in Cygwin environment
# MINGW: build with MingW compiler, link with MingW libraries
#
# Experimental (does not work properly):
# WITH_NETWORK: enable networking
# WITH_DIRECTMUSIC: enable DirectMusic MIDI support


##############################################################################
#
# Configuration
#

ifndef MANUAL_CONFIG
# Automatic configuration
MAKE_CONFIG:=Makefile.config
MAKEFILE:=Makefile

# Apply automatic configuration
# See target section for how this is built, suppress errors
# since first time it isn't found but make reads this twice
-include $(MAKE_CONFIG)
else
CONFIG_INCLUDED:=1
endif


ifndef CONFIG_INCLUDED
# Configuration is not available yet, so set up meaningful defaults
# Automatically recognize if building on Win32
ifdef WINDIR
ifndef UNIX
WIN32:=1
endif
else
UNIX:=1
endif

# Automatically recognize if building on MacOSX
ifeq ($(VENDOR), apple)
OSX:=1
endif

ifdef OSX
UNIX:=1
endif

# Library detections

WITH_SDL:=$(shell sdl-config --version 2>/dev/null)
WITH_PNG:=$(shell libpng-config --version 2>/dev/null)

# Library defaults

# Default to zlib on, that can be changed in Makefile.config
WITH_ZLIB:=1

endif


# Force SDL on UNIX platforms
ifndef WITH_SDL
ifdef UNIX
$(error You need to have SDL installed in order to run OpenTTD on UNIX.)
endif
endif


##############################################################################
#
# Compiler configuration
#

CC=gcc
CXX=g++

# Executable file extension
ifdef WIN32
EXE=.exe
else
EXE=
endif

# Set output executable names
TTD=ttd$(EXE)
STRGEN=strgen/strgen$(EXE)
OSXAPP="Open Transport Tycoon.app"

# What revision are we compiling, if we have an idea?
REV := $(shell if test -d .svn; then echo -n r; svnversion .; fi)

# When calling the compiler, use these flags
# -g	debugging symbols
# -Wall	all warnings
# -s    automatic strip
#
# You may also want:
# -O	optimize or -O2 fully optimize (O's above 2 are not recommended)
# -pg	profile - generate profiling data.  See "man gprof" to use this.

CFLAGS=-Wall -Wno-multichar
CDEFS=-DWITH_REV
LDFLAGS=
LIBS=

ifdef DEBUG
# Debug mode
CDEFS += -D_DEBUG
BASECFLAGS += -g
else
# Release mode
BASECFLAGS += -s
LDFLAGS += -s

ifdef OSX
# these compilerflags makes the app run as fast as possible without making the app unstable. It works on G3 or newer
CFLAGS += -O3 -funroll-loops -fsched-interblock -falign-loops=16 -falign-jumps=16 -falign-functions=16 -falign-jumps-max-skip=15 -falign-loops-max-skip=15 -mdynamic-no-pic -mpowerpc-gpopt -force_cpusubtype_ALL -fstrict-aliasing 
else
BASECFLAGS += -O2 -fomit-frame-pointer
endif

endif

ifdef STATIC
ifndef OSX	# OSX can't build static if -static flag is used (why?)
LDFLAGS += -static
endif
endif

# If building on Cygwin/MingW don't link with Cygwin libs
ifdef WIN32
ifdef MINGW
ifdef CYGWIN
BASECFLAGS += -mno-cygwin
LDFLAGS += -mno-cygwin
endif
endif
endif

CFLAGS += $(BASECFLAGS)

ifdef UNIX
CDEFS += -DUNIX
endif

# SDL config
ifdef WITH_SDL
CDEFS += -DWITH_SDL
CFLAGS += `sdl-config --cflags`
ifdef STATIC
LIBS += `sdl-config --static-libs`
else
LIBS += `sdl-config --libs`
endif
endif

# zlib config
ifdef WITH_ZLIB
CDEFS +=  -DWITH_ZLIB
LIBS += -lz
endif

# libpng config
ifdef WITH_PNG
CDEFS += -DWITH_PNG
CFLAGS += `libpng-config --cflags`
ifdef OSX
ifdef STATIC
# Seems like we need a tiny hack for OSX static to work
LIBS += `libpng-config --prefix`/lib/libpng.a
else
LIBS += `libpng-config  --libs`
endif
else
# seems like older libpng versions are broken and need this
PNGCONFIG_FLAGS = --ldflags --libs
ifdef STATIC
LIBS += `libpng-config --static $(PNGCONFIG_FLAGS)`
else
LIBS += `libpng-config  $(PNGCONFIG_FLAGS)`
endif
endif
endif


ifdef TRANSLATOR
STRGEN_FLAGS=-t
else
STRGEN_FLAGS=
endif

# Experimental
ifdef WITH_NETWORK
CDEFS += -DENABLE_NETWORK
ifdef UNIX
ifndef OSX
LIBS += -lresolv
endif
endif
endif

ifdef WITH_DIRECTMUSIC
CDEFS += -DWIN32_ENABLE_DIRECTMUSIC_SUPPORT
endif

ifdef WIN32
LIBS += -lws2_32 -lwinmm -lgdi32 -ldxguid -lole32 -lstdc++
TTDLDFLAGS += -Wl,--subsystem,windows
endif


##############################################################################
#
# What to compile
# (users do not want to modify anything below)
#


### Sources

ttd_SOURCES = \
	ai.c aircraft_cmd.c aircraft_gui.c airport_gui.c bridge_gui.c \
	clear_cmd.c command.c disaster_cmd.c dock_gui.c dummy_land.c economy.c \
	engine.c engine_gui.c fileio.c gfx.c graph_gui.c industry_cmd.c \
	industry_gui.c intro_gui.c landscape.c main_gui.c misc.c misc_cmd.c \
	misc_gui.c music_gui.c namegen.c network.c news_gui.c oldloader.c \
	order_cmd.c order_gui.c pathfind.c player_gui.c players.c rail_cmd.c \
	rail_gui.c road_cmd.c road_gui.c roadveh_cmd.c roadveh_gui.c saveload.c \
	sdl.c settings_gui.c ship_cmd.c ship_gui.c smallmap_gui.c sound.c \
	spritecache.c station_cmd.c station_gui.c strings.c subsidy_gui.c \
	texteff.c town_cmd.c town_gui.c train_cmd.c train_gui.c tree_cmd.c \
	ttd.c tunnelbridge_cmd.c unmovable_cmd.c vehicle.c viewport.c \
	water_cmd.c widget.c window.c minilzo.c screenshot.c settings.c rev.c

ifdef WIN32
ttd_SOURCES += win32.c w32dm.c
else
ttd_SOURCES += extmidi.c unix.c
endif

ttd_OBJS = $(ttd_SOURCES:%.c=%.o)

ifdef WIN32
# Resource file
ttd_OBJS += winres.o
endif

ifdef WITH_DIRECTMUSIC
ttd_SOURCES += w32dm2.cpp
ttd_OBJS += w32dm2.o
endif

ttd_DEPS1 = $(foreach obj,$(ttd_OBJS),.deps/$(obj))
ttd_DEPS = $(ttd_DEPS1:%.o=%.P)

LANG_TXT = $(filter-out %.unfinished.txt,$(wildcard lang/*.txt))
LANGS = $(LANG_TXT:%.txt=%.lng)

C_COMPILE = $(CC) $(CFLAGS) $(CDEFS)
CXX_COMPILE = $(CXX) $(CFLAGS) $(CDEFS)

C_BUILD = $(C_COMPILE) -c
CXX_BUILD = $(CXX_COMPILE) -c

C_LINK = $(CC) $(LDFLAGS) -o


##############################################################################
#
# Targets
#


### Normal build rules


ifdef OSX
all: osx
else
all: $(TTD)
endif


$(TTD): table/strings.h $(ttd_OBJS) $(LANGS) $(MAKE_CONFIG)
	$(C_LINK) $@ $(TTDLDFLAGS) $(ttd_OBJS) $(LIBS)

osx: $(TTD)
	mkdir -p $(OSXAPP)/Contents/MacOS
	mkdir -p $(OSXAPP)/Contents/Resources
	echo "APPL????" > $(OSXAPP)/Contents/PkgInfo
	cp os/macos/ttd.icns $(OSXAPP)/Contents/Resources/
	os/macos/plistgen.sh $(OSXAPP) $(REV) $(RELEASE)
	cp os/macos/track_starter $(OSXAPP)/contents/macos
	if [ "`ls os/macos | grep ".class"`" == "" ]; then \
	javac os/macos/OpenTTDMidi.java; fi
	cp os/macos/OpenTTDMidi.class $(OSXAPP)/contents/macos
	cp $(TTD) $(OSXAPP)/Contents/MacOS/ttd

$(STRGEN): strgen/strgen.c rev.o
	$(CC) $(BASECFLAGS) $(CDEFS) -o $@ $^

lang/english.lng: lang/english.txt $(STRGEN)
	$(STRGEN)
	
table/strings.h: lang/english.lng

lang/%.lng: lang/%.txt $(STRGEN)
	$(STRGEN) $(STRGEN_FLAGS) $<

winres.o: ttd.rc
	windres -o $@ $<

rev.c: FORCE
	@echo 'const char _openttd_revision[] = "'$(REV)'";' >>rev.c.new
	@# Only update the real rev.c if it actually changed, to prevent
	@# useless rebuilds.
	@cmp -s rev.c rev.c.new 2>/dev/null || mv rev.c.new rev.c
	@rm -f rev.c.new

FORCE:


clean:
	rm -rf .deps *~ $(TTD) $(STRGEN) core table/strings.h $(LANGS) $(ttd_OBJS)

mrproper: clean
	rm -rf $(MAKE_CONFIG)

.PHONY: clean all osx


### Automatic configuration

# Magic at work, note that you can't use commas in arguments for this
CONFIG_LINE=@$(SHELL) -c 'echo $(1)' >> $(MAKE_CONFIG) 2> /dev/null

# Create default config from autodetected values
$(MAKE_CONFIG):
	touch $(MAKE_CONFIG)
	
	$(call CONFIG_LINE,CONFIG_INCLUDED:=yes)
		
	$(call CONFIG_LINE,\# Set your options here - 1 for use and empty for disable)
		
	$(call CONFIG_LINE,WITH_ZLIB:=$(WITH_ZLIB))
	$(call CONFIG_LINE,WITH_SDL:=$(WITH_SDL))
	$(call CONFIG_LINE,WITH_PNG:=$(WITH_PNG))

	$(call CONFIG_LINE,WIN32:=$(WIN32))
	$(call CONFIG_LINE,OSX:=$(OSX))
	$(call CONFIG_LINE,UNIX:=$(UNIX))
	$(call CONFIG_LINE,TRANSLATOR:=$(TRANSLATOR))
	$(call CONFIG_LINE,STATIC:=$(STATIC))
	$(call CONFIG_LINE,CYGWIN:=$(CYGWIN))
	$(call CONFIG_LINE,MINGW:=$(MINGW))
	
	$(call CONFIG_LINE,\# Experimental)
	$(call CONFIG_LINE,DEBUG:=$(DEBUG))
	$(call CONFIG_LINE,WITH_NETWORK:=$(WITH_NETWORK))
	$(call CONFIG_LINE,WITH_DIRECTMUSIC:=$(WITH_DIRECTMUSIC))
	
# Export all variables set to subprocesses (a bit dirty)
.EXPORT_ALL_VARIABLES:
upgradeconf: $(MAKE_CONFIG)
	rm $(MAKE_CONFIG)
	$(MAKE) $(MAKE_CONFIG)

.PHONY: upgradeconf


### Internal build rules

# This makes sure the .deps dir is always around.
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)

# Introduce the dependencies
-include $(ttd_DEPS)

# This compiles the object file as well as silently updating its dependencies
# list at the same time. It is not an issue that they aren't around during the
# first compilation round as we just build everything at that time anyway,
# therefore we do not need to watch deps.
%.o: %.c $(MAKE_CONFIG)
	@echo '$(C_BUILD) $<'; \
		$(C_BUILD) $< -Wp,-MD,.deps/$(*F).pp
	@-cp .deps/$(*F).pp .deps/$(*F).P; \
		tr ' ' '\012' < .deps/$(*F).pp \
		| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
		>> .deps/$(*F).P; \
	rm .deps/$(*F).pp

# For DirectMusic build
%.o: %.cpp  $(MAKE_CONFIG)
	$(CXX_BUILD) $<
