CC_HOST = !!CC_HOST!! CXX_HOST = !!CXX_HOST!! CC_BUILD = !!CC_BUILD!! CXX_BUILD = !!CXX_BUILD!! WINDRES = !!WINDRES!! STRIP = !!STRIP!! CC_CFLAGS = !!CC_CFLAGS!! CFLAGS = !!CFLAGS!! CFLAGS_BUILD = !!CFLAGS_BUILD!! LIBS = !!LIBS!! LDFLAGS = !!LDFLAGS!! ROOT_DIR = !!ROOT_DIR!! BIN_DIR = !!BIN_DIR!! LANG_DIR = !!LANG_DIR!! SRC_OBJS_DIR = !!SRC_OBJS_DIR!! LANG_OBJS_DIR= !!LANG_OBJS_DIR!! SRC_DIR = !!SRC_DIR!! SCRIPT_SRC_DIR=!!SCRIPT_SRC_DIR!! MEDIA_DIR = !!MEDIA_DIR!! TTD = !!TTD!! STRGEN = !!STRGEN!! ENDIAN_CHECK = !!ENDIAN_CHECK!! DEPEND = !!DEPEND!! ENDIAN_FORCE = !!ENDIAN_FORCE!! OS = !!OS!! STAGE = !!STAGE!! MAKEDEPEND = !!MAKEDEPEND!! CFLAGS_MAKEDEP= !!CFLAGS_MAKEDEP!! SORT = !!SORT!! REVISION = !!REVISION!! AWK = !!AWK!! GCC295 = !!GCC295!! 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!! OBJS_MM := !!OBJS_MM!! OBJS_RC := !!OBJS_RC!! OBJS := $(OBJS_C) $(OBJS_CPP) $(OBJS_MM) $(OBJS_RC) SRCS := !!SRCS!! # All C-files depend on those 3 files FILE_DEP := $(CONFIG_CACHE_COMPILER) endian_target.h # 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) CFLAGS_MAKEDEP += -I $(SRC_OBJS_DIR) -I $(LANG_OBJS_DIR) -I $(SCRIPT_SRC_DIR) ENDIAN_TARGETS := endian_target.h $(ENDIAN_CHECK) # This 'sed' basicly just removes 'const' from the line if it is a 2+D array # For more information, please check: # http://maillist.openttd.org/pipermail/devs/2007-April/000284.html # http://maillist.openttd.org/pipermail/devs/2007-February/000248.html GCC295_FIX=sed -r 's@^(\t*)(.*)( const )([A-Za-z0-9_ ]+(\[.*\]){2,})(( = \{)|(;))(.*)$$@\1\2 \4\6\8\9@g' # This 'sed' removes the 3rd '4' in the # lines of the -E output of # gcc 2.95.3 and lower, as it should indicate that it is a C-linkage, but the # compiler can't handle that information (just don't ask). So we remove it # and then it compiles happily and without bitching :) # Furthermore gcc 2.95 has some trouble with protected and private when # accessing the protected/private stuff of the enclosing class (or the # super class of the enclosing class). GCC295_FIX_2=sed -e 's@\(^\# [0-9][0-9]* "[^"]*"[ 0-9]*\) 4$$@\1@g;s@private:@public:@g;s@protected:@public:@g' # Check if we want to show what we are doing ifdef VERBOSE Q = E = @true else Q = @ E = @echo endif # Our default target all: $(BIN_DIR)/$(TTD) # 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 # Always run version detection, so we always have an accurate modified # flag VERSIONS := $(shell AWK="$(AWK)" "$(ROOT_DIR)/findversion.sh") MODIFIED := $(shell echo "$(VERSIONS)" | cut -f 3 -d' ') ifdef REVISION # Use specified revision (which should be of the form "r000"). REV := $(REVISION) REV_NR := $(shell echo $(REVISION) | sed "s@[^0-9]@@g") else # Use autodetected revisions REV := $(shell echo "$(VERSIONS)" | cut -f 1 -d' ') REV_NR := $(shell echo "$(VERSIONS)" | cut -f 2 -d' ') endif # Make sure we have something in REV and REV_NR ifeq ($(REV),) REV := norev000 endif ifeq ($(REV_NR),) REV_NR := 0 endif # This helps to recompile if flags change RES := $(shell if [ "`cat $(CONFIG_CACHE_COMPILER) 2>/dev/null`" != "$(CC_CFLAGS) $(CFLAGS)" ]; then echo "$(CC_CFLAGS) $(CFLAGS)" > $(CONFIG_CACHE_COMPILER); fi ) 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 ) # If there is a change in the revision, make sure we recompile rev.cpp RES := $(shell if [ "`cat $(CONFIG_CACHE_VERSION) 2>/dev/null`" != "$(REV) $(MODIFIED)" ]; then echo "$(REV) $(MODIFIED)" > $(CONFIG_CACHE_VERSION); fi ) ifndef MAKEDEPEND # The slow, but always correct, dep-check DEP_MASK := %.d DEPS := $(OBJS:%.o=%.d) # Only include the deps if we are compiling everything ifeq ($(filter $(ENDIAN_TARGETS) %.o clean mrproper, $(MAKECMDGOALS)),) -include $(DEPS) else # In case we want to compile a single target, include the .d file for it ifneq ($(filter %.o, $(MAKECMDGOALS)),) SINGLE_DEP := $(filter %.o, $(MAKECMDGOALS)) -include $(SINGLE_DEP:%.o=%.d) endif endif # Find the deps via GCC. Rarely wrong, but a bit slow $(OBJS_C:%.o=%.d): %.d: $(SRC_DIR)/%.c $(FILE_DEP) $(E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.c=%.c)' $(Q)$(CC_HOST) $(CC_CFLAGS) $(CFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@ $(OBJS_CPP:%.o=%.d): %.d: $(SRC_DIR)/%.cpp $(FILE_DEP) $(E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.cpp=%.cpp)' $(Q)$(CXX_HOST) $(CFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@ $(OBJS_MM:%.o=%.d): %.d: $(SRC_DIR)/%.mm $(FILE_DEP) $(E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.mm=%.mm)' $(Q)$(CC_HOST) $(CFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@ $(OBJS_RC:%.o=%.d): %.d: $(SRC_DIR)/%.rc $(FILE_DEP) $(E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.mm=%.mm)' $(Q)touch $@ else # The much faster, but can be wrong, dep-check DEP_MASK := DEPS := Makefile.dep # Only include the deps if we are not cleaning ifeq ($(filter $(ENDIAN_TARGETS) depend clean mrproper, $(MAKECMDGOALS)),) -include Makefile.dep endif ifeq ("$(SRC_OBJS_DIR)/$(DEPEND)","$(MAKEDEPEND)") DEP := $(MAKEDEPEND) $(SRC_OBJS_DIR)/$(DEPEND): $(SRC_DIR)/depend/depend.cpp $(E) '$(STAGE) Compiling and linking $(DEPEND)' $(Q)$(CXX_HOST) -o $@ $< endif # Make sure that only 'make depend' ALWAYS triggers a recheck ifeq ($(filter depend, $(MAKECMDGOALS)),) Makefile.dep: $(FILE_DEP) $(SRCS:%=$(SRC_DIR)/%) $(CONFIG_CACHE_SOURCE) $(DEP) else Makefile.dep: $(FILE_DEP) $(SRCS:%=$(SRC_DIR)/%) $(DEP) FORCE endif $(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 ifeq ($(OS), MINGW) @cat Makefile.dep.tmp | sed 's@/\([a-zA-Z]\):\/@\/\1\/@g' > Makefile.dep.tmp.mingw @cp Makefile.dep.tmp.mingw Makefile.dep.tmp @rm -f Makefile.dep.tmp.mingw endif # Remove all comments and includes that don't start with $(SRC_DIR) # Remove $(SRC_DIR) from object-file-name @$(AWK) ' \ /^# DO NOT/ { print $$0 ; next} \ /^#/ {next} \ /: / { \ left = NF - 1; \ for (n = 2; n <= NF; n++) { \ if (match($$n, "^$(ROOT_DIR)") == 0) { \ $$n = ""; \ left--; \ } \ } \ gsub("$(SRC_DIR)/", "", $$1); \ if (left > 0) { \ print $$0; \ $$1 = "Makefile.dep:"; \ print $$0; \ } \ next \ } \ { \ print $$0 \ } \ ' < Makefile.dep.tmp | sed 's@ *@ @g;s@ $$@@' | $(SORT) > Makefile.dep $(Q)rm -f Makefile.dep.tmp Makefile.dep.tmp.bak endif # Avoid problems with deps if a .h/.hpp/.hpp.sq file is deleted without the deps # being updated. Now the Makefile continues, the deps are recreated # and all will be fine. %.h %.hpp %.hpp.sq: @true # Compile all the files according to the targets $(OBJS_C): %.o: $(SRC_DIR)/%.c $(DEP_MASK) $(FILE_DEP) $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.c=%.c)' $(Q)$(CC_HOST) $(CC_CFLAGS) $(CFLAGS) -c -o $@ $< $(OBJS_CPP): %.o: $(SRC_DIR)/%.cpp $(DEP_MASK) $(FILE_DEP) $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)' ifeq ($(GCC295), 1) $(Q)$(CXX_HOST) -E $(CFLAGS) $< | $(GCC295_FIX) | $(GCC295_FIX_2) | $(CXX_HOST) $(CFLAGS) -c -o $@ -x c++ - else $(Q)$(CXX_HOST) $(CFLAGS) -c -o $@ $< endif $(OBJS_MM): %.o: $(SRC_DIR)/%.mm $(DEP_MASK) $(FILE_DEP) $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.mm=%.mm)' $(Q)$(CC_HOST) $(CFLAGS) -c -o $@ $< $(OBJS_RC): %.o: $(SRC_DIR)/%.rc $(FILE_DEP) $(E) '$(STAGE) Compiling resource $(<:$(SRC_DIR)/%.rc=%.rc)' $(Q)$(WINDRES) -o $@ -I $(MEDIA_DIR) $< $(BIN_DIR)/$(TTD): $(TTD) $(Q)cp $< $@ $(TTD): $(OBJS) $(CONFIG_CACHE_LINKER) $(E) '$(STAGE) Linking $@' ifeq ($(OS), PSP) # 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 $(Q)$(CC_HOST) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ else $(Q)$(CXX_HOST) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ endif ifdef STRIP $(Q)$(STRIP) $@ ifeq ($(OS), DOS) $(E) '$(STAGE) Adding CWSDPMI stub to $@' $(Q)$(ROOT_DIR)/os/dos/make_dos_binary_selfcontained.sh $(SRC_OBJS_DIR)/$@ endif endif # 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) > $@ $(ENDIAN_CHECK): $(SRC_DIR)/endian_check.cpp $(E) '$(STAGE) Compiling and Linking $@' $(Q)$(CXX_BUILD) $(CFLAGS_BUILD) $< -o $@ # Revision files $(SRC_DIR)/rev.cpp: $(CONFIG_CACHE_VERSION) $(SRC_DIR)/rev.cpp.in $(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 $(SRC_DIR)/ottdres.rc: $(CONFIG_CACHE_VERSION) $(SRC_DIR)/ottdres.rc.in $(Q)cat $(SRC_DIR)/ottdres.rc.in | sed "s@\!\!REVISION\!\!@$(REV_NR)@g;s@!!VERSION!!@$(REV)@g;s@!!DATE!!@`date +%d.%m.%y`@g" > $(SRC_DIR)/ottdres.rc FORCE: depend: $(DEPS) clean: $(E) '$(STAGE) Cleaning up object files' $(Q)rm -f $(DEPS) $(OBJS) $(TTD) $(DEPEND) $(TTD:%=$(BIN_DIR)/%) $(CONFIG_CACHE_COMPILER) $(CONFIG_CACHE_LINKER) $(CONFIG_CACHE_ENDIAN) $(CONFIG_CACHE_SOURCE) $(ENDIAN_TARGETS) mrproper: clean $(Q)rm -f $(SRC_DIR)/rev.cpp $(SRC_DIR)/ottdres.rc %.o: @echo '$(STAGE) No such source-file: $(@:%.o=%).[c|cpp|mm|rc]' .PHONY: all mrproper depend clean FORCE