SRC_DIR = @SRC_DIR@ CONFIG_HASH = @CONFIG_HASH@ PACKAGE = @PACKAGE@ PACKAGE_NAME = @PACKAGE_NAME@ PREFIX = @PREFIX@ EPREFIX = @EXEC_PREFIX@ # EPREFIX = @EPREFIX@ BINDIR = @BINDIR@ SBINDIR = @SBINDIR@ LIBEXECDIR = @LIBEXECDIR@ SYSCONFDIR = @SYSCONFDIR@ PACKAGESYSCONFDIR := ${SYSCONFDIR}/${PACKAGE} SHAREDSTATEDIR = @SHAREDSTATEDIR@ LOCALSTATEDIR = @LOCALSTATEDIR@ PACKAGELOCALSTATEDIR := ${LOCALSTATEDIR}/${PACKAGE} LIBDIR = @LIBDIR@ INCLUDEDIR = @INCLUDEDIR@ OLDINCLUDEDIR = @OLDINCLUDEDIR@ DATAROOTDIR = @DATAROOTDIR@ DATADIR = @DATADIR@ PACKAGEDATADIR = @PACKAGEDATADIR@ INFODIR = @INFODIR@ LOCALEDIR = @LOCALEDIR@ MANDIR = @MANDIR@ DOCDIR = @DOCDIR@ HTMLDIR = @HTMLDIR@ DVIDIR = @DVIDIR@ PDFDIR = @PDFDIR@ PSDIR = @PSDIR@ DEBUGDIR = @DEBUGDIR@ BUILD = @BUILD@ HOST = @HOST@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LDLIBS = @LIBS@ # LDLIBS = @LDLIBS@ CXX = @CXX@ CXXFLAGS = @CXXFLAGS@ GTEST_DIR = @GTEST_DIR@ ENABLE_BACKUPS_DURING_INSTALL = @ENABLE_BACKUPS_DURING_INSTALL@ ENABLE_WARNINGS = @ENABLE_WARNINGS@ ENABLE_ABI6 = @ENABLE_ABI6@ ENABLE_CYGWIN_HACKS = @ENABLE_CYGWIN_HACKS@ ENABLE_COMPAT_SYMLINKS = @ENABLE_COMPAT_SYMLINKS@ ENABLE_DEBUG = @ENABLE_DEBUG@ ENABLE_RPATH = @ENABLE_RPATH@ TESTER = TEST_ARGS = ## real.make - The One Makefile that builds them all. ## ## Copyright © 2012-2014 Ben Longbons ## ## This file is part of The Mana World (Athena server) ## ## This program 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, either version 3 of the License, or ## (at your option) any later version. ## ## This program 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 this program. If not, see . # With the One Makefile, you never have to remember to update the list of # objects you need to link your programs. It is designed to behave (almost) # exactly the way you expect a Makefile to act - which cannot be said of # automake, cmake, or qmake. # # The One Makefile lives under the name 'real.make', because it is # reponsible for doing all the actual building, but it is not the file # that the user actually calls (using make) directly. The reason for this # is that the One Makefile requires a certain environment that it cannot # arrange for on its own. # # Specifically: # The -r and -R flags must be passed. # A list of variables must be included, but regenerating Makefile from # Makefile.in is time-consuming, so real.make actually *includes* the # file that called it. # # For an example of how to do this safely, look at the Makefile.in shipped # by TMWA. Of course, you could use any other mechanism to generate a # Makefile, as long as it supplies the appropriate list of variables. # TODO: # 1. Implement support for static libraries # This should be trivial. # 2. Implement support for shared libraries # This requires building two different .o files and such. # 3. Implement support for mixed C and C++ source trees # This just requires writing more patsubst in various places # At that point, they should *probably* be refactored out into functions. # However, it would be hard to allow linking some binaries as pure C. # Unless maybe we should use .c.o and .cpp.o ? # 4. See if something can be done about all the mkdirs. # 5. Remove the few (obvious) bits that are hard-coded for TMWA. # 6. Handle testing better. I'm guessing I should actually compile just # one foo_test.cpp file into each executable test ... # 7. Refactor into several files after all. We need extensibility! # # IWBNMI: # 1. Add 'make check' and 'make installcheck'. # 2. 'make distclean' should remove "anything that ./configure created". # 3. 'make dist' should be implemented. Git only or not? # 4. 'make install' should install documentation. # 5. Split 'make install-exec' and 'make install-data'. Beware etc and var! # 6. '--program-prefix' and '--program-suffix' (easy). What about sed? # 7. Support DESTDIR during 'make install' (URGENT). # 8. 'make distcheck' using the 'make dist' tarball? # 9. Add rules for gettext. # 10. Support per-target build flags? (requires renaming) ifeq ($(findstring s,$(firstword ${MAKEFLAGS})),) ifndef MAKE_RESTARTS # TODO: should I write this in tengwar? # The major problem is that it's usually encoded in the PUA # and thus requires a font specification. # There *is* a formal request and tentative allocation in the SMP, # but it has been languishing for 15 years. # TODO: regardless of the preceding, look up the words for 'build' and 'link'. # (Does there exist a word that could mean "makefile"? # Maybe something like 'instructional scroll') # Note: the space is necessary $(info ) $(info Welcome to the One Makefile) $(info Copyright 2012-2014 Ben Longbons) $(info ) $(info One Makefile to build them all,) $(info One Makefile to find them,) $(info One Makefile to bring them all) $(info and in the darkness link them.) $(info ) else $(info The Road goes ever on and on ...) endif endif c = @colorize 6: 2:$< 3:$@ : ifneq '$c' '' l = @colorize 6: $(patsubst %,2:%,$^) 3:$@ : endif .SUFFIXES: # make 3.81 doesn't support 'undefine' and Debian hasn't shipped it yet # even though all the related bugs have already been fixed. $(foreach var,$(filter-out .% MAKE% SUFFIXES,${.VARIABLES}),$(if $(filter default,$(origin ${var})),$(eval ${var} =))) .SECONDARY: export PATH:=$(realpath ${SRC_DIR}/tools):${PATH} # bash is needed for 'set -o pipefail' below - I have had real bugs there! # It's just not worth the bother to see if another shell works when it # needs to *and* fails when it needs to. Just use bash. SHELL=bash # need to generate source files before path lists $(shell make -f ${SRC_DIR}/generate.make >&2) obj/generated.stamp: # if you get here, the shell above failed false # path lists REAL_SOURCES := $(shell cd ${SRC_DIR}; find src/ -name '*.cpp') REAL_HEADERS := $(shell cd ${SRC_DIR}; find include/ src/ -name '*.hpp' -o -name '*.tcc') PIES := $(shell cd ${SRC_DIR}; find src/ -name '*.py') PIES := $(filter-out src/main-gdb-%.py,${PIES}) SOURCES := ${REAL_SOURCES} HEADERS := ${REAL_HEADERS} PATTERN_ROOTS := $(patsubst src/%.cpp,%,${SOURCES}) PATTERN_MAINS := $(patsubst %/main,%,$(filter %/main,${PATTERN_ROOTS})) PATTERN_LIBS := $(patsubst %/lib,%,$(filter %/lib,${PATTERN_ROOTS})) PATTERN_TESTS := $(patsubst %/test,%,$(filter %/test,${PATTERN_ROOTS})) DEPENDS := $(patsubst src/%.cpp,obj/%.d,${SOURCES}) PREPROCESSED := $(patsubst %.d,%.ii,${DEPENDS}) IRS := $(patsubst %.d,%.ll,${DEPENDS}) BITCODES := $(patsubst %.d,%.bc,${DEPENDS}) ASSEMBLED := $(patsubst %.d,%.s,${DEPENDS}) PDC_OBJECTS := $(patsubst %.d,%.pdc.o,${DEPENDS}) PIC_OBJECTS := $(patsubst %.d,%.pic.o,${DEPENDS}) MAIN_SOURCES := $(filter %/main.cpp,${SOURCES}) LIB_SOURCES := $(filter %/lib.cpp,${SOURCES}) TEST_SOURCES := $(filter %/test.cpp,${SOURCES}) BINARIES := $(patsubst src/%/main.cpp,bin/tmwa-%,${MAIN_SOURCES}) LIBRARIES := $(patsubst src/%/lib.cpp,lib/libtmwa-%.so,${LIB_SOURCES}) TEST_BINARIES := $(patsubst src/%/test.cpp,bin/test-%,${TEST_SOURCES}) # tricky part # We can't put comments in a macro so here goes: # 1: Include the contents of the current %.d file ($1). # 2: For each header, substitute the corresponding %.o's dependency file. # 3: For each lib.hpp header, substitute the corresponding .so library # 4: Remove all non-deps - clutter and lonely headers. # 5: Prevent infinite loops later by filtering out deps we've already seen. # 6: Merge new deps into the existing dep list. # 7: Recurse over all new deps (see 5). define RECURSIVE_DEPS_IMPL $(eval more_deps := $(value ${1})) $(eval more_deps := $(patsubst src/%.hpp,%,${more_deps})) $(eval lib_deps += $(patsubst include/tmwa/%.hpp,lib/libtmwa-%.${SO_LONG},$(filter include/tmwa/%.hpp,${more_deps}))) $(eval more_deps := $(filter ${PATTERN_ROOTS},${more_deps})) $(eval more_deps := $(filter-out ${cur_deps},${more_deps})) $(eval cur_deps += ${more_deps}) $(foreach dep,${more_deps},${call RECURSIVE_DEPS_IMPL,${dep}}) endef # 1: Initialize the dep list ($1 is a %.d). # 2: Call the real function on it. # 3: Blank for clarity. # 4: Expand to text. Note that *nothing* else actually produces anything! define RECURSIVE_DEPS $(eval cur_deps := ${1}) $(eval lib_deps :=) $(call RECURSIVE_DEPS_IMPL,${1}) ${cur_deps} endef # Apply the rules to all the main.cpp files # (now below, since it has to go below the include) # utility functions for the rules MKDIR_FIRST = @mkdir -p ${@D} # Stuff sensitive to attoconf CPPFLAGS += ${WARNINGS} ifeq (${ENABLE_WARNINGS},yes) WARNINGS := -include ${SRC_DIR}/src/warnings.hpp endif # related to gdb bug 15801 ifeq (${ENABLE_ABI6},yes) CXXFLAGS += -fabi-version=6 endif # This needs to edit CXX instead of CXXFLAGS in order to make # the %.ii rule work. ifeq (${ENABLE_CYGWIN_HACKS},yes) override CXX += -std=gnu++0x else override CXX += -std=c++0x endif CXXFLAGS += -fstack-protector override CXXFLAGS += -fno-strict-aliasing override CXXFLAGS += -fvisibility=hidden nothing= space=${nothing} ${nothing} define relpath $(subst ${space},/,$(foreach component,$(subst /,${space},$1),..))$2 endef ,=, ifeq (${ENABLE_RPATH},relative) rel_BINDIR := $(subst ${EPREFIX},,${BINDIR}) rel_LIBDIR := $(subst ${EPREFIX},,${LIBDIR}) ifneq (${EPREFIX}${rel_BINDIR},${BINDIR}) $(error BINDIR must be within EPREFIX to use relative rpath) endif ifneq (${EPREFIX}${rel_LIBDIR},${LIBDIR}) $(error LIBDIR must be within EPREFIX to use relative rpath) endif override LDFLAGS += -Wl,-rpath='$$ORIGIN/$(call relpath,${rel_BINDIR},${rel_LIBDIR})' endif ifeq (${ENABLE_RPATH},absolute) override LDFLAGS += -Wl,rpath=${LIBDIR} override LDFLAGS += $(patsubst -L%,-Wl$,rpath=%,$(filter -L%,${LDFLAGS})) endif # above is configury # below are actual rules # first pass, include silently, but force rebuild ifndef MAKE_RESTARTS # disabled due to bad interaction with generating dependencies that fail #-include ${DEPENDS} include ${DEPENDS} else include ${DEPENDS} endif include ${SRC_DIR}/version.make thisdir := $(abspath .) #$(foreach root,${PATTERN_ROOTS},$(info pre-root: ${root} := $(value ${root}))$(info )) # can't do $(filter %.hpp yet) $(foreach root,${PATTERN_ROOTS},$(eval ${root} := $(sort $(patsubst ${thisdir}/%,%,$(abspath $(patsubst ${SRC_DIR}/%,%,$(wildcard $(value ${root})) $(filter conf-raw/%.h,$(value ${root})))))))) # have to redo what we undid to get it as a variable $(foreach root,${PATTERN_ROOTS},$(eval obj/${root}.ii obj/${root}.ll obj/${root}.bc obj/${root}.s obj/${root}.pdc.o obj/${root}.pic.o obj/${root}.d : $(value ${root})) ) #$(foreach root,${PATTERN_ROOTS},$(info post-root: ${root} := $(value ${root}))$(info )) # test.o implicitly (NOT explicitly) depends on all (nonexistent) test_*.hpp # TODO actually have more than one test.o, each with its own set of files #$(foreach test,${PATTERN_TESTS},$(eval ${test}/test += $(patsubst %,src/%.hpp,$(filter %_test,${PATTERN_ROOTS})))) # FIXME find a better way $(foreach test,tests,$(eval ${test}/test += $(patsubst %,src/%.hpp,$(filter %_test,${PATTERN_ROOTS})))) $(foreach main,${PATTERN_MAINS},$(eval main-${main} := $(strip $(call RECURSIVE_DEPS,${main}/main))) $(eval main-${main}-libs := ${lib_deps})) # actual rule deps $(foreach main,${PATTERN_MAINS},$(eval bin/tmwa-${main} : $(patsubst %,obj/%.pdc.o,$(value main-${main})) $(value main-${main}-libs))) $(foreach main,${PATTERN_MAINS},$(eval bin/tmwa-${main}-gdb.py : $(filter ${PIES},$(patsubst %,src/%.py,$(value main-${main}))))) #$(foreach main,${PATTERN_MAINS},$(info post-main: main-${main}: $(value main-${main})) $(info post-main: main-${main}-libs: $(value main-${main}-libs)) $(info )) $(foreach lib,${PATTERN_LIBS},$(eval lib-${lib} := $(strip $(call RECURSIVE_DEPS,${lib}/lib))) $(eval lib-${lib}-libs := ${lib_deps})) # actual rule deps $(foreach lib,${PATTERN_LIBS},$(eval lib/libtmwa-${lib}.${SO_LONG} : $(patsubst %,obj/%.pic.o,$(value lib-${lib})) $(filter-out lib/libtmwa-${lib}.${SO_LONG},$(value lib-${lib}-libs)))) $(foreach lib,${PATTERN_LIBS},$(eval lib/libtmwa-${lib}.${SO_LONG}-gdb.py : $(filter ${PIES},$(patsubst %,src/%.py,$(value lib-${lib}))))) #$(foreach lib,${PATTERN_LIBS},$(info post-lib: lib-${lib}: $(value lib-${lib})) $(info post-lib: lib-${lib}-libs: $(value lib-${lib}-libs)) $(info )) $(foreach test,${PATTERN_TESTS},$(eval test-${test} := $(strip $(call RECURSIVE_DEPS,${test}/test))) $(eval test-${test}-libs := ${lib_deps})) # actual rule deps $(foreach test,${PATTERN_TESTS},$(eval bin/test-${test} : $(patsubst %,obj/%.pdc.o,$(value test-${test})) $(value test-${test}-libs))) $(foreach test,${PATTERN_TESTS},$(eval bin/test-${test}-gdb.py : $(filter ${PIES},$(patsubst %,src/%.py,$(value test-${test}))))) #$(foreach test,${PATTERN_TESTS},$(info post-test: test-${test}: $(value test-${test})) $(info post-test: test-${test}-libs: $(value test-${test}-libs)) $(info )) vpath %.cpp ${SRC_DIR} vpath %.hpp ${SRC_DIR} vpath %.tcc ${SRC_DIR} vpath tools/% ${SRC_DIR} vpath %.py ${SRC_DIR} .DELETE_ON_ERROR: .DEFAULT_GOAL := all # main goals all: bin lib bin: ${BINARIES} lib: $(patsubst %.so,%.${SO_LONG},${LIBRARIES}) ii: ${PREPROCESSED} ll: ${IRS} bc: ${BITCODES} s: ${ASSEMBLED} o: ${PDC_OBJECTS} # why not PIC objects? Because this is only for debugging, so we don't need # duplicates, and PDC is more common, and also some override rules are only # currently defined for PDC clean-stamp: -$l find obj -name '*.stamp' -delete clean-deps: -$l find obj -name '*.d' -delete clean-format: -$l find obj -name '*.formatted' -delete clean-obj: -$l find obj -name '*.o' -delete clean-conf: $l rm -rf conf-raw mostlyclean: clean-conf $l rm -rf obj clean: mostlyclean $l rm -rf bin lib distclean: clean gen-clean gen-clean: $l rm -f obj/generated.stamp $l rm -rf ${SRC_DIR}/src/proto2/ $l rm -rf ${SRC_DIR}/src/debug-debug/ ifndef MAKE_RESTARTS obj/%.d: src/%.cpp | obj/generated.stamp $(MKDIR_FIRST) # Not using $c because it's slow and this should be fast ${CXX} ${CPPFLAGS} -DGENERATING_DEPENDENCIES ${CXXFLAGS} -MG -MM \ -MT '$(patsubst obj/%.d,%,$@) := ' \ -MF $@ $< endif # the above SRC_DIR replacement is not really safe, but it works okayish. obj/%.ii: src/%.cpp $(MKDIR_FIRST) $c ${CXX} ${CPPFLAGS} -E -o $@ $< obj/%.ll: src/%.cpp $(MKDIR_FIRST) $c ${CXX} ${CPPFLAGS} ${CXXFLAGS} -S -emit-llvm -o $@ $< obj/%.bc: src/%.cpp $(MKDIR_FIRST) $c ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -emit-llvm -o $@ $< obj/%.s: src/%.cpp $(MKDIR_FIRST) $c ${CXX} ${CPPFLAGS} ${CXXFLAGS} -S -o $@ $< obj/%.pdc.o: src/%.cpp $(MKDIR_FIRST) $c ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $< obj/%.pic.o: src/%.cpp $(MKDIR_FIRST) $c ${CXX} ${CPPFLAGS} ${CXXFLAGS} -fPIC -c -o $@ $< bin/%-gdb.py: src/main-gdb-head.py src/main-gdb-tail.py $(MKDIR_FIRST) cat $(filter %/main-gdb-head.py,$^) \ $(filter-out %/main-gdb-head.py %/main-gdb-tail.py,$^) \ $(filter %/main-gdb-tail.py,$^) \ > $@ bin/%: bin/%-gdb.py $(MKDIR_FIRST) $l ${CXX} ${LDFLAGS} $(filter-out bin/%-gdb.py,$^) ${LDLIBS} -o $@ lib/%.${SO_LONG}-gdb.py: $(MKDIR_FIRST) cat ${SRC_DIR}/src/main-gdb-head.py \ $^ \ ${SRC_DIR}/src/main-gdb-tail.py \ > $@ lib/%.${SO_LONG}: lib/%.${SO_LONG}-gdb.py $(MKDIR_FIRST) $l ${CXX} -shared -Wl,-soname=$*.${SO_SHORT} ${LDFLAGS} $(filter-out lib/%-gdb.py,$^) ${LDLIBS} -o $@ $c ln -sf $*.${SO_LONG} lib/$*.${SO_SHORT} $c ln -sf $*.${SO_SHORT} lib/$*.so #${TEST_BINARIES}: obj/gtest-all.pdc.o bin/test-tests: obj/gtest-all.pdc.o # This isn't perfect. $(filter %_test.pdc.o,${PDC_OBJECTS}) obj/gtest-all.pdc.o: override CPPFLAGS += -DGTEST_HAS_PTHREAD=0 -I${GTEST_DIR} obj/gtest-all.pdc.o: override WARNINGS := obj/gtest-all.pdc.o: ${GTEST_DIR}/src/gtest-all.cc $(MKDIR_FIRST) $c ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $< obj/debug-debug/test.o: override CXXFLAGS += -g -O0 obj/run-test-debug-debug.stamp: TESTER=gdb -return-child-result -nx -batch -iex 'set auto-load safe-path /' -x ${SRC_DIR}/tools/debug-debug.gdb obj/run-test-debug-debug.stamp: tools/debug-debug.gdb test: $(patsubst bin/%,obj/run-%.stamp,${TEST_BINARIES}) obj/run-%.stamp: bin/% ${TESTER} $< ${TEST_ARGS} touch $@ install := install --backup=${ENABLE_BACKUPS_DURING_INSTALL} install_exe := ${install} install_dir := ${install} -d install_data := ${install} -m 0644 install_symlink := ln --backup=${ENABLE_BACKUPS_DURING_INSTALL} -sf install: @echo = Done installing install: install-bin install-bin: @echo + Installing binaries ${install_dir} ${DESTDIR}${BINDIR} ${install_exe} -t ${DESTDIR}${BINDIR} \ ${BINARIES} install-bin: install-bin-compat install-bin-compat: ifeq (${ENABLE_COMPAT_SYMLINKS},yes) @echo + Installing compatibility symlinks ${install_dir} ${DESTDIR}${BINDIR} ${install_symlink} tmwa-login ${DESTDIR}${BINDIR}/login-server ${install_symlink} tmwa-char ${DESTDIR}${BINDIR}/char-server ${install_symlink} tmwa-map ${DESTDIR}${BINDIR}/map-server ${install_symlink} tmwa-admin ${DESTDIR}${BINDIR}/ladmin ${install_symlink} tmwa-monitor ${DESTDIR}${BINDIR}/eathena-monitor else @echo - Not installing compatibility symlinks endif install: install-lib install-lib: @echo + Install libraries ${install_dir} ${DESTDIR}${LIBDIR} ${install_data} -t ${DESTDIR}${LIBDIR} \ $(patsubst %.so,%.${SO_LONG},${LIBRARIES}) for lib in $(patsubst lib/%.so,%,${LIBRARIES}); do \ ln -sf $$lib.${SO_LONG} ${DESTDIR}${LIBDIR}/$$lib.${SO_SHORT}; \ ln -sf $$lib.${SO_SHORT} ${DESTDIR}${LIBDIR}/$$lib.so; \ done install: install-debug install-debug: ifeq (${ENABLE_DEBUG},yes) @echo + Installing debug files ${install_dir} ${DESTDIR}${DEBUGDIR}${BINDIR} ${install_data} -t ${DESTDIR}${DEBUGDIR}${BINDIR} \ $(patsubst %,%-gdb.py,${BINARIES}) ${install_dir} ${DESTDIR}${DEBUGDIR}${LIBDIR} ${install_data} -t ${DESTDIR}${DEBUGDIR}${LIBDIR} \ $(patsubst %.so,%.${SO_LONG}-gdb.py,${LIBRARIES}) else @echo - Not installing debug files endif install: install-include install-include: @echo + Install headers ${install_dir} ${DESTDIR}${INCLUDEDIR} ${install_data} -t ${DESTDIR}${INCLUDEDIR} \ $(addprefix ${SRC_DIR}/,$(filter include/%,${HEADERS})) install: install-state install-state: @echo + Install statedir ${install_dir} ${DESTDIR}${PACKAGELOCALSTATEDIR} touch ${DESTDIR}${PACKAGELOCALSTATEDIR}/.keep install: install-data install-data: @echo + Install data ${install_dir} ${DESTDIR}${PACKAGEDATADIR} ${install_data} -t ${DESTDIR}${PACKAGEDATADIR} \ ${SRC_DIR}/share/tmwa/* install: install-conf install-conf: @echo + Install config files ${install_dir} ${DESTDIR}${PACKAGESYSCONFDIR} ${install_data} -t ${DESTDIR}${PACKAGESYSCONFDIR} \ ${SRC_DIR}/etc/tmwa/* tags: ${SOURCES} ${HEADERS} $l ctags --totals -h .tcc --langmap=C++:+.tcc --c-kinds=+px -f $@ $^ Makefile: ${SRC_DIR}/Makefile.in @echo Makefile.in updated, reconfiguring ... ./config.status # TODO - fix pattern priority bug so I can make these .hpp # # This is complicated and still isn't optimal. conf-raw/int-%.h: FORCE $(MKDIR_FIRST) @echo '#define $* $(value $*)' | maybe-replace $@ bool_yes := true bool_no := false conf-raw/bool-%.h: FORCE $(MKDIR_FIRST) @echo '#define $* $(bool_$(value $*))' | maybe-replace $@ conf-raw/str-%.h: FORCE $(MKDIR_FIRST) @echo '#define $* "$(value $*)"_s' | maybe-replace $@ FORCE: ; .PHONY: FORCE override CPPFLAGS += -I . -I ${SRC_DIR}/include # distribution tarballs # this only works from within a git checkout dist/%/version.make: $(MKDIR_FIRST) git --git-dir=${SRC_DIR}/.git show HEAD:version.make > $@ sed 's/^VERSION_FULL := .*/#&\nVERSION_FULL := ${VERSION_FULL}/' -i $@ sed 's/^VERSION_HASH := .*/#&\nVERSION_HASH := ${VERSION_HASH}/' -i $@ dist/%-src.tar: dist/%/version.make git --git-dir=${SRC_DIR}/.git archive --prefix=$*/ -o $@ HEAD ( mtime="$$(git --git-dir=${SRC_DIR}/.git log -n1 --pretty=%ci)" && cd dist && tar uf $*-src.tar --mtime="$${mtime}" --mode=664 --owner=root --group=root $*/version.make ) rm dist/$*/version.make rmdir dist/$*/ dist/%-attoconf-only.tar: $(MKDIR_FIRST) git --git-dir=${SRC_DIR}/deps/attoconf/.git archive --prefix=$*/deps/attoconf/ HEAD -o $@ dist/%-bundled.tar: dist/%-src.tar dist/%-attoconf-only.tar cp dist/$*-src.tar $@ tar Af $@ dist/$*-attoconf-only.tar dist/%-bin-${HOST}.tar: all ${MAKE} install DESTDIR=$(abspath dist/${HOST}/$*) if test -n '${BUNDLED_LIBS}'; then cp ${BUNDLED_LIBS} dist/${HOST}/$*/${LIBDIR}/; fi tar cf $@ -C dist/${HOST} $* rm -r dist/${HOST}/ dist: dist/tmwa-${VERSION_FULL}-src.tar dist/tmwa-${VERSION_FULL}-bundled.tar ifneq '' '${HOST}' bindist: dist/tmwa-${VERSION_FULL}-bin-${HOST}.tar else bindist: @echo @echo @echo "Fatal Error: 'make bindist' requires './configure --host='." @echo "Maybe you want `${CXX} -v 2>&1 | sed -n '/Target: /{s///;p}'`, but I refuse to guess," @echo "because there are too many options like -m32 that confuse me." @echo @echo @false endif .PHONY: dist format: format-cpp format-hpp format-cpp: $(patsubst src/%,obj/%.formatted,${REAL_SOURCES}) format-hpp: $(patsubst src/%,obj/%.formatted,${REAL_HEADERS}) obj/%.cpp.formatted: src/%.cpp tools/indenter $(MKDIR_FIRST) apply-filter 'indenter -cpp' $< fgrep -q Copyright $< fgrep -q $(notdir $<) $< fgrep -q ../poison.hpp $< grep -q '^namespace tmwa$$' $< grep -q '^} // namespace tmwa$$' $< touch $@ obj/%.hpp.formatted: src/%.hpp tools/indenter $(MKDIR_FIRST) apply-filter 'indenter -cpp' $< fgrep -q Copyright $< fgrep -q $(notdir $<) $< if [[ $< == *fwd* ]]; then fgrep -q ../sanity.hpp $<; else fgrep -q '"fwd.hpp"' $<; fi if [[ $< == *fwd* ]]; then ! fgrep -q '"fwd.hpp"' $<; else ! fgrep -q ../sanity.hpp $<; fi grep -q '^namespace tmwa$$' $< grep -q '^} // namespace tmwa$$' $< grep -q '^#pragma once$$' $< touch $@ obj/%.tcc.formatted: src/%.tcc tools/indenter $(MKDIR_FIRST) apply-filter 'indenter -cpp' $< fgrep -q Copyright $< fgrep -q $(notdir $<) $< grep -q '^namespace tmwa$$' $< grep -q '^} // namespace tmwa$$' $< touch $@ .PHONY: format format-cpp format-hpp most: $(filter-out bin/tmwa-map,${BINARIES}) magic: $(filter obj/map/magic%,${PDC_OBJECTS}) common: $(filter-out %/lib.pdc.o %_test.pdc.o obj/login/% obj/char/% obj/map/% obj/admin/% obj/monitor/%,${PDC_OBJECTS})