summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--.gitlab-ci.yml74
-rw-r--r--.gitmodules2
-rw-r--r--CMakeLists.txt188
-rw-r--r--COPYING2
-rw-r--r--Makefile.in88
-rw-r--r--README.md2
-rwxr-xr-xconfigure10
m---------deps/attoconf0
-rw-r--r--generate.mk (renamed from generate.make)0
-rw-r--r--src/conf/install.hpp.in (renamed from src/conf/install.hpp)7
-rw-r--r--src/conf/version.hpp.in (renamed from src/conf/version.hpp)21
-rw-r--r--src/main-gdb-head.py2
-rw-r--r--src/map/script-parse.py2
-rw-r--r--src/mmo/version.cpp2
-rw-r--r--src/shared/lib.cpp2
-rwxr-xr-xtools/bs-align2
-rwxr-xr-xtools/colorize4
-rwxr-xr-xtools/config.py10
-rwxr-xr-xtools/debug-debug-scripts9
-rw-r--r--tools/debug-debug.gdb6
-rwxr-xr-xtools/indenter7
-rwxr-xr-xtools/pp-indent2
-rwxr-xr-xtools/protocol.py125
-rw-r--r--version.mk (renamed from version.make)31
25 files changed, 456 insertions, 148 deletions
diff --git a/.gitignore b/.gitignore
index d28b05e..34afd74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,10 +9,12 @@
/src/proto2/
/src/debug-debug/
/src/*/*_conf.[ch]pp
+/src/conf/version.hpp
# tags file
/tags
# generated by configure
/Makefile
+/src/conf/install.hpp
/config.status
/lib
# generated by python
@@ -32,3 +34,7 @@
# generic build
/build/
+
+# CI build
+/build-atto/
+/build-cmake/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f7c750a..0368723 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,6 +8,7 @@ variables: &base_vars
# Depth of clone. If no tag is made after this many commits, then
# the git describe call and version header generation will fail.
GIT_DEPTH: 100 # Will break again eventually.
+ GIT_SUBMODULE_STRATEGY: normal
.prerequisites: &prerequisites
before_script:
@@ -15,21 +16,21 @@ variables: &base_vars
- apt-get update
- apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES
-
# Active server OS?
-re:ubuntu1804:build:
+re:ubuntu1804-attoconf:build:
<<: *prerequisites
stage: build
image: ubuntu:18.04
variables:
<<: *base_vars
- INSTALL_PACKAGES: python
+ INSTALL_PACKAGES: python3
script:
- echo "Building TMW Athena $CI_BUILD_NAME"
- - git submodule update --init
- git fetch -t
- printf "Building TMW Athena version %s\n" "$(git describe --tags HEAD)"
- - ./configure --user
+ - mkdir build-atto
+ - cd build-atto
+ - ../configure --user
- make
- whoami
- make install
@@ -37,23 +38,20 @@ re:ubuntu1804:build:
untracked: true
expire_in: 30 mins
-
-
-
# Next server OS?
-re:ubuntu2204:build:
+re:ubuntu2204-attoconf:build:
<<: *prerequisites
stage: build
image: ubuntu:22.04
variables:
<<: *base_vars
- INSTALL_PACKAGES: python2
+ INSTALL_PACKAGES: python3
script:
- - ln -s /usr/bin/python2 /usr/bin/python
- - git submodule update --init
- git fetch -t
- printf "Building TMW Athena version %s\n" "$(git describe --tags HEAD)"
- - ./configure --user
+ - mkdir build-atto
+ - cd build-atto
+ - ../configure --user
- make
- whoami
- make install
@@ -61,31 +59,69 @@ re:ubuntu2204:build:
untracked: true
expire_in: 30 mins
-
+# Next server OS, with cmake
+re:ubuntu2204:build:
+ <<: *prerequisites
+ stage: build
+ image: ubuntu:22.04
+ variables:
+ <<: *base_vars
+ INSTALL_PACKAGES: python3 cmake
+ script:
+ - git fetch -t
+ - printf "Building TMW Athena version %s\n" "$(git describe --tags HEAD)"
+ - mkdir build-cmake
+ - cd build-cmake
+ - cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local ..
+ - make
+ - whoami
+ - make install
+ artifacts: # required for test stage
+ untracked: true
+ expire_in: 30 mins
# Disabled. fails with:
# (1) GDB failing to resolve a type
# (2) /usr/bin/ld: Dwarf Error: Can't find .debug_ranges section.
-.re:ubuntu1804:test:
+.re:ubuntu1804-attoconf:test:
<<: *prerequisites
stage: test
image: ubuntu:18.04
+ needs: ["ubuntu1804-attoconf:build"]
+ variables:
+ <<: *base_vars
+ INSTALL_PACKAGES: python3 gdb
+ script:
+ - printf "Testing TMW Athena version %s\n" "$(git describe --tags HEAD)"
+ - cd build-atto
+ - make test
+
+
+# Enabled tests
+re:ubuntu2204-attoconf:test:
+ <<: *prerequisites
+ stage: test
+ image: ubuntu:22.04
+ needs: ["re:ubuntu2204-attoconf:build"]
variables:
<<: *base_vars
- INSTALL_PACKAGES: python gdb
+ INSTALL_PACKAGES: python3 gdb
script:
- printf "Testing TMW Athena version %s\n" "$(git describe --tags HEAD)"
+ - cd build-atto
- make test
-re:ubuntu2204:test:
+# Disabled. Tests are not supported yet by the CMake project.
+.re:ubuntu2204:test:
<<: *prerequisites
stage: test
image: ubuntu:22.04
+ needs: ["re:ubuntu2204:build"]
variables:
<<: *base_vars
- INSTALL_PACKAGES: python2 gdb
+ INSTALL_PACKAGES: python3 gdb
script:
- - ln -s /usr/bin/python2 /usr/bin/python
- printf "Testing TMW Athena version %s\n" "$(git describe --tags HEAD)"
+ - cd build-cmake
- make test
diff --git a/.gitmodules b/.gitmodules
index 8197e60..48c5d1f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "deps/attoconf"]
path = deps/attoconf
- url = https://github.com/o11c/attoconf.git
+ url = https://github.com/Freeyorp/attoconf
[submodule "deps/googletest"]
path = deps/googletest
url = https://github.com/google/googletest.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..16e251c
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,188 @@
+cmake_minimum_required(VERSION 3.10)
+
+# Function for conveniently capturing git output, used to set version related variables
+find_package(Git REQUIRED)
+function(git_capture_output var)
+ execute_process(COMMAND ${GIT_EXECUTABLE} ${ARGN}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE ${var}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ message(STATUS "${var} = ${${var}}")
+ set(${var} ${${var}} PARENT_SCOPE)
+endfunction()
+
+git_capture_output(VERSION_FULL describe --tags)
+git_capture_output(VERSION_HASH rev-parse HEAD)
+
+# Capture the major.minor.patch part of the version based on the last tag
+string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION ${VERSION_FULL})
+
+# Capture the tweak part of the version
+if(${VERSION_FULL} MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-([0-9]+)-g[0-9a-f]+$")
+ set(VERSION "${VERSION}.${CMAKE_MATCH_1}")
+else()
+ set(VERSION "${VERSION}.0")
+endif()
+
+project(tmwAthena VERSION ${VERSION} LANGUAGES CXX)
+
+# Prefer to use G++ as the compiler
+set(CMAKE_CXX_COMPILER g++)
+# Set C++ standard to C++11
+# Note we want -std=c++11, not -std=gnu++11, as we want to avoid GNU extensions
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# Some sources and includes are generated, such as the protocol headers.
+# We defer to generate.make for these rules.
+# Note that these are raw Makefile rules, not CMake rules, so a simple
+# add_custom_command() won't work.
+execute_process(COMMAND make -f ${CMAKE_SOURCE_DIR}/generate.mk
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+
+# The generate target must be re-run when the scripts change
+set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
+ "${PROJECT_SOURCE_DIR}/generate.mk"
+ "${PROJECT_SOURCE_DIR}/tools/config.py"
+ "${PROJECT_SOURCE_DIR}/tools/protocol.py"
+)
+
+# Search through the tree for sources
+# For each subfolder in src, add all .cpp, .hpp and .tcc files to a subfolder's SOURCES
+# variable.
+set(ALL_SOURCES "")
+foreach(dir admin ast char compat conf generic high ints io login map mmo net proto-base range sexpr shared strings tests wire)
+ file(GLOB_RECURSE ${dir}_SOURCES CONFIGURE_DEPENDS
+ src/${dir}/*.cpp
+ src/${dir}/*.hpp
+ src/${dir}/*.tcc)
+ # Exclude any _test.cpp files from the build
+ set(ALL_SOURCES ${ALL_SOURCES} ${${dir}_SOURCES})
+ list(FILTER ${dir}_SOURCES EXCLUDE REGEX ".*_test.cpp")
+ message("Adding sources in ${dir}: ${${dir}_SOURCES}")
+endforeach()
+
+# All targets include the include/ directory
+include_directories(include)
+
+# We want -fvisibility=hidden for regular objects, but not shared libraries.
+# CMake provides a helpful preset for this.
+# FIXME this is currently broken
+#set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+# General purpose build flags.
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fstack-protector -fno-strict-aliasing -flto")
+# Enable link time optimization, and track function and data sections. We let
+# the linker remove unused code.
+#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto -ffunction-sections -fdata-sections -Wl,--gc-sections")
+# Next, add warnings
+#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
+# Add debug information
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
+
+# Vendor Name: String (no newlines, no parentheses)
+# This is usually one word, and does not (usually) change over time.
+# (Examples: Gentoo, Debian, Fedora, Ubuntu)
+set(VENDOR_NAME Vanilla)
+# Vendor Point: Integer (max value 65535)
+# This is intended to be the "packaging revision number", assuming that's
+# an integer. At a minimum, please try to make it nonzero if you have
+# any non-upstream patches (unconditionally nonzero is also okay).
+# (If your revision 0 package has patches ... please be nicer to upstream)
+set(VENDOR_POINT 0)
+# URL where the source may be found (after searching for version number).
+# See AGPLv3 section 13
+set(VENDOR_SOURCE https://git.themanaworld.org/legacy/tmwa)
+
+# Convenience
+set(VERSION_STRING "TMWA ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} dev${PROJECT_VERSION_TWEAK} +${VENDOR_POINT} (${VENDOR_NAME})")
+set(VERSION_DOTS "${PROJECT_VERSION}.${VENDOR_POINT}")
+
+include(GNUInstallDirs)
+set(PACKAGEDATADIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}/tmwa")
+set(LOCALSTATEDIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}")
+set(SYSCONFDIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
+
+# Generate the install.hpp and version.hpp files.
+configure_file(src/conf/install.hpp.in src/conf/install.hpp @ONLY)
+configure_file(src/conf/version.hpp.in src/conf/version.hpp @ONLY)
+set(conf_SOURCES ${conf_SOURCES} src/conf/install.hpp src/conf/version.hpp)
+# And have the build search for files in the build directory.
+# Note that #includes with generated files should use a path relative to the
+# top level source or build directory.
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+# Add a shared library: libtmwa-shared.so.0
+# When we add_executable later, we need to link against this library.
+add_library(tmwa-shared SHARED ${shared_SOURCES}
+ src/io/dir.cpp
+ src/io/fd.cpp
+ src/io/read.cpp
+ src/io/write.cpp
+ ${strings_SOURCES}
+)
+# SO versioning
+set(ABI_VERSION 0)
+set_target_properties(tmwa-shared PROPERTIES
+ VERSION ${ABI_VERSION}.${VERSION_DOTS}
+ SOVERSION ${ABI_VERSION})
+
+# We have four binaries we want to build: tmwa-{login,char,map,admin}
+add_executable(tmwa-login ${login_SOURCES}
+ ${generic_SOURCES}
+ ${high_SOURCES}
+ ${io_SOURCES}
+ ${mmo_SOURCES}
+ ${net_SOURCES}
+ ${wire_SOURCES}
+)
+target_link_libraries(tmwa-login tmwa-shared)
+
+add_executable(tmwa-char ${char_SOURCES}
+ ${generic_SOURCES}
+ ${high_SOURCES}
+ ${io_SOURCES}
+ ${mmo_SOURCES}
+ ${net_SOURCES}
+ ${wire_SOURCES}
+)
+target_link_libraries(tmwa-char tmwa-shared)
+
+add_executable(tmwa-map ${map_SOURCES}
+ ${ast_SOURCES}
+ ${compat_SOURCES}
+ ${generic_SOURCES}
+ ${high_SOURCES}
+ ${io_SOURCES}
+ ${mmo_SOURCES}
+ ${net_SOURCES}
+ ${wire_SOURCES}
+ )
+target_link_libraries(tmwa-map tmwa-shared)
+
+add_executable(tmwa-admin ${admin_SOURCES}
+ ${generic_SOURCES}
+ ${high_SOURCES}
+ ${io_SOURCES}
+ ${mmo_SOURCES}
+ ${net_SOURCES}
+ ${wire_SOURCES}
+)
+target_link_libraries(tmwa-admin tmwa-shared)
+
+# TODO: Call make -f ${CMAKE_SOURCE_DIR}/generate.mk clean to clean up the
+# generated files. We want this to be run every time we call make clean.
+
+# Install targets
+install(TARGETS tmwa-login tmwa-char tmwa-map tmwa-admin tmwa-shared
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+# Install shared configuration and data
+install(FILES etc/tmwa/shared.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/tmwa)
+install(FILES share/tmwa/shared.data DESTINATION ${CMAKE_INSTALL_DATADIR}/tmwa)
+
+# Make sure there is a var directory
+install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LOCALSTATEDIR}/tmwa)
diff --git a/COPYING b/COPYING
index edf98ab..c1c13ff 100644
--- a/COPYING
+++ b/COPYING
@@ -5,7 +5,7 @@ This combination is explicitly allowed by section 13 of the licenses.
See gpl-3.0.txt or agpl-3.0.txt for specific terms.
In order to make life easy for users who run this software publicly,
-please set VENDOR_SOURCE in version.make if you make any modifications.
+please set VENDOR_SOURCE in version.mk if you make any modifications.
History:
diff --git a/Makefile.in b/Makefile.in
index 10f909c..075c107 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -152,7 +152,7 @@ $(info The Road goes ever on and on ...)
endif
endif
-include ${SRC_DIR}/version.make
+include ${SRC_DIR}/version.mk
ifeq (${ENABLE_SHARED},yes)
LIB_SUFFIX_FAKE := so
@@ -184,12 +184,13 @@ export PATH:=$(realpath ${SRC_DIR}/tools):${PATH}
SHELL=bash
# need to generate source files before path lists
-$(shell make -f ${SRC_DIR}/generate.make >&2)
+$(shell make -f ${SRC_DIR}/generate.mk >&2)
stamp/generated.stamp:
# if you get here, the shell above failed
false
# path lists
+GENERATED_FILES := src/conf/version.hpp
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')
@@ -283,9 +284,9 @@ 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
+override CXX += -std=gnu++11
else
-override CXX += -std=c++0x
+override CXX += -std=c++11
endif
CXXFLAGS += -fstack-protector
@@ -333,9 +334,60 @@ include ${DEPENDS}
endif
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}))))))))
+
+# Sanitize the dependencies.
+#
+# ${root} has a value like "mmo/version", and ${mmo/version} in turn has the
+# value of all of its dependencies (from the %.d files).
+#
+# This reassigns the *value of the value* of ${root} to be:
+# - sorted
+# - relative and simplified: it's stripped of any absolute path relative to
+# the current directory after being converted to an absolute path.
+# This also converts paths from being relative to the build directory to
+# being relative to the source directory, if they differ.
+# This simplifies any construct such as:
+# ../src/mmo/../strings/zstring.tcc
+# to:
+# src/strings/zstring.tcc
+# - only files which either exist (the purpose of the wildcard function),
+# are in the conf-raw directory (the first filter function), or
+# are listed in the GENERATED_FILES variable (the second filter function).
+# This means that if there are any build-time generated files added, this
+# needs to be modified to not filter them out.
+#
+# The end result for each root will look something like:
+# mmo/version := conf-raw/int-VENDOR_POINT.h conf-raw/int-VERSION_DEVEL.h [...]
+# src/strings/zstring.tcc src/wire/fwd.hpp
+
+# Firstly, make the paths relative and simplified.
+$(foreach root,${PATTERN_ROOTS},$(eval \
+ ${root} := $(sort $(patsubst ${thisdir}/%,%, \
+ $(abspath $(patsubst ${SRC_DIR}/%,%, $(value ${root}))) \
+ )) \
+))
+
+# Secondly, make sure that the files actually exist, or are files we expect to
+# generate ourselves. Sort the result for readability.
+# Note that we re-add and remove the ${SRC_DIR} prefix when first testing for
+# existence, as we need to test for existence relative to our build directory.
+# The second wildcard test doesn't add a ${SRC_DIR} prefix, but does strip it,
+# handling the case where the file is specified relative to the source
+# directory (mostly the case in test sources).
+$(foreach root,${PATTERN_ROOTS},$(eval \
+ ${root} := $(sort \
+ $(patsubst ${SRC_DIR}/%,%,$(wildcard $(addprefix ${SRC_DIR}/, \
+ $(value ${root}) \
+ ))) \
+ $(patsubst ${SRC_DIR}/%,%,$(wildcard ${SRC_DIR})) \
+ $(filter conf-raw/%.h,$(value ${root})) \
+ $(filter ${GENERATED_FILES},$(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 ))
@@ -386,6 +438,7 @@ vpath include/%.hpp ${SRC_DIR}
vpath src/%.tcc ${SRC_DIR}
vpath tools/% ${SRC_DIR}
vpath src/%.py ${SRC_DIR}
+vpath src/%.in ${SRC_DIR}
.DELETE_ON_ERROR:
.DEFAULT_GOAL := all
@@ -437,6 +490,10 @@ obj/%.d: src/%.cpp | stamp/generated.stamp
${CXX} ${CPPFLAGS} -DGENERATING_DEPENDENCIES ${CXXFLAGS} -MG -MM \
-MT '$(patsubst obj/%.d,%,$@) := ' \
-MF $@ $<
+# -MG takes the include parameter as-is without prepending the path whenever
+# it's not found, and presumed to be a not-yet generated file.
+# #include statements for generated files should always be relative to the
+# source (or build) directory.
endif
# the above SRC_DIR replacement is not really safe, but it works okayish.
obj/%.ii: src/%.cpp
@@ -508,8 +565,8 @@ obj/gtest%.pdc.o: ${GTEST_DIR}/src/gtest%.cc
DTEST_OBJS := $(filter obj/debug-debug/%.pdc.o,${PDC_OBJECTS})
DTEST_STAMPS := $(patsubst bin/tests/%.elf,stamp/run-%.stamp,${DTEST_BINARIES})
-${DTEST_OBJS}: override CXXFLAGS += -g -O0 -gdwarf-3
-${DTEST_STAMPS}: override TESTER=${GDB} -return-child-result -nx -batch -ex 'python file_to_load = "$<"' -x ${SRC_DIR}/tools/debug-debug.gdb --args false
+${DTEST_OBJS}: override CXXFLAGS += -ggdb -O0
+${DTEST_STAMPS}: override TESTER=LD_LIBRARY_PATH="./lib" ${GDB} -return-child-result -nx -batch -ex 'python file_to_load = "$<"' -x ${SRC_DIR}/tools/debug-debug.gdb --args false
${DTEST_STAMPS}: tools/debug-debug.gdb
test: test-direct
@@ -539,7 +596,7 @@ test: test-rank-fwd
test-rank-fwd: ${CHECK_RANK_FWDS}
stamp/%.rank: src/%
$(MKDIR_FIRST)
- includes=$$(grep '#include.*".*/.*"' $< | sed 's/^[^"]*"//;s/"[^"]*$$//;s:/[^/]*$$::' | sort -u | fgrep -vx -e '..' -e 'conf-raw' -e '../conf'); \
+ includes=$$(grep '#include.*".*/.*"' $< | sed 's/^[^"]*"//;s/"[^"]*$$//;s:/[^/]*$$::' | sort -u | fgrep -vx -e '..' -e 'conf-raw' -e '../conf' -e 'src/conf'); \
for inc in $$includes; do if ! test -f ${<D}/fwd.hpp; then continue; fi; echo fgrep -q $${inc}/fwd.hpp ${<D}/fwd.hpp; fgrep -q $${inc}/fwd.hpp ${<D}/fwd.hpp || { echo ${<D}/fwd.hpp:''23: error: No $${inc}/fwd.hpp; exit 1; }; done
touch $@
@@ -682,21 +739,22 @@ conf-raw/bool-%.h: FORCE
conf-raw/str-%.h: FORCE
$(MKDIR_FIRST)
@echo '#define $* "$(value $*)"_s' | maybe-replace $@
-FORCE: ;
+
+FORCE:: ;
.PHONY: FORCE
-override CPPFLAGS += -I . -I ${SRC_DIR}/include
+override CPPFLAGS += -I. -I${SRC_DIR} -I${SRC_DIR}/include
# distribution tarballs
# this only works from within a git checkout
-dist/%/version.make:
+dist/%/version.mk:
$(MKDIR_FIRST)
- git --git-dir=${SRC_DIR}/.git show HEAD:version.make > $@
+ git --git-dir=${SRC_DIR}/.git show HEAD:version.mk > $@
sed 's/^VERSION_FULL := .*/#&\nVERSION_FULL := ${VERSION_FULL}/' -i $@
sed 's/^VERSION_HASH := .*/#&\nVERSION_HASH := ${VERSION_HASH}/' -i $@
-dist/%-src.tar: dist/%/version.make
+dist/%-src.tar: dist/%/version.mk
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
+ ( 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.mk )
+ rm dist/$*/version.mk
rmdir dist/$*/
dist/%-attoconf-only.tar:
$(MKDIR_FIRST)
diff --git a/README.md b/README.md
index 6ec6a58..8947def 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ The rest of this file contains information relevant to distributors and contribu
## 1. Distributors
### Important notes
-- Please read [version.make](version.make) for important version information.
+- Please read [version.mk](version.mk) for important version information.
- TMWA requires git to build by default. Use 'make dist' to get a tarball.
### Platform dependencies
diff --git a/configure b/configure
index aa1d0fd..468f029 100755
--- a/configure
+++ b/configure
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright 2013 Ben Longbons <b.r.longbons@gmail.com>
#
@@ -17,8 +17,6 @@
# You should have received a copy of the GNU General Public License
# along with attoconf. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import print_function, division, absolute_import
-
import os
import sys
@@ -90,7 +88,7 @@ class Configuration(Cxx, Install, ConfigHash, Templates):
# 2) Modern distros ship gtest-1.13+. It requires C++14+, while
# TMWA is currently a C++0x codebase.
self.add_option('GTEST_DIR',
- init=os.path.join(os.getcwd(), 'deps/googletest/googletest'),
+ init=os.path.join(os.path.abspath(self.srcdir), 'deps/googletest/googletest'),
# http://code.google.com/p/googletest/wiki/FAQ#Why_is_it_not_recommended_to_install_a_pre-compiled_copy_of_Goog
type=filepath, check=lambda build, GTEST_DIR: None,
help='Location of Google Test sources, must contain src/gtest-all.cc (linking to a precompiled library is NOT supported)', hidden=False)
@@ -112,7 +110,9 @@ def main():
srcdir = os.path.dirname(sys.argv[0])
proj = Configuration(
srcdir=srcdir,
- template_files=['Makefile'],
+ # Note that src/conf/version.hpp is made later, by Makefile.
+ # See version.mk (included by Makefile).
+ template_files=['Makefile', 'src/conf/install.hpp'],
)
proj.set_package('tmwa', 'The Mana World (Athena server)');
proj.jiggle()
diff --git a/deps/attoconf b/deps/attoconf
-Subproject 7b939e7e4ce36e8b62b10025e567f871731cbf4
+Subproject 58e75e5f1271363a48c2a3417a2851d3b145b3f
diff --git a/generate.make b/generate.mk
index c32ca8d..c32ca8d 100644
--- a/generate.make
+++ b/generate.mk
diff --git a/src/conf/install.hpp b/src/conf/install.hpp.in
index 42fd125..e63164a 100644
--- a/src/conf/install.hpp
+++ b/src/conf/install.hpp.in
@@ -20,10 +20,9 @@
// just mention "fwd.hpp" to make formatter happy
-#include "conf-raw/str-PACKAGESYSCONFDIR.h"
-#include "conf-raw/str-PACKAGELOCALSTATEDIR.h"
-#include "conf-raw/str-PACKAGEDATADIR.h"
-
+#define PACKAGESYSCONFDIR "@SYSCONFDIR@/tmwa"_s
+#define PACKAGELOCALSTATEDIR "@LOCALSTATEDIR@/tmwa"_s
+#define PACKAGEDATADIR "@PACKAGEDATADIR@"_s
namespace tmwa
{
diff --git a/src/conf/version.hpp b/src/conf/version.hpp.in
index df8a8b6..126fae2 100644
--- a/src/conf/version.hpp
+++ b/src/conf/version.hpp.in
@@ -20,20 +20,19 @@
// just mention "fwd.hpp" to make formatter happy
-#include "conf-raw/str-VERSION_FULL.h"
-#include "conf-raw/str-VERSION_HASH.h"
+#define VERSION_FULL "@VERSION_FULL@"_s
+#define VERSION_HASH "@VERSION_HASH@"_s
-#include "conf-raw/int-VERSION_MAJOR.h"
-#include "conf-raw/int-VERSION_MINOR.h"
-#include "conf-raw/int-VERSION_PATCH.h"
-#include "conf-raw/int-VERSION_DEVEL.h"
+#define VERSION_MAJOR @PROJECT_VERSION_MAJOR@
+#define VERSION_MINOR @PROJECT_VERSION_MINOR@
+#define VERSION_PATCH @PROJECT_VERSION_PATCH@
+#define VERSION_DEVEL @PROJECT_VERSION_TWEAK@
-#include "conf-raw/str-VENDOR_NAME.h"
-#include "conf-raw/int-VENDOR_POINT.h"
-#include "conf-raw/str-VENDOR_SOURCE.h"
-
-#include "conf-raw/str-VERSION_STRING.h"
+#define VENDOR_NAME "@VENDOR_NAME@"_s
+#define VENDOR_POINT @VENDOR_POINT@
+#define VENDOR_SOURCE "@VENDOR_SOURCE@"_s
+#define VERSION_STRING "@VERSION_STRING@"_s
namespace tmwa
{
diff --git a/src/main-gdb-head.py b/src/main-gdb-head.py
index a465c97..09e22fe 100644
--- a/src/main-gdb-head.py
+++ b/src/main-gdb-head.py
@@ -5,7 +5,7 @@
# gdb sticks everything in one scope.
# This lets us enumerate what *we* added.
-initial_globals = {id(v):v for v in globals().values()}
+initial_globals = {id(v):v for v in list(globals().values())}
import re
diff --git a/src/map/script-parse.py b/src/map/script-parse.py
index 199e348..3346b92 100644
--- a/src/map/script-parse.py
+++ b/src/map/script-parse.py
@@ -106,7 +106,7 @@ class ScriptBuffer(object):
code_begin = code['_M_impl']['_M_start']
code_end = code['_M_impl']['_M_finish']
code_size = int(code_end - code_begin)
- r = iter(range(code_size))
+ r = iter(list(range(code_size)))
for i in r:
buf = []
for label in labels_dict.get(i, []):
diff --git a/src/mmo/version.cpp b/src/mmo/version.cpp
index f91b748..c75c25c 100644
--- a/src/mmo/version.cpp
+++ b/src/mmo/version.cpp
@@ -20,7 +20,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "../conf/version.hpp"
+#include "src/conf/version.hpp"
#include "../strings/xstring.hpp"
diff --git a/src/shared/lib.cpp b/src/shared/lib.cpp
index c0a4371..37b2e93 100644
--- a/src/shared/lib.cpp
+++ b/src/shared/lib.cpp
@@ -18,7 +18,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "../conf/install.hpp"
+#include "src/conf/install.hpp"
#include "../strings/literal.hpp"
#include "../strings/astring.hpp"
diff --git a/tools/bs-align b/tools/bs-align
index 6582298..0caf649 100755
--- a/tools/bs-align
+++ b/tools/bs-align
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- encoding: utf-8
## bs-align.py - Filter to align trailing line continuations
##
diff --git a/tools/colorize b/tools/colorize
index ce6f410..205a1bc 100755
--- a/tools/colorize
+++ b/tools/colorize
@@ -1,6 +1,4 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
+#!/usr/bin/env python3
import os
import sys
diff --git a/tools/config.py b/tools/config.py
index f87fe77..22ece0b 100755
--- a/tools/config.py
+++ b/tools/config.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# coding: utf-8
# config.py - generator for config file parsers
@@ -20,8 +20,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import print_function
-
import glob
import os
@@ -259,7 +257,7 @@ class Group(object):
short_cpp_name = '%s.cpp' % var_name
cpp_name = os.path.join(path, short_cpp_name)
- values = sorted(self.options.values(), key=lambda o: o.name)
+ values = sorted(list(self.options.values()), key=lambda o: o.name)
desc = 'Config for %s::%s' % (namespace_name, self.name)
with OpenWrite(hpp_name) as hpp, \
@@ -384,7 +382,7 @@ class Realm(object):
return rv
def dump(self):
- for g in self.groups.values():
+ for g in list(self.groups.values()):
g.dump_in(self.path, self.path.split('/')[-1])
class Everything(object):
@@ -401,7 +399,7 @@ class Everything(object):
def dump(self):
for g in glob.glob('src/*/*_conf.[ch]pp'):
os.rename(g, g + '.old')
- for v in self.realms.values():
+ for v in list(self.realms.values()):
v.dump()
for g in glob.glob('src/*/*_conf.[ch]pp.old'):
print('Obsolete: %s' % g)
diff --git a/tools/debug-debug-scripts b/tools/debug-debug-scripts
index 2112a6e..5ba7ecb 100755
--- a/tools/debug-debug-scripts
+++ b/tools/debug-debug-scripts
@@ -1,6 +1,5 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# encoding: utf-8
-from __future__ import print_function
copyright = '''
// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
@@ -35,6 +34,12 @@ error = False
def eprint(s):
print('Error:', s, file=sys.stderr)
+# Implement an equivalent to Python 2's execfile for Python 3
+def execfile(filename, globals=None, locals=None):
+ with open(filename, 'r') as f:
+ code = compile(f.read(), filename, 'exec')
+ exec(code, globals, locals)
+
def get_classes_from_file(a):
global error
d = {}
diff --git a/tools/debug-debug.gdb b/tools/debug-debug.gdb
index b50a49b..5bf3a57 100644
--- a/tools/debug-debug.gdb
+++ b/tools/debug-debug.gdb
@@ -9,7 +9,7 @@ gdb.execute('file %s' % file_to_load)
end
set logging file /dev/null
set logging redirect on
-set logging off
+set logging enabled off
python
import re
@@ -41,7 +41,7 @@ set print elements 9999
set print frame-arguments none
set python print-stack full
-set logging on
+set logging enabled on
# Workaround "Function... not defined in.." (breakpoints not found) (GDB bug)
# https://sourceware.org/bugzilla/show_bug.cgi?id=15962
# In some gdb versions rbreak works, in some break does.
@@ -55,7 +55,7 @@ if bpoint.pending:
gdb.execute("rbreak do_breakpoint")
end
-set logging off
+set logging enabled off
commands
silent
diff --git a/tools/indenter b/tools/indenter
index 0d93543..ee000da 100755
--- a/tools/indenter
+++ b/tools/indenter
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- encoding: utf-8
## indenter.py - Top-level indenter for all files
##
@@ -20,10 +20,9 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import print_function
from collections import namedtuple
-import cStringIO
+import io
import string
import subprocess
import sys
@@ -114,7 +113,7 @@ class Reader(object):
self._column += 1
def string_reader(s, name='<string>', line=1, column=1):
- return Reader(name, cStringIO.StringIO(s), line, column)
+ return Reader(name, io.StringIO(s), line, column)
def take_while(b, r, s):
assert isinstance(b, bytearray)
diff --git a/tools/pp-indent b/tools/pp-indent
index 9be9a03..622614a 100755
--- a/tools/pp-indent
+++ b/tools/pp-indent
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- encoding: utf-8
## pp-indent - Filter to apply indentation to preprocessor statements
##
diff --git a/tools/protocol.py b/tools/protocol.py
index cf89a16..c4c8657 100755
--- a/tools/protocol.py
+++ b/tools/protocol.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# coding: utf-8
# protocol.py - generator for entire TMWA network protocol
@@ -20,8 +20,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import print_function
-
import glob
import itertools
import os
@@ -29,11 +27,6 @@ from pipes import quote
from posixpath import relpath
from weakref import ref as wr
-try:
- unicode
-except NameError:
- unicode = str
-
## For various reasons this is all one file, so let's navigate with a
##
## Table of Contents
@@ -91,7 +84,7 @@ class OpenWrite(object):
self.filename = filename
def __enter__(self):
- self.handle = open(self.filename + '.tmp', 'w')
+ self.handle = open(self.filename + '.tmp', 'w', encoding='utf-8')
return self.handle
def __exit__(self, ty, v, tb):
@@ -116,30 +109,30 @@ class OpenWrite(object):
# TOC_
def gvq(s):
- return u'"%s"' % s.replace(u'"', u'\\"')
+ return '"%s"' % s.replace('"', '\\"')
def gva(d):
if d:
- return u' [%s]' % u', '.join(u'%s=%s' % (ak, gvq(av)) for (ak, av) in sorted(d.items()))
- return u''
+ return ' [%s]' % ', '.join('%s=%s' % (ak, gvq(av)) for (ak, av) in sorted(d.items()))
+ return ''
class Attributes(object):
- __slots__ = (u'_attributes')
+ __slots__ = ('_attributes')
def __init__(self):
self._attributes = {}
def __getitem__(self, k):
- assert isinstance(k, unicode)
+ assert isinstance(k, str)
return self._attributes[k]
def __setitem__(self, k, v):
- assert isinstance(k, unicode)
- assert isinstance(v, unicode)
+ assert isinstance(k, str)
+ assert isinstance(v, str)
self._attributes[k] = v
def __delitem__(self, k):
- assert isinstance(k, unicode)
+ assert isinstance(k, str)
del self._attributes[k]
def merge(self, *others):
@@ -150,7 +143,7 @@ class Attributes(object):
self._attributes.update(other._attributes)
class Graph(Attributes):
- __slots__ = (u'default_vertex', u'default_edge', u'_vertices', u'_edges', u'_vertex_lookup')
+ __slots__ = ('default_vertex', 'default_edge', '_vertices', '_edges', '_vertex_lookup')
def __init__(self):
Attributes.__init__(self)
@@ -161,7 +154,7 @@ class Graph(Attributes):
self._vertex_lookup = {}
def vertex(self, name, insert=True):
- assert isinstance(name, unicode)
+ assert isinstance(name, str)
vert = self._vertex_lookup.get(name)
if insert and vert is None:
vert = Vertex(name)
@@ -238,21 +231,21 @@ class Graph(Attributes):
def p(*args):
for x in args:
- out.write(unicode(x))
- out.write(u'\n')
- p(u'digraph')
- p(u'{')
+ out.write(str(x))
+ out.write('\n')
+ p('digraph')
+ p('{')
for ak, av in sorted(self._attributes.items()):
- p(u' ', ak, u'=', gvq(av), u';')
+ p(' ', ak, '=', gvq(av), ';')
for ak, av in sorted(self.default_vertex._attributes.items()):
- p(u' node [', ak, u'=', gvq(av), u'];')
+ p(' node [', ak, '=', gvq(av), '];')
for ak, av in sorted(self.default_edge._attributes.items()):
- p(u' edge [', ak, u'=', gvq(av), u'];')
+ p(' edge [', ak, '=', gvq(av), '];')
for n in sorted(self._vertices):
- p(u' ', n)
+ p(' ', n)
for _, e in sorted(self._edges.items()):
- p(u' ', e)
- p(u'}')
+ p(' ', e)
+ p('}')
def dot_str(self):
from io import StringIO
@@ -261,18 +254,18 @@ class Graph(Attributes):
return out.getvalue()
def dot_file(self, name):
- with open(name, u'w') as f:
+ with open(name, 'w') as f:
self.dot(f, False)
def preview(self, block):
from subprocess import Popen, PIPE
- proc = Popen([u'dot', u'-Txlib', u'/dev/stdin'], stdin=PIPE, universal_newlines=True)
+ proc = Popen(['dot', '-Txlib', '/dev/stdin'], stdin=PIPE, universal_newlines=True)
self.dot(proc.stdin, True)
if block:
proc.wait()
class Vertex(Attributes):
- __slots__ = (u'_key', u'_post', u'_pre', u'__weakref__')
+ __slots__ = ('_key', '_post', '_pre', '__weakref__')
def __init__(self, key):
Attributes.__init__(self)
@@ -281,13 +274,13 @@ class Vertex(Attributes):
self._pre = set()
def __str__(self):
- return u'%s%s;' % (gvq(self._key), gva(self._attributes))
+ return '%s%s;' % (gvq(self._key), gva(self._attributes))
def __lt__(self, other):
return self._key < other._key
class Edge(Attributes):
- __slots__ = (u'_from', u'_to')
+ __slots__ = ('_from', '_to')
def __init__(self, f, t):
Attributes.__init__(self)
@@ -295,7 +288,7 @@ class Edge(Attributes):
self._to = t
def __str__(self):
- return u'%s -> %s%s;' % (gvq(self._from._key), gvq(self._to._key), gva(self._attributes))
+ return '%s -> %s%s;' % (gvq(self._from._key), gvq(self._to._key), gva(self._attributes))
# TOC_TYPES
@@ -7091,7 +7084,7 @@ def partition(d):
changed = True
while changed:
changed = False
- for k, vlist in d.items():
+ for k, vlist in list(d.items()):
if vlist:
m = min(leaders[v] for v in vlist)
if m < leaders[k]:
@@ -7107,9 +7100,9 @@ def partition(d):
leaders[v] = m
followers = {}
- for k, v in leaders.items():
+ for k, v in list(leaders.items()):
followers.setdefault(v, []).append(k)
- return [set(v) for v in followers.values()]
+ return [set(v) for v in list(followers.values())]
def ids_only(vpost):
rv = [e for e in vpost if not isinstance(e, SpecialEventOrigin)]
@@ -7124,7 +7117,7 @@ def make_dots(ctx):
#p = partition({k: ids_only(v.post) for (k, v) in d.items()})
if not os.path.exists('doc-gen'):
- # generate.make will succeed if missing the wiki repo
+ # generate.mk will succeed if missing the wiki repo
# but 'make doc' will fail
return
for g in glob.glob('doc-gen/*.gv'):
@@ -7132,7 +7125,7 @@ def make_dots(ctx):
for g in glob.glob('doc-gen/Packet-*.md'):
os.rename(g, g + '.old')
- for (id, p) in d.items():
+ for (id, p) in list(d.items()):
md = 'doc-gen/Packet-0x%04x.md' % id
dot = 'doc-gen/packets-around-0x%04x.gv' % id
with OpenWrite(md) as f:
@@ -7179,16 +7172,16 @@ def make_dots(ctx):
covered_nodes = sorted(p.pre_set(d, 2) | p.post_set(d, 2))
covered_edges = [(a, b) for a in covered_nodes for b in covered_nodes if b in d[a].post]
g = Graph()
- g.default_vertex[u'shape'] = u'box'
- # g[u'layout'] = u'twopi'
- # g[u'root'] = u'0x%04x' % id
+ g.default_vertex['shape'] = 'box'
+ # g['layout'] = 'twopi'
+ # g['root'] = '0x%04x' % id
for n in covered_nodes:
- v = g.vertex(u'0x%04x' % n)
- v[u'label'] = u'Packet \\N: %s' % d[n].name
+ v = g.vertex('0x%04x' % n)
+ v['label'] = 'Packet \\N: %s' % d[n].name
if n == id:
- v[u'style'] = u'filled'
+ v['style'] = 'filled'
for (a, b) in covered_edges:
- g.edge(u'0x%04x' % a, u'0x%04x' % b)
+ g.edge('0x%04x' % a, '0x%04x' % b)
for n in covered_nodes:
# the center node will be covered specially below
if n == id:
@@ -7206,10 +7199,10 @@ def make_dots(ctx):
# don't show mere siblings unless also ancestor/descendent
count += 1
if count:
- v = g.vertex(u'0x%04x...pre' % n)
- v[u'label'] = u'%d more' % count
- v[u'style'] = u'dashed'
- g.edge(v, u'0x%04x' % n)
+ v = g.vertex('0x%04x...pre' % n)
+ v['label'] = '%d more' % count
+ v['style'] = 'dashed'
+ g.edge(v, '0x%04x' % n)
# strong forward links
count = 0
for p in d[n].post:
@@ -7218,36 +7211,36 @@ def make_dots(ctx):
elif p not in covered_nodes:
count += 1
if count:
- v = g.vertex(u'0x%04x...post' % n)
- v[u'label'] = u'%d more' % count
- v[u'style'] = u'dashed'
- g.edge(u'0x%04x' % n, v)
+ v = g.vertex('0x%04x...post' % n)
+ v['label'] = '%d more' % count
+ v['style'] = 'dashed'
+ g.edge('0x%04x' % n, v)
# for the immediate node, also cover specials and weaks
for p in d[id].pre:
# (there are no weak backward specials)
# strong backward specials
if isinstance(p, SpecialEventOrigin):
- g.edge(unicode(p.name), u'0x%04x' % id)
+ g.edge(str(p.name), '0x%04x' % id)
# weak backward nodes
elif id in d[p].xpost:
- e = g.edge(u'0x%04x' % p, u'0x%04x' % id)
- e[u'style']=u'dashed'
- e[u'weight'] = u'0'
+ e = g.edge('0x%04x' % p, '0x%04x' % id)
+ e['style']='dashed'
+ e['weight'] = '0'
for p in d[id].post:
# strong forward specials
if isinstance(p, SpecialEventOrigin):
- g.edge(u'0x%04x' % id, unicode(p.name))
+ g.edge('0x%04x' % id, str(p.name))
for p in d[id].xpost:
# weak forward specials
if isinstance(p, SpecialEventOrigin):
- e = g.edge(u'0x%04x' % id, unicode(p.name))
- e[u'style'] = u'dashed'
- e[u'weight'] = u'0'
+ e = g.edge('0x%04x' % id, str(p.name))
+ e['style'] = 'dashed'
+ e['weight'] = '0'
# weak forward nodes
elif p not in covered_nodes:
- e = g.edge(u'0x%04x' % id, u'0x%04x' % p)
- e[u'style'] = u'dashed'
- e[u'weight'] = u'0'
+ e = g.edge('0x%04x' % id, '0x%04x' % p)
+ e['style'] = 'dashed'
+ e['weight'] = '0'
g.dot(f, False)
diff --git a/version.make b/version.mk
index 73ecc83..23bd071 100644
--- a/version.make
+++ b/version.mk
@@ -39,7 +39,7 @@ VENDOR_NAME := Vanilla
VENDOR_POINT := 0
# URL where the source may be found (after searching for version number).
# See AGPLv3 section 13
-VENDOR_SOURCE := https://github.com/themanaworld/tmwa
+VENDOR_SOURCE := https://git.themanaworld.org/legacy/tmwa
# Convenience
VERSION_STRING := TMWA ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} dev${VERSION_DEVEL} +${VENDOR_POINT} (${VENDOR_NAME})
@@ -50,9 +50,38 @@ SO_SHORT := so.${ABI_VERSION}
SO_LONG := ${SO_SHORT}.${VERSION_DOTS}
# and thanks for all the fish
+# This is a phony target, so that it always runs.
+# Targets which depend on this will always have their recipes run.
+FORCE:: ;
+.PHONY: FORCE
+
+# Fully generate version.hpp here, where we have all the relevant information.
+# version.mk is included by the top level Makefile, so simply explaning how to
+# make it here will let it be built later, when needed.
+# Note that some variable substitutions are slightly different here to use the
+# name used by standard CMake macros, such as PROJECT_VERSION_TWEAK instead of
+# VERSION_DEVEL.
+src/conf/version.hpp: src/conf/version.hpp.in FORCE
+ sed -e 's/@VERSION_FULL@/${VERSION_FULL}/g' \
+ -e 's/@VERSION_HASH@/${VERSION_HASH}/g' \
+ -e 's/@VERSION_STRING@/${VERSION_STRING}/g' \
+ -e 's/@PROJECT_VERSION_MAJOR@/${VERSION_MAJOR}/g' \
+ -e 's/@PROJECT_VERSION_MINOR@/${VERSION_MINOR}/g' \
+ -e 's/@PROJECT_VERSION_PATCH@/${VERSION_PATCH}/g' \
+ -e 's/@PROJECT_VERSION_TWEAK@/${VERSION_DEVEL}/g' \
+ -e 's/@VENDOR_NAME@/${VENDOR_NAME}/g' \
+ -e 's/@VENDOR_POINT@/${VENDOR_POINT}/g' \
+ -e 's|@VENDOR_SOURCE@|${VENDOR_SOURCE}|g' \
+ -e 's/@ABI_VERSION@/${ABI_VERSION}/g' \
+ -e 's/@SO_SHORT@/${SO_SHORT}/g' \
+ -e 's/@SO_LONG@/${SO_LONG}/g' \
+ $< > $@
+
+
version:
@echo version '${VERSION_STRING}'
@echo based on commit ${VERSION_FULL} aka ${VERSION_HASH}
@echo source ${VENDOR_SOURCE}
@echo abi version ${ABI_VERSION}
@echo 'lib so -> ${SO_SHORT} -> ${SO_LONG}'
+.PHONY: version