2009-08-21 20:21:05 +00:00
# $Id$
# This file is part of OpenTTD.
# OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
# OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
2007-01-02 19:19:48 +00:00
CC_HOST = !!CC_HOST!!
CXX_HOST = !!CXX_HOST!!
CC_BUILD = !!CC_BUILD!!
2007-01-10 18:56:51 +00:00
CXX_BUILD = !!CXX_BUILD!!
2007-01-02 19:19:48 +00:00
WINDRES = !!WINDRES!!
STRIP = !!STRIP!!
CFLAGS = !!CFLAGS!!
CFLAGS_BUILD = !!CFLAGS_BUILD!!
LIBS = !!LIBS!!
LDFLAGS = !!LDFLAGS!!
2009-08-21 21:28:59 +00:00
LDFLAGS_BUILD = !!LDFLAGS_BUILD!!
2008-09-07 13:24:49 +00:00
ROOT_DIR = !!ROOT_DIR!!
2007-01-02 19:19:48 +00:00
BIN_DIR = !!BIN_DIR!!
LANG_DIR = !!LANG_DIR!!
SRC_OBJS_DIR = !!SRC_OBJS_DIR!!
LANG_OBJS_DIR = !!LANG_OBJS_DIR!!
SRC_DIR = !!SRC_DIR!!
2009-01-12 17:11:45 +00:00
SCRIPT_SRC_DIR = !!SCRIPT_SRC_DIR!!
2007-01-02 19:19:48 +00:00
MEDIA_DIR = !!MEDIA_DIR!!
TTD = !!TTD!!
STRGEN = !!STRGEN!!
ENDIAN_CHECK = !!ENDIAN_CHECK!!
2009-05-14 21:59:24 +00:00
DEPEND = !!DEPEND!!
2007-01-02 19:19:48 +00:00
ENDIAN_FORCE = !!ENDIAN_FORCE!!
OS = !!OS!!
STAGE = !!STAGE!!
MAKEDEPEND = !!MAKEDEPEND!!
CFLAGS_MAKEDEP = !!CFLAGS_MAKEDEP!!
SORT = !!SORT!!
2007-01-05 15:01:51 +00:00
REVISION = !!REVISION!!
2007-02-19 19:59:19 +00:00
AWK = !!AWK!!
2007-01-02 19:19:48 +00:00
CONFIG_CACHE_COMPILER = $( SRC_OBJS_DIR) /!!CONFIG_CACHE_COMPILER!!
CONFIG_CACHE_LINKER = $( SRC_OBJS_DIR) /!!CONFIG_CACHE_LINKER!!
CONFIG_CACHE_ENDIAN = $( SRC_OBJS_DIR) /!!CONFIG_CACHE_ENDIAN!!
CONFIG_CACHE_SOURCE = $( SRC_OBJS_DIR) /!!CONFIG_CACHE_SOURCE!!
CONFIG_CACHE_VERSION = $( SRC_OBJS_DIR) /!!CONFIG_CACHE_VERSION!!
OBJS_C := !!OBJS_C!!
OBJS_CPP := !!OBJS_CPP!!
2007-02-05 21:16:56 +00:00
OBJS_MM := !!OBJS_MM!!
2007-01-02 19:19:48 +00:00
OBJS_RC := !!OBJS_RC!!
2007-02-05 21:16:56 +00:00
OBJS := $( OBJS_C) $( OBJS_CPP) $( OBJS_MM) $( OBJS_RC)
2007-01-02 19:19:48 +00:00
SRCS := !!SRCS!!
# All C-files depend on those 3 files
2009-02-04 23:40:01 +00:00
FILE_DEP := $( CONFIG_CACHE_COMPILER) endian_target.h
2007-01-02 19:19:48 +00:00
# Create all dirs and subdirs
RES := $( shell mkdir -p $( BIN_DIR) $( sort $( dir $( OBJS) ) ) )
# Make sure endian_target.h is reasable as if it was in the src/ dir
CFLAGS += -I $( SRC_OBJS_DIR) -I $( LANG_OBJS_DIR)
2009-01-12 17:11:45 +00:00
CFLAGS_MAKEDEP += -I $( SRC_OBJS_DIR) -I $( LANG_OBJS_DIR) -I $( SCRIPT_SRC_DIR)
2007-01-02 19:19:48 +00:00
ENDIAN_TARGETS := endian_target.h $( ENDIAN_CHECK)
# Check if we want to show what we are doing
i f d e f V E R B O S E
Q =
E = @true
e l s e
Q = @
E = @echo
e n d i f
# Our default target
2007-01-11 18:26:53 +00:00
all : $( BIN_DIR ) /$( TTD )
2007-01-02 19:19:48 +00:00
# This are 2 rules that are pointing back to STRGEN stuff.
# There is not really a need to have them here, but in case
# some weirdo wants to run 'make' in the 'src' dir and expects
# the languages to be recompiled, this catches that case and
# takes care of it nicely.
$(LANG_OBJS_DIR)/$(STRGEN) :
$( MAKE) -C $( LANG_OBJS_DIR) $( STRGEN)
$(LANG_OBJS_DIR)/table/strings.h : $( LANG_DIR ) /english .txt $( LANG_OBJS_DIR ) /$( STRGEN )
$( MAKE) -C $( LANG_OBJS_DIR) table/strings.h
2008-09-07 13:24:49 +00:00
# Always run version detection, so we always have an accurate modified
# flag
VERSIONS := $( shell AWK = " $( AWK) " " $( ROOT_DIR) /findversion.sh " )
2008-09-08 06:27:08 +00:00
MODIFIED := $( shell echo " $( VERSIONS) " | cut -f 3 -d' ' )
2008-06-03 18:35:58 +00:00
2007-01-02 19:19:48 +00:00
i f d e f R E V I S I O N
2008-09-07 13:24:49 +00:00
# Use specified revision (which should be of the form "r000").
2007-01-02 19:19:48 +00:00
REV := $( REVISION)
2009-05-16 12:36:33 +00:00
REV_NR := $( shell echo $( REVISION) | sed "s@[^0-9]@@g" )
2007-01-02 19:19:48 +00:00
e l s e
2008-09-07 13:24:49 +00:00
# Use autodetected revisions
2008-09-08 06:27:08 +00:00
REV := $( shell echo " $( VERSIONS) " | cut -f 1 -d' ' )
REV_NR := $( shell echo " $( VERSIONS) " | cut -f 2 -d' ' )
2007-01-02 19:19:48 +00:00
e n d i f
2007-06-07 00:25:49 +00:00
2008-07-31 19:19:29 +00:00
# Make sure we have something in REV and REV_NR
2007-01-02 19:19:48 +00:00
i f e q ( $( REV ) , )
REV := norev000
2008-07-31 19:19:29 +00:00
e n d i f
i f e q ( $( REV_NR ) , )
2007-10-21 14:59:05 +00:00
REV_NR := 0
2007-01-02 19:19:48 +00:00
e n d i f
# This helps to recompile if flags change
2009-06-22 20:22:04 +00:00
RES := $( shell if [ " `cat $( CONFIG_CACHE_COMPILER) 2>/dev/null` " != " $( CFLAGS) " ] ; then echo " $( CFLAGS) " > $( CONFIG_CACHE_COMPILER) ; fi )
2007-01-02 19:19:48 +00:00
RES := $( shell if [ " `cat $( CONFIG_CACHE_LINKER) 2>/dev/null` " != " $( LDFLAGS) $( LIBS) " ] ; then echo " $( LDFLAGS) $( LIBS) " > $( CONFIG_CACHE_LINKER) ; fi )
RES := $( shell if [ " `cat $( CONFIG_CACHE_ENDIAN) 2>/dev/null` " != " $( ENDIAN_FORCE) " ] ; then echo " $( ENDIAN_FORCE) " > $( CONFIG_CACHE_ENDIAN) ; fi )
# If there is a change in the source-file-list, make sure we recheck the deps
RES := $( shell if [ " `cat $( CONFIG_CACHE_SOURCE) 2>/dev/null` " != " $( SRCS) " ] ; then echo " $( SRCS) " > $( CONFIG_CACHE_SOURCE) ; fi )
2007-01-10 18:56:51 +00:00
# If there is a change in the revision, make sure we recompile rev.cpp
2008-07-31 20:09:54 +00:00
RES := $( shell if [ " `cat $( CONFIG_CACHE_VERSION) 2>/dev/null` " != " $( REV) $( MODIFIED) " ] ; then echo " $( REV) $( MODIFIED) " > $( CONFIG_CACHE_VERSION) ; fi )
2007-01-02 19:19:48 +00:00
i f n d e f M A K E D E P E N D
# The slow, but always correct, dep-check
DEP_MASK := %.d
DEPS := $( OBJS:%.o= %.d)
# Only include the deps if we are compiling everything
i f e q ( $( filter $ ( ENDIAN_TARGETS ) %.o clean mrproper , $ ( MAKECMDGOALS ) ) , )
- i n c l u d e $( DEPS )
e l s e
# In case we want to compile a single target, include the .d file for it
i f n e q ( $( filter %.o , $ ( MAKECMDGOALS ) ) , )
SINGLE_DEP := $( filter %.o, $( MAKECMDGOALS) )
-include $(SINGLE_DEP : %.o =%.d )
e n d i f
e n d i f
# Find the deps via GCC. Rarely wrong, but a bit slow
2009-08-18 17:49:28 +00:00
$(OBJS_C : %.o =%.d ): %.d : $( SRC_DIR ) /%.c $( FILE_DEP )
$( E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.c=%.c)'
$( Q) $( CC_HOST) $( CFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@
2007-01-02 19:19:48 +00:00
$(OBJS_CPP : %.o =%.d ): %.d : $( SRC_DIR ) /%.cpp $( FILE_DEP )
$( E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.cpp=%.cpp)'
2009-05-16 12:36:33 +00:00
$( Q) $( CXX_HOST) $( CFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@
2007-01-02 19:19:48 +00:00
2007-02-05 21:16:56 +00:00
$(OBJS_MM : %.o =%.d ): %.d : $( SRC_DIR ) /%.mm $( FILE_DEP )
$( E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.mm=%.mm)'
2009-05-16 12:36:33 +00:00
$( Q) $( CC_HOST) $( CFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@
2007-01-02 19:19:48 +00:00
2007-01-02 20:19:25 +00:00
$(OBJS_RC : %.o =%.d ): %.d : $( SRC_DIR ) /%.rc $( FILE_DEP )
2007-02-05 21:16:56 +00:00
$( E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.mm=%.mm)'
2007-01-02 20:19:25 +00:00
$( Q) touch $@
2007-01-02 19:19:48 +00:00
e l s e
# The much faster, but can be wrong, dep-check
DEP_MASK :=
DEPS := Makefile.dep
# Only include the deps if we are not cleaning
i f e q ( $( filter $ ( ENDIAN_TARGETS ) depend clean mrproper , $ ( MAKECMDGOALS ) ) , )
- i n c l u d e M a k e f i l e . d e p
e n d i f
2009-05-14 21:59:24 +00:00
i f e q ( "$(SRC_OBJS_DIR)/$(DEPEND)" , "$(MAKEDEPEND)" )
DEP := $( MAKEDEPEND)
$(SRC_OBJS_DIR)/$(DEPEND) : $( SRC_DIR ) /depend /depend .cpp
$( E) '$(STAGE) Compiling and linking $(DEPEND)'
2009-08-21 21:28:59 +00:00
$( Q) $( CXX_BUILD) $( CFLAGS_BUILD) $( LDFLAGS_BUILD) -o $@ $<
2009-05-14 21:59:24 +00:00
e n d i f
2007-01-02 19:19:48 +00:00
# Make sure that only 'make depend' ALWAYS triggers a recheck
i f e q ( $( filter depend , $ ( MAKECMDGOALS ) ) , )
2009-05-14 21:59:24 +00:00
Makefile.dep : $( FILE_DEP ) $( SRCS :%=$ ( SRC_DIR ) /%) $( CONFIG_CACHE_SOURCE ) $( DEP )
2007-01-02 19:19:48 +00:00
e l s e
2009-05-26 23:05:11 +00:00
Makefile.dep : $( FILE_DEP ) $( SRCS :%=$ ( SRC_DIR ) /%) $( DEP ) FORCE
2007-01-02 19:19:48 +00:00
e n d i f
$( E) '$(STAGE) DEP CHECK (all files)'
$( Q) rm -f Makefile.dep.tmp
$( Q) touch Makefile.dep.tmp
# Calculate the deps via makedepend
$( Q) $( MAKEDEPEND) -f$( SRC_OBJS_DIR) /Makefile.dep.tmp -o.o -Y -v -- $( CFLAGS_MAKEDEP) -- $( SRCS:%= $( SRC_DIR) /%) 2>/dev/null
# Convert x:/... paths to /x/... for mingw
i f e q ( $( OS ) , M I N G W )
2009-05-24 17:34:39 +00:00
@cat Makefile.dep.tmp | sed 's@/\([a-zA-Z]\):\/@\/\1\/@g' > Makefile.dep.tmp.mingw
2007-01-02 19:19:48 +00:00
@cp Makefile.dep.tmp.mingw Makefile.dep.tmp
@rm -f Makefile.dep.tmp.mingw
e n d i f
# Remove all comments and includes that don't start with $(SRC_DIR)
# Remove $(SRC_DIR) from object-file-name
2007-02-19 19:59:19 +00:00
@$( AWK) ' \
2007-01-02 19:19:48 +00:00
/^# DO NOT/ { print $$ 0 ; next} \
/^#/ { next} \
2009-05-24 17:34:39 +00:00
/: / { \
2007-01-02 19:19:48 +00:00
left = NF - 1; \
for ( n = 2; n <= NF; n++) { \
2009-02-04 23:40:01 +00:00
if ( match( $$ n, " ^ $( ROOT_DIR) " ) = = 0) { \
2007-01-02 19:19:48 +00:00
$$ n = "" ; \
left--; \
} \
} \
gsub( " $( SRC_DIR) / " , "" , $$ 1) ; \
if ( left > 0) { \
print $$ 0; \
$$ 1 = "Makefile.dep:" ; \
print $$ 0; \
} \
next \
} \
{ \
print $$ 0 \
} \
2009-05-16 12:36:33 +00:00
' < Makefile.dep.tmp | sed ' s@ *@ @g; s@ $$ @@' | $( SORT) > Makefile.dep
2007-01-02 19:19:48 +00:00
$( Q) rm -f Makefile.dep.tmp Makefile.dep.tmp.bak
e n d i f
2009-01-12 17:11:45 +00:00
# Avoid problems with deps if a .h/.hpp/.hpp.sq file is deleted without the deps
2007-01-02 19:19:48 +00:00
# being updated. Now the Makefile continues, the deps are recreated
# and all will be fine.
2009-01-12 17:11:45 +00:00
%.h %.hpp %.hpp.sq :
2007-01-02 19:19:48 +00:00
@true
# Compile all the files according to the targets
2009-08-18 17:49:28 +00:00
$(OBJS_C) : %.o : $( SRC_DIR ) /%.c $( DEP_MASK ) $( FILE_DEP )
$( E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.c=%.c)'
$( Q) $( CC_HOST) $( CFLAGS) -c -o $@ $<
2007-01-02 19:19:48 +00:00
$(OBJS_CPP) : %.o : $( SRC_DIR ) /%.cpp $( DEP_MASK ) $( FILE_DEP )
$( E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
$( Q) $( CXX_HOST) $( CFLAGS) -c -o $@ $<
2007-02-05 21:16:56 +00:00
$(OBJS_MM) : %.o : $( SRC_DIR ) /%.mm $( DEP_MASK ) $( FILE_DEP )
$( E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.mm=%.mm)'
$( Q) $( CC_HOST) $( CFLAGS) -c -o $@ $<
2007-01-02 19:19:48 +00:00
$(OBJS_RC) : %.o : $( SRC_DIR ) /%.rc $( FILE_DEP )
$( E) '$(STAGE) Compiling resource $(<:$(SRC_DIR)/%.rc=%.rc)'
$( Q) $( WINDRES) -o $@ -I $( MEDIA_DIR) $<
2007-01-11 18:26:53 +00:00
$(BIN_DIR)/$(TTD) : $( TTD )
$( Q) cp $< $@
2007-09-12 07:11:48 +00:00
$(TTD) : $( OBJS ) $( CONFIG_CACHE_LINKER )
2007-01-02 19:19:48 +00:00
$( E) '$(STAGE) Linking $@'
2007-02-11 16:28:00 +00:00
i f e q ( $( OS ) , P S P )
2007-02-19 21:18:39 +00:00
# Because of a bug in the PSP GCC tools, linking via CXX results
# in total chaos and more problems then you can handle. So we need
# CC to link OpenTTD for PSP
2007-09-12 07:11:48 +00:00
$( Q) $( CC_HOST) $( LDFLAGS) $( OBJS) $( LIBS) -o $@
2007-02-11 16:28:00 +00:00
e l s e
2007-09-12 07:11:48 +00:00
$( Q) $( CXX_HOST) $( LDFLAGS) $( OBJS) $( LIBS) -o $@
2007-02-11 16:28:00 +00:00
e n d i f
2007-01-02 19:19:48 +00:00
i f d e f S T R I P
$( Q) $( STRIP) $@
2008-11-26 13:12:45 +00:00
i f e q ( $( OS ) , D O S )
$( E) '$(STAGE) Adding CWSDPMI stub to $@'
$( Q) $( ROOT_DIR) /os/dos/make_dos_binary_selfcontained.sh $( SRC_OBJS_DIR) /$@
e n d i f
2007-01-02 19:19:48 +00:00
e n d i f
# The targets to compile the endian-code
endian_target.h : $( ENDIAN_CHECK ) $( CONFIG_CACHE_ENDIAN )
$( E) '$(STAGE) Testing endianness for target'
$( Q) ./$( ENDIAN_CHECK) $( ENDIAN_FORCE) > $@
2007-01-10 18:56:51 +00:00
$(ENDIAN_CHECK) : $( SRC_DIR ) /endian_check .cpp
2007-01-02 19:19:48 +00:00
$( E) '$(STAGE) Compiling and Linking $@'
2007-01-10 18:56:51 +00:00
$( Q) $( CXX_BUILD) $( CFLAGS_BUILD) $< -o $@
2007-01-02 19:19:48 +00:00
# Revision files
2007-09-12 07:11:48 +00:00
$(SRC_DIR)/rev.cpp : $( CONFIG_CACHE_VERSION ) $( SRC_DIR ) /rev .cpp .in
2009-05-16 12:36:33 +00:00
$( Q) cat $( SRC_DIR) /rev.cpp.in | sed " s@\!\!REVISION\!\!@ $( REV_NR) @g;s@!!VERSION!!@ $( REV) @g;s@!!MODIFIED!!@ $( MODIFIED) @g;s@!!DATE!!@`date +%d.%m.%y`@g " > $( SRC_DIR) /rev.cpp
2007-01-02 19:19:48 +00:00
2009-08-31 22:38:37 +00:00
$(SRC_DIR)/os/windows/ottdres.rc : $( CONFIG_CACHE_VERSION ) $( SRC_DIR ) /os /windows /ottdres .rc .in
$( Q) cat $( SRC_DIR) /os/windows/ottdres.rc.in | sed " s@\!\!REVISION\!\!@ $( REV_NR) @g;s@!!VERSION!!@ $( REV) @g;s@!!DATE!!@`date +%d.%m.%y`@g " > $( SRC_DIR) /os/windows/ottdres.rc
2007-01-02 19:19:48 +00:00
FORCE :
depend : $( DEPS )
clean :
$( E) '$(STAGE) Cleaning up object files'
2009-05-14 21:59:24 +00:00
$( Q) rm -f $( DEPS) $( OBJS) $( TTD) $( DEPEND) $( TTD:%= $( BIN_DIR) /%) $( CONFIG_CACHE_COMPILER) $( CONFIG_CACHE_LINKER) $( CONFIG_CACHE_ENDIAN) $( CONFIG_CACHE_SOURCE) $( ENDIAN_TARGETS)
2007-01-02 19:19:48 +00:00
mrproper : clean
2009-08-31 22:38:37 +00:00
$( Q) rm -f $( SRC_DIR) /rev.cpp $( SRC_DIR) /os/windows/ottdres.rc
2007-01-02 19:19:48 +00:00
%.o :
2007-02-10 00:22:32 +00:00
@echo '$(STAGE) No such source-file: $(@:%.o=%).[c|cpp|mm|rc]'
2007-01-02 19:19:48 +00:00
.PHONY : all mrproper depend clean FORCE