TrinityCore是经典MMO游戏《魔兽世界》的开源版服务端,本文记录了TrinityCore项目中一个已经不再维护的历史版本的编译脚本。
目前在往上能够找到的大部分基于TrinityCore制作的服务端都是Windows版本的,如果需要在Linux系统上运行一个服务端,那就需要自己编译了。不过好在现在已经有了一个可以允许我们任意构建编译环境的办法:容器化。
本文中要完成编译的TrinityCore 7.3.5标签是对应《魔兽世界:军团再临》版本的服务端,这个版本目前已经很老了,所以在编译的时候肯定会遇到一些困难。为了尽可能减小最终镜像的体积,镜像编译脚将直接采用二段化编译。
用到的编译工具
既然是准备使用容器化的方法来完成全部编译工作,所以首先要先准备一个容器化环境。
这里没有使用网上广泛采用的Docker来作为容器化环境,这里采用containerd项目中的nerdctl来作为容器化环境的控制器,并直接使用其中携带的containerd服务作为容器环境,buildkit作为镜像编译环境。
问题分析
首先对项目中的CMakeLists.txt
文件们进行分析,基本上可以知道要完成这个版本项目的编译,需要CMake 3.2以上的版本,和Boost 1.58版本的库。
至于用来完成编译操作的基本镜像,可以直接使用Debian或者Ubuntu。
检查了一下目前常用版本Debian和Ubuntu中apt源里CMake和libboost-all-dev
的版本,发现它们都已经太高了。经过尝试编译确认,使用这些高版本的库,必然导致编译失败。所以需要构建一个低版本的编译环境。所以这样就会面临一个困难,Boost库的1.58版本现在在apt里已经找不到了,所以就需要手工来完成安装。
所以现在第一个目标就是构建一个基础的编译环境镜像。
基础编译环境镜像的构建
这里不再对Dockerfile的调试过程做更加详细的记录了。这里只记录一点:Boost 1.58版本对于gcc的版本是有一定要求的,所以对于编译器的设置这里尽量的不要再修改。
Dockerfile文件里列出安装的其他依赖都是可能在TrinityCore项目的编译中使用的到的,为了提升TrinityCore镜像的构建速度,所以这一部分依赖也就移到了编译环境镜像中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
FROM ubuntu:16.04
ENV DEBIAN_FRONTEND noninteractive
ENV TERM dumb
ENV PAGER cat
ARG BOOST_VERSION=1.58.0
ARG CMAKE_VERSION=3.2.3
RUN echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" \
>> /etc/apt/sources.list
RUN echo "deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main" \
>> /etc/apt/sources.list
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 60C317803A41BA51845E371A1E9377A2BA9EF27F
RUN apt-get update && apt-get install --no-install-recommends -y \
autoconf \
binutils \
ca-certificates \
curl \
file \
gettext-base \
git \
gzip \
g++-6 \
gcc-6 \
make \
mysql-client \
pkg-config \
python \
python-dev \
software-properties-common \
tzdata \
unzip \
wget \
libbz2-dev \
libedit-dev \
libncurses5-dev \
libssl-dev \
build-essential
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6 && \
update-alternatives --config gcc
# Install CMake
COPY cmake-${CMAKE_VERSION}.tar.gz /tmp
RUN cd /tmp && \
# wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz && \
tar xzf cmake-${CMAKE_VERSION}.tar.gz && \
cd cmake-${CMAKE_VERSION} && \
./bootstrap && \
make -j $(nproc) && \
make install && \
rm -rf /tmp/*
# Install Boost
# https://www.boost.org/doc/libs/1_80_0/more/getting_started/unix-variants.html
# https://nchc.dl.sourceforge.net/project/boost/boost/1.58.0/boost_1_58_0.tar.bz2
COPY boost_1_58_0.tar.bz2 /tmp
RUN cd /tmp && \
BOOST_VERSION_MOD=$(echo $BOOST_VERSION | tr . _) && \
# wget https://nchc.dl.sourceforge.net/project/boost/boost/${BOOST_VERSION}/boost_${BOOST_VERSION_MOD}.tar.bz2 && \
tar --bzip2 -xf boost_${BOOST_VERSION_MOD}.tar.bz2 && \
cd boost_1_58_0 && \
./bootstrap.sh --prefix=/usr --with-libraries=all --with-toolset=gcc && \
./b2 install && \
rm -rf /tmp/*
# Install NCurses 6.1
# 这个是为了弥补安装的MySQL client运行需要。
COPY ncurses-6.1.tar.gz /tmp
RUN cd /tmp && \
tar xzf ncurses-6.1.tar.gz && \
cd ncurses-6.1 && \
./configure --prefix=/usr/lib/ncurses --with-shared && \
make && \
make install && \
rm -rf /tmp/*
|
编译环境镜像在完成构建以后,打标签为registry.cn-beijing.aliyuncs.com/tc_core/tc_builder:7.3.5
供TrinityCore编译使用。
项目镜像的构建
对于项目的构建主要核心问题在于编译器的选择,经过反复测试,编译镜像中提供的g++无法完成TrinityCore的编译,所以在项目编译镜像中,还需要切换为clang。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
FROM registry.cn-beijing.aliyuncs.com/tc_core/tc_builder:7.3.5 AS builder
ENV TERM dumb
ENV PAGER cat
RUN mkdir -pv /build/ /artifacts/ /src/
# RUN apt-get update && apt-get upgrade
RUN apt-get -qq -o Dpkg::Use-Pty=0 update \
&& apt-get -qq -o Dpkg::Use-Pty=0 install --no-install-recommends -y \
clang \
ccache \
libmysqlclient-dev \
libreadline-dev \
zlib1g-dev \
&& add-apt-repository ppa:git-core/ppa && apt-get install -y git \
&& curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash && apt-get install -y git-lfs \
&& git version && git lfs version \
&& rm -rf /var/lib/apt/lists/*
RUN update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100 && \
update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang 100
COPY cmake /src/cmake
COPY contrib /src/contrib
COPY dep /src/dep
COPY sql /src/sql
COPY src /src/src
COPY sql /src/sql
COPY .git /src/.git
COPY CMakeLists.txt PreLoad.cmake revision_data.h.in.cmake COPYING /src/
RUN mkdir /artifacts/src/
WORKDIR /build
ARG INSTALL_PREFIX=/opt/trinitycore
ARG CONF_DIR=/etc
RUN cmake ../src -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS=dynamic -DSERVERS=1 -DNOJEM=1 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_C_FLAGS_DEBUG="-DNDEBUG" -DCMAKE_CXX_FLAGS_DEBUG="-DNDEBUG" -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" -DBUILD_TESTING=0 -DCONF_DIR="${CONF_DIR}"
RUN make -j $(nproc) \
&& make install
WORKDIR /artifacts
# Save upstream source Git SHA information that we built form.
ARG TDB_FULL_URL
RUN git -C /src rev-parse HEAD > .git-rev \
&& git -C /src rev-parse --short HEAD > .git-rev-short \
&& echo "$TDB_FULL_URL" > .tdb-full-url
# Copy binaries and example .dist.conf configuration files.
RUN tar -cf - \
"${INSTALL_PREFIX}" \
/bin/bash \
/etc/ca-certificates* \
/etc/*server.conf.dist \
/etc/ssl/certs \
/src/AUTHORS \
/src/COPYING \
/usr/bin/7zr \
/usr/bin/curl \
/usr/bin/git \
/usr/bin/jq \
/usr/bin/mariadb \
/usr/bin/mysql \
/usr/bin/stdbuf \
/usr/bin/xml2 \
/usr/lib/git-core/git-remote-http* \
/usr/lib/ncurses \
/usr/lib/p7zip/7zr \
/usr/lib//x86_64-linux-gnu \
/usr/libexec/coreutils/libstdbuf.so \
/usr/share/ca-certificates \
| tar -C /artifacts/ -xvf -
# Copy linked libraries and strip symbols from binaries.
RUN ldd opt/trinitycore/bin/* usr/bin/* usr/lib/git-core/* | grep ' => ' | tr -s '[:blank:]' '\n' | grep '^/' | sort -u | \
xargs -I % sh -c 'mkdir -pv $(dirname .%); cp -v % .%'
RUN strip \
"./${INSTALL_PREFIX}/bin/"*server \
"./${INSTALL_PREFIX}/bin/"*extractor \
"./${INSTALL_PREFIX}/bin/"*generator \
"./${INSTALL_PREFIX}/bin/"*assembler
# Copy example .conf.dist configuration files into expected .conf locations.
RUN cp -v etc/bnetserver.conf.dist etc/bnetserver.conf \
&& cp -v etc/worldserver.conf.dist etc/worldserver.conf \
&& find etc/ -name '*server.conf' -exec sed -i"" -r \
-e 's,^(.*DatabaseInfo[[:space:]]*=[[:space:]]*")[[:alnum:]\.-]*(;.*"),\1mysql\2,' \
-e 's,^(LogsDir[[:space:]]*=[[:space:]]).*,\1"/logs",' \
-e 's,^(SourceDirectory[[:space:]]*=[[:space:]]).*,\1"/src",' \
-e 's,^(MySQLExecutable[[:space:]]*=[[:space:]]).*,\1"/usr/bin/mysql",' \
'{}' \; \
&& sed -i"" -r \
-e 's,^(DataDir[[:space:]]*=[[:space:]]).*,\1"/mapdata",' \
-e 's,^(Console\.Enable[[:space:]]*=[[:space:]]).*,\10,' \
etc/worldserver.conf \
&& mkdir -pv "./${INSTALL_PREFIX}/etc/" \
&& ln -s -T /etc/worldserver.conf "./${INSTALL_PREFIX}/etc/worldserver.conf" \
&& ln -s -T /etc/worldserver.conf.dist "./${INSTALL_PREFIX}/etc/worldserver.conf.dist" \
&& ln -s -T /etc/bnetserver.conf "./${INSTALL_PREFIX}/etc/authserver.conf" \
&& ln -s -T /etc/bnetserver.conf.dist "./${INSTALL_PREFIX}/etc/authserver.conf.dist"
# 由于之前选用的Busybox镜像在运行的时候会出现提示glibc不兼容的饿问题,所以更换为Debian镜像。
FROM debian:stretch-slim
ARG INSTALL_PREFIX=/opt/trinitycore
ENV LD_LIBRARY_PATH=/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:${INSTALL_PREFIX}/lib:/usr/lib/ncurses/lib \
PATH=/bin:/usr/bin:${INSTALL_PREFIX}/bin
COPY --from=builder /artifacts /
WORKDIR /
VOLUME ["/opt/trinitycore/logs", "/opt/trinitycore/data", "/src/sql"]
ARG TC_GIT_BRANCH=7.3.5
|
至此,TrinityCore 7.3.5标签内容即可正常完成编译。
目前这套配置所编译出的世界服务端依旧不能成功完成数据库的自动生成(populating)和自动升级(auto-update),主要问题在于无法找到一些依赖的动态链接库。目前推测应该是镜像内的配置引起的,这个问题尚有待解决。