Version information is in output of commands version, xdump version, and in program output for option -v. Looks like this: Wolfpack Empire 4.3.33 The version number is defined in configure.ac, and incremented manually. It identifies only the base release (here: 4.3.33). Fine when this is an unmodified released version. Pretty much useless during development. Add a suffix to the version number that describes it further: V Unmodified release V (same as before) V.N-H Modified release built from a clean git tree N is the number of additional commits, and H is the abbreviated commit hash V.N-H-dirty Same, but the working tree is dirty V-dirty Modified release built from a tarball A git tree is clean when the contents of its files are unchanged. Changing only the their timestamps doesn't count. It does count when building from a tarball, because tracking contents isn't implemented there. Also use this suffixed version for tarball names. The version reported by configure is fixed at configure generation time, i.e. it is usually out of date during development. Ensuring a release tarball contains one with a current version is manual for now. Running autoconf -f should do the trick. Elsewhere, the version is determined at build time, so it is always current. Dirty tracking isn't implemented in the standalone client build. If you start with a clean tarball, the version will not change from V to V-dirty when you build with modifications. Steal build-aux/git-version-gen from autoconf 2.69 to help with computing the version string. Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
461 lines
15 KiB
Makefile
461 lines
15 KiB
Makefile
#
|
|
# Empire - A multi-player, client/server Internet based war game.
|
|
# Copyright (C) 1986-2016, Dave Pare, Jeff Bailey, Thomas Ruschak,
|
|
# Ken Stevens, Steve McClure, Markus Armbruster
|
|
#
|
|
# Empire 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 <http://www.gnu.org/licenses/>.
|
|
#
|
|
# ---
|
|
#
|
|
# See files README, COPYING and CREDITS in the root of the source
|
|
# tree for related information and legal notices. It is expected
|
|
# that future projects/authors will amend these files as needed.
|
|
#
|
|
# ---
|
|
#
|
|
# Make.mk: The real Makefile, included by GNUmakefile
|
|
#
|
|
# Known contributors to this file:
|
|
# Markus Armbruster, 2005-2016
|
|
#
|
|
|
|
# This makefile was inspired by `Recursive Make Considered Harmful',
|
|
# Peter Miller, 1997.
|
|
# http://miller.emu.id.au/pmiller/books/rmch/
|
|
|
|
# Recursively expanded variables are occasionally useful, but can be
|
|
# slow and tricky. Do not use them gratuitously. If you don't
|
|
# understand this, always use `:=' rather than `='.
|
|
|
|
# Default goal
|
|
all:
|
|
|
|
# Delete target on error. Every Makefile should have this.
|
|
.DELETE_ON_ERROR:
|
|
|
|
# Source files
|
|
ifeq ($(revctrl),git)
|
|
src := $(shell cd $(srcdir) && git ls-files | uniq)
|
|
version := $(shell cd $(srcdir) && build-aux/git-version-gen /dev/null)
|
|
else
|
|
include $(srcdir)/sources.mk
|
|
version := $(shell cat $(srcdir)/.tarball-version || echo "UNKNOWN")
|
|
endif
|
|
ifeq ($(version),UNKNOWN)
|
|
$(error cannot figure out version)
|
|
endif
|
|
dirs := $(sort $(dir $(src)))
|
|
csrc := $(filter %.c, $(src))
|
|
tsrc := $(filter %.t, $(src))
|
|
man6 := $(filter man/%.6, $(src))
|
|
builtins := $(filter src/lib/global/%.config, $(src))
|
|
|
|
# Info subjects
|
|
include $(srcdir)/info/subjects.mk
|
|
|
|
# Abbreviations
|
|
topics := $(patsubst %.t,%,$(notdir $(tsrc)))
|
|
info := $(topics) $(subjects) all TOP
|
|
scripts := $(srcdir)/src/scripts
|
|
depcomp := $(SHELL) $(srcdir)/depcomp
|
|
tarball := $(SHELL) -e $(scripts)/tarball
|
|
econfig := $(sysconfdir)/empire/econfig
|
|
schedule := $(sysconfdir)/empire/schedule
|
|
gamedir := $(localstatedir)/empire
|
|
edatadir := $(datadir)/empire
|
|
builtindir := $(edatadir)/builtin
|
|
einfodir := $(edatadir)/info.nr
|
|
ehtmldir := $(edatadir)/info.html
|
|
client/w32 := arpa/inet.h netdb.h netinet/in.h sys/time.h sys/socket.h \
|
|
sys/uio.h unistd.h w32io.c w32sockets.c w32types.h
|
|
|
|
# Abbreviate make output
|
|
# Run make with a V=1 parameter for full output.
|
|
ifneq ($(origin V),command line)
|
|
V:=
|
|
endif
|
|
# $(call quiet-command COMMAND,ABBREV) runs COMMAND, but prints only ABBREV.
|
|
# Recursively expanded so that variables in COMMAND and ABBREV work.
|
|
ifneq ($V$(findstring s,$(MAKEFLAGS)),)
|
|
quiet-command = $1
|
|
else
|
|
quiet-command = @echo $2 && $1
|
|
endif
|
|
|
|
# How to substitute Autoconf output variables
|
|
# Recursively expanded so that $@ and $< work.
|
|
subst.in = sed \
|
|
-e 's?@configure_input\@?$(notdir $@): Generated from $(notdir $<) by make.?g' \
|
|
-e 's?@builtindir\@?$(builtindir)?g' \
|
|
-e 's?@econfig\@?$(econfig)?g' \
|
|
-e 's?@einfodir\@?$(einfodir)?g' \
|
|
-e 's?@gamedir\@?$(gamedir)?g' \
|
|
-e 's/@EMPIREHOST\@/$(EMPIREHOST)/g' \
|
|
-e 's/@EMPIREPORT\@/$(EMPIREPORT)/g'
|
|
|
|
# Generated files
|
|
# See `Cleanliness' below
|
|
# Generated makefiles, distributed by dist-source from $(srcdir):
|
|
mk := sources.mk
|
|
# Generated by Autoconf, not distributed:
|
|
ac := config.h config.log config.status info.html info.nr lib stamp-h
|
|
ac += $(basename $(filter %.in, $(src)))
|
|
ac += $(srcdir)/autom4te.cache $(srcdir)/src/client/autom4te.cache
|
|
# distributed by dist-source from $(srcdir):
|
|
acdist := aclocal.m4 config.h.in configure stamp-h.in
|
|
# distributed by dist-client from $(srcdir):
|
|
acdistcli := $(addprefix src/client/, aclocal.m4 config.h.in configure)
|
|
# Object files:
|
|
obj := $(csrc:.c=.o) $(filter %.o, $(ac:.c=.o))
|
|
# Dependencies:
|
|
deps := $(obj:.o=.d)
|
|
# Library archives:
|
|
libs := $(addprefix lib/, libcommon.a libgen.a libglobal.a)
|
|
# Programs:
|
|
util := $(addprefix src/util/, $(addsuffix $(EXEEXT), empdump empsched fairland files pconfig))
|
|
client := src/client/empire$(EXEEXT)
|
|
server := src/server/emp_server$(EXEEXT)
|
|
# Info subjects:
|
|
tsubj := $(addprefix info/, $(addsuffix .t, $(subjects)))
|
|
# Formatted info:
|
|
info.nr := $(addprefix info.nr/, $(info))
|
|
info.html := $(addprefix info.html/, $(addsuffix .html, $(info)))
|
|
info.all := $(info.nr) $(info.html) info.ps info/stamp-subj
|
|
# Tests
|
|
# sandbox
|
|
|
|
# Conditionally generated files:
|
|
empth_obj := src/lib/empthread/io.o
|
|
empth_lib :=
|
|
ifeq ($(empthread),LWP)
|
|
empth_obj += src/lib/empthread/lwp.o src/lib/empthread/posix.o
|
|
empth_lib += lib/liblwp.a
|
|
endif
|
|
ifeq ($(empthread),POSIX)
|
|
empth_obj += src/lib/empthread/pthread.o src/lib/empthread/posix.o
|
|
endif
|
|
ifeq ($(empthread),Windows)
|
|
empth_obj += src/lib/empthread/ntthread.o
|
|
endif
|
|
|
|
ifeq ($(empthread),Windows) # really: W32, regardless of thread package
|
|
libs += lib/libw32.a
|
|
$(client): lib/libw32.a
|
|
endif
|
|
|
|
# Cleanliness
|
|
# Each generated file should be in one of the following sets.
|
|
# Removed by clean:
|
|
clean := $(obj) $(deps) $(libs) $(util) $(client) $(server) $(tsubj) \
|
|
info/toc info/TOP.t $(info.all) $(empth_obj) $(empth_lib) sandbox
|
|
# Removed by distclean:
|
|
distclean := $(ac)
|
|
ifeq ($(revctrl),git)
|
|
distclean += $(addprefix $(srcdir)/, $(mk))
|
|
endif
|
|
# Distributed by dist-source from $(srcdir):
|
|
src_distgen := $(acdist) $(mk)
|
|
# Distributed by dist-client from $(srcdir)/src/client; removed by distclean:
|
|
cli_distgen := $(acdistcli)
|
|
|
|
# Compiler flags
|
|
CPPFLAGS += -I$(srcdir)/include -I.
|
|
ifeq ($(empthread),Windows) # really: W32, regardless of thread package
|
|
CPPFLAGS += -I$(srcdir)/src/lib/w32
|
|
endif
|
|
$(client): LDLIBS := $(LIBS_client)
|
|
$(server): LDLIBS := $(LIBS_server)
|
|
|
|
|
|
### Advertized goals
|
|
|
|
.PHONY: all
|
|
all: $(util) $(client) $(server) info
|
|
|
|
.PHONY: info html
|
|
info: $(info.nr)
|
|
html: $(info.html)
|
|
|
|
.PHONY: clean
|
|
clean:
|
|
$(call quiet-command,rm -rf $(clean),CLEAN)
|
|
|
|
.PHONY: distclean
|
|
distclean: clean
|
|
$(call quiet-command,rm -rf $(distclean) $(cli_distgen),DISTCLEAN)
|
|
|
|
.PHONY: install
|
|
install: all installdirs
|
|
$(INSTALL_PROGRAM) $(util) $(server) $(sbindir)
|
|
$(INSTALL_PROGRAM) $(client) $(bindir)
|
|
$(INSTALL) -m 444 $(addprefix $(srcdir)/, $(builtins)) $(builtindir)
|
|
rm -f $(einfodir)/*
|
|
$(INSTALL_DATA) $(info.nr) $(einfodir)
|
|
$(INSTALL_DATA) $(addprefix $(srcdir)/, $(man6)) $(mandir)/man6
|
|
sed -e '1,/^$$/d' -e 's/^/# /g' <$(srcdir)/doc/schedule >$(schedule).dist
|
|
echo >>$(schedule).dist
|
|
echo 'every 10 minutes' >>$(schedule).dist
|
|
[ -e $(schedule) ] || mv $(schedule).dist $(schedule)
|
|
if [ -e $(econfig) ]; then \
|
|
echo "Attempting to update your econfig"; \
|
|
if src/util/pconfig $(econfig) >$(econfig).dist; then \
|
|
if cmp -s $(econfig) $(econfig).dist; then \
|
|
echo "$(econfig) unchanged"; \
|
|
rm $(econfig).dist; \
|
|
fi; \
|
|
else \
|
|
echo "Your $(econfig) doesn't work"; \
|
|
src/util/pconfig >$(econfig).dist; \
|
|
fi; \
|
|
if [ -e $(econfig).dist ]; then \
|
|
echo "Check out $(econfig).dist"; \
|
|
fi; \
|
|
else \
|
|
src/util/pconfig >$(econfig); \
|
|
fi
|
|
|
|
.PHONY: installdirs
|
|
installdirs:
|
|
mkdir -p $(sbindir) $(bindir) $(builtindir) $(einfodir) $(mandir)/man6 $(dir $(econfig)) $(gamedir)
|
|
|
|
.PHONY: install-html
|
|
install-html: html
|
|
mkdir -p $(ehtmldir)
|
|
rm -f $(ehtmldir)/*
|
|
$(INSTALL_DATA) $(info.html) $(ehtmldir)
|
|
|
|
.PHONY: uninstall
|
|
uninstall:
|
|
rm -f $(addprefix $(sbindir)/, $(notdir $(util) $(server)))
|
|
rm -f $(addprefix $(bindir)/, $(notdir $(client)))
|
|
rm -rf $(builtindir) $(einfodir) $(ehtmldir)
|
|
rmdir $(edatadir)
|
|
rm -f $(addprefix $(mandir)/man6/, $(notdir $(man6)))
|
|
@echo "$(dir $(econfig)) and $(gamedir) not removed, you may wish to remove it manually."
|
|
|
|
.PHONY: dist
|
|
dist: dist-source dist-client dist-info
|
|
|
|
.PHONY: check check-accept _check
|
|
check check-accept: _check
|
|
check: export EMPIRE_CHECK_ACCEPT :=
|
|
check-accept: export EMPIRE_CHECK_ACCEPT := y
|
|
_check: all
|
|
@echo "Warning: test suite is immature and needs work." >&2
|
|
$(srcdir)/tests/files-test $(srcdir)
|
|
$(srcdir)/tests/fairland-test $(srcdir)
|
|
$(srcdir)/tests/info-test $(srcdir)
|
|
ifeq ($(empthread),LWP)
|
|
$(srcdir)/tests/smoke-test $(srcdir)
|
|
$(srcdir)/tests/actofgod-test $(srcdir)
|
|
$(srcdir)/tests/build-test $(srcdir)
|
|
$(srcdir)/tests/navi-march-test $(srcdir)
|
|
$(srcdir)/tests/fire-test $(srcdir)
|
|
$(srcdir)/tests/torpedo-test $(srcdir)
|
|
$(srcdir)/tests/bridgefall-test $(srcdir)
|
|
$(srcdir)/tests/retreat-test $(srcdir)
|
|
$(srcdir)/tests/update-test $(srcdir)
|
|
$(srcdir)/tests/version-test $(srcdir)
|
|
else
|
|
@echo "$(srcdir)/tests/smoke-test SKIPPED"
|
|
@echo "$(srcdir)/tests/actofgod-test SKIPPED"
|
|
@echo "$(srcdir)/tests/build-test SKIPPED"
|
|
@echo "$(srcdir)/tests/navi-march-test SKIPPED"
|
|
@echo "$(srcdir)/tests/fire-test SKIPPED"
|
|
@echo "$(srcdir)/tests/torpedo-test SKIPPED"
|
|
@echo "$(srcdir)/tests/bridgefall-test SKIPPED"
|
|
@echo "$(srcdir)/tests/retreat-test SKIPPED"
|
|
@echo "$(srcdir)/tests/update-test SKIPPED"
|
|
@echo "$(srcdir)/tests/version-test SKIPPED"
|
|
endif
|
|
$(srcdir)/tests/empdump-test $(srcdir)
|
|
|
|
|
|
### Implicit rules
|
|
|
|
# Compile with dependencies as side effect, i.e. create %.d in
|
|
# addition to %.o.
|
|
ifeq ($(how_to_dep),fast)
|
|
%.o: %.c
|
|
$(call quiet-command,$(COMPILE.c) -MT $@ -MMD -MP -MF $(@:.o=.d) \
|
|
$(OUTPUT_OPTION) $< || { rm -f $(@:.o=.d) $@; false; },CC $@)
|
|
# Why the rm? If gcc's preprocessor chokes, it leaves an empty
|
|
# dependency file behind, and doesn't touch the object file. If an
|
|
# old object file exists, and is newer than the .c file, make will
|
|
# then consider the object file up-to-date.
|
|
endif
|
|
ifeq ($(how_to_dep),depcomp)
|
|
%.o: %.c
|
|
$(call quiet-command,source='$<' object='$@' depfile='$(@:.o=.d)' \
|
|
$(CCDEPMODE) $(depcomp) $(COMPILE.c) $(OUTPUT_OPTION) $<,CC $@)
|
|
endif
|
|
# Cancel the rule to compile %.c straight to %, it interferes with
|
|
# automatic dependency generation
|
|
%: %.c
|
|
|
|
%$(EXEEXT): %.o
|
|
$(call quiet-command,$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@,LINK $@)
|
|
|
|
|
|
info.nr/%: info/%.t
|
|
$(call quiet-command,$(NROFF) $(filter %.MAC, $^) $< | $(AWK) -f $(filter %/Blank.awk, $^) >$@ && test -s $@,NROFF $@)
|
|
# Pipes in make are a pain. The "test -s" catches obvious errors.
|
|
|
|
info.html/%.html: info/%.t
|
|
$(call quiet-command,perl $(srcdir)/info/emp2html.pl $(info) <$< >$@,GEN $@)
|
|
|
|
|
|
### Explicit rules
|
|
|
|
# Compilation
|
|
|
|
$(server): $(filter src/server/% src/lib/commands/% src/lib/player/% src/lib/subs/% src/lib/update/%, $(obj)) $(empth_obj) $(empth_lib) $(libs)
|
|
$(call quiet-command,$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@,LINK $@)
|
|
|
|
$(client): $(filter src/client/%, $(obj)) src/lib/global/version.o
|
|
$(call quiet-command,$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@,LINK $@)
|
|
|
|
$(util): $(libs)
|
|
|
|
lib/libcommon.a: $(filter src/lib/common/%, $(obj))
|
|
lib/libgen.a: $(filter src/lib/gen/%, $(obj))
|
|
lib/libglobal.a: $(filter src/lib/global/%, $(obj))
|
|
lib/liblwp.a: $(filter src/lib/lwp/%, $(obj))
|
|
lib/libw32.a: $(filter src/lib/w32/%, $(obj))
|
|
|
|
$(libs) $(empth_lib):
|
|
$(call quiet-command,$(AR) rc $@ $?,AR $@)
|
|
$(RANLIB) $@
|
|
|
|
src/lib/global/version.o: CPPFLAGS += -DVERSION='"$(version)"'
|
|
src/lib/global/version.o: $(src)
|
|
|
|
ifneq ($(revctrl),git)
|
|
$(srcdir)/.tarball-version: $(src)
|
|
v=`sed -e 's/-dirty$$//' <$@`; echo "$$v-dirty" >$@
|
|
# Force Make to start over after updating .tarball-version, so that
|
|
# $(version) gets the new value
|
|
$(srcdir)/.dirty-stamp: .tarball-version
|
|
>$@
|
|
include $(srcdir)/.dirty-stamp
|
|
endif
|
|
|
|
# Info formatting
|
|
|
|
# mksubj.pl reads $(tsrc) and writes $(tsubj). A naive rule
|
|
# $(tsubj): $(tsrc)
|
|
# COMMAND
|
|
# runs COMMAND once for each target. That's because multiple targets
|
|
# in an explicit rule is just a shorthand for one rule per target,
|
|
# each with the same prerequisites and commands. Use a stamp file.
|
|
$(tsubj) info/toc: info/stamp-subj ;
|
|
info/stamp-subj: info/mksubj.pl $(tsrc)
|
|
$(call quiet-command,perl $(srcdir)/info/mksubj.pl $(subjects) $(filter %.t, $^),GEN '$(tsubj) info/toc')
|
|
>$@
|
|
|
|
info/TOP.t: info/mktop.pl info/subjects.mk
|
|
$(call quiet-command,perl $(srcdir)/info/mktop.pl $@ $(subjects),GEN $@)
|
|
|
|
info.nr/all: $(filter-out info.nr/all, $(info.nr))
|
|
>$@
|
|
(cd info.nr && LC_ALL=C ls -C $(info)) >>$@
|
|
|
|
info.html/all.html: info.nr/all info/ls2html.pl
|
|
expand $< | perl $(srcdir)/info/ls2html.pl >$@
|
|
|
|
$(info.nr): info/CRT.MAC info/INFO.MAC info/Blank.awk
|
|
|
|
$(info.html): info/emp2html.pl
|
|
|
|
info.ps: info/TROFF.MAC info/INFO.MAC info/TOP.t $(tsubj) $(tsrc)
|
|
groff $^ >$@
|
|
|
|
# Distributing
|
|
|
|
.PHONY: dist-source
|
|
dist-source: $(src_distgen)
|
|
$(tarball) $(TARNAME) $(version) -C $(srcdir) $(src_distgen) $(src)
|
|
|
|
ifeq ($(revctrl),git)
|
|
.PHONY: $(srcdir)/sources.mk
|
|
$(srcdir)/sources.mk:
|
|
$(call quiet-command,echo "src := $(src)" >$@,GEN $@)
|
|
endif
|
|
|
|
.PHONY: dist-client
|
|
dist-client: $(cli_distgen)
|
|
$(tarball) $(TARNAME)-client $(version) \
|
|
-C $(srcdir)/src/client \
|
|
$(notdir $(filter src/client/%, $(src)) $(cli_distgen)) \
|
|
-C $(srcdir)/include proto.h version.h \
|
|
-C $(srcdir)/src/lib/global version.c \
|
|
-C $(srcdir)/src/lib $(addprefix w32/, $(client/w32)) \
|
|
-C $(srcdir)/man empire.6 \
|
|
-C $(srcdir)/build-aux install-sh \
|
|
-C $(srcdir) COPYING INSTALL
|
|
|
|
.PHONY: dist-info
|
|
dist-info: info html
|
|
$(tarball) $(TARNAME)-info-text $(version) -C info.nr $(info)
|
|
$(tarball) $(TARNAME)-info-html $(version) -C info.html $(addsuffix .html, $(info))
|
|
|
|
# Dependencies
|
|
|
|
ifneq ($(deps),)
|
|
-include $(deps)
|
|
endif
|
|
|
|
|
|
# Automatic remake of configuration
|
|
# See (autoconf)Automatic Remaking.
|
|
# This requires sufficiently recent versions of autoconf and automake
|
|
|
|
$(srcdir)/configure: configure.ac aclocal.m4
|
|
cd $(srcdir) && autoconf
|
|
|
|
# autoheader might not change config.h.in, so touch a stamp file.
|
|
$(srcdir)/config.h.in: stamp-h.in ;
|
|
$(srcdir)/stamp-h.in: configure.ac aclocal.m4
|
|
cd $(srcdir) && autoheader
|
|
touch $@
|
|
|
|
$(srcdir)/aclocal.m4: $(filter m4/%.m4, $(src))
|
|
cd $(srcdir) && aclocal -I m4
|
|
|
|
# config.status might not change config.h; use the stamp file.
|
|
config.h: stamp-h ;
|
|
stamp-h: config.h.in config.status
|
|
./config.status config.h stamp-h
|
|
|
|
GNUmakefile: GNUmakefile.in config.status
|
|
./config.status $@
|
|
|
|
config.status: configure
|
|
./config.status --recheck
|
|
|
|
src/lib/global/path.c src/client/ipglob.c: %: %.in GNUmakefile Make.mk
|
|
$(call quiet-command,$(subst.in) <$< >$@,GEN $@)
|
|
|
|
|
|
# Make files for standalone client distribution
|
|
|
|
$(srcdir)/src/client/configure: src/client/configure.ac src/client/aclocal.m4
|
|
cd $(dir $@) && autoconf
|
|
|
|
$(srcdir)/src/client/config.h.in: src/client/configure.ac src/client/aclocal.m4
|
|
cd $(dir $@) && autoheader
|
|
touch $@
|
|
|
|
$(srcdir)/src/client/aclocal.m4: m4/ax_lib_socket_nsl.m4 m4/my_terminfo.m4 m4/my_windows_api.m4
|
|
cat $^ >$@
|