mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-10-31 15:20:10 +00:00
301 lines
11 KiB
Makefile
301 lines
11 KiB
Makefile
# $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/>.
|
|
|
|
CC_HOST = !!CC_HOST!!
|
|
CXX_HOST = !!CXX_HOST!!
|
|
CC_BUILD = !!CC_BUILD!!
|
|
CXX_BUILD = !!CXX_BUILD!!
|
|
WINDRES = !!WINDRES!!
|
|
STRIP = !!STRIP!!
|
|
CFLAGS = !!CFLAGS!!
|
|
CFLAGS_BUILD = !!CFLAGS_BUILD!!
|
|
CXXFLAGS = !!CXXFLAGS!!
|
|
CXXFLAGS_BUILD = !!CXXFLAGS_BUILD!!
|
|
LIBS = !!LIBS!!
|
|
LDFLAGS = !!LDFLAGS!!
|
|
LDFLAGS_BUILD = !!LDFLAGS_BUILD!!
|
|
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!!
|
|
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)
|
|
|
|
# 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`" != "$(CXXFLAGS) $(CFLAGS)" ]; then echo "$(CXXFLAGS) $(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) $(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) $(CXXFLAGS) $(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)/%.rc=%.rc)'
|
|
$(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_BUILD) $(CXXFLAGS_BUILD) $(CFLAGS_BUILD) $(LDFLAGS_BUILD) -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) $(CFLAGS) -c -o $@ $<
|
|
|
|
$(OBJS_CPP): %.o: $(SRC_DIR)/%.cpp $(DEP_MASK) $(FILE_DEP)
|
|
$(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.cpp=%.cpp)'
|
|
$(Q)$(CXX_HOST) $(CXXFLAGS) $(CFLAGS) -c -o $@ $<
|
|
|
|
$(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 `basename $<` $<
|
|
|
|
$(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) $(CXXFLAGS_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)/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
|
|
|
|
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)/os/windows/ottdres.rc
|
|
|
|
%.o:
|
|
@echo '$(STAGE) No such source-file: $(@:%.o=%).[c|cpp|mm|rc]'
|
|
|
|
.PHONY: all mrproper depend clean FORCE
|