使用cmake搭建一个跨平台游戏服务器

1 简言

当前游戏服务器开发,通常需要跨平台进行。开发人员在windows上进行代码编写,调试,然后发布到linux上编译运行。因此,构建一个既能在windows上运行,又可以在linux上运行的服务器项目很是重要。

cmake可以很方便的解决这个事情。这是由cmake的特性决定的:可以跨平台代码构建,使用简单的语句来描述所有平台的安装(编译过程)。

本文将使用C++17ProtobufTinyXML2以及spdlog来搭建一个基本的游戏服务器项目。

涉及到存储相关的Redis、MySQL等暂不接入,想要了解的同学可以浏览后续相关文章。


2 描述

2.1 C++(C# 文档 - 入门、教程、参考。 | Microsoft Docs):C++是一门十分强大的语言,不再过多叙述。这里我们将使用C++17来作为我们的版本,供开发人员能在项目开发中,使用到一些强大易用的新特性。

2.2 Protobuf(Protocol Buffers  |  Google Developers,全程是Protocol Buffers,是一种轻便高效的结构化数据存储格式,可以将数据结构序列化和反序列化,从而适用于数据传输。由于此特性,它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

下面是Protocol Buffers的官方介绍:

Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

在游戏项目中,我们将使用protobuf来进行数据存储、以及和客户端的通信。

2.3 TinyXML2(TinyXML-2 (grinninglizard.com)):TinyXML2是simple、small、efficient开源的C++ XML文件解析库,可以很方便的应用到现有的项目之中。非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作。

在游戏项目中,我们将使用TinyXML2读取配置表格。

2.4 Spdlog(GitHub - gabime/spdlog: Fast C++ logging library.):它是一个C++编写的日志库,具有简单、快速、易上手的特点。

在游戏项目中,我们将使用spdlog来进行打印日志。


3 编写CMakeLists

先上笔主本身可以运行的CMakeLists.txt(支持windows和linux两种环境)

cmake_minimum_required (VERSION 3.8)

set(CMAKE_CXX_COMPILER "/opt/rh/devtoolset-11/root/usr/bin/g++")
set(CMAKE_C_COMPILER "/opt/rh/devtoolset-11/root/usr/bin/gcc")
set(CMAKE_CXX_STANDARD 17)

project ("tdserver")

# 包含的路径
include_directories(.)
include_directories(lib framemk)
include_directories(third)
include_directories(third/protobuf-3.5.1)
include_directories(third/spdlog)
include_directories(third/tinyxml2)

if(WIN32)
    find_library(PROTOBUFLIB NAMES libprotobuf-lited PATHS lib)
    find_library(FRAMEMKLIB NAMES framemk PATHS lib)
    find_library(SPDLOGDLIB NAMES spdlogd PATHS lib)
elseif(UNIX)
    find_library(PROTOBUFLIB NAMES protobuf-lite PATHS lib)
    find_library(FRAMEMKLIB NAMES framemk PATHS lib)
    find_library(SPDLOGDLIB NAMES spdlog PATHS lib)
endif()

# 将源代码添加到此项目的可执行文件。
add_executable (tdserver "tdserver.cpp" "tdserver.h" )

# lib
target_link_libraries(tdserver ${FRAMEMKLIB} ${PROTOBUFLIB} ${SPDLOGDLIB})

if (WIN32)
elseif(UNIX)
target_link_libraries(tdserver pthread)
endif()

下图则是项目的目录详情

使用cmake搭建一个跨平台游戏服务器_第1张图片

 framemk是笔者自己编写的框架库,里面包含了网络、定时器、日志、读表、线程池等基础功能,后续我将会逐一编写文章进行讲解,这里先行跳过。本文的重点是CMakeLists.txt的编写。

lib文件夹下,存放着编译好的库,这里有三个库,分别是framemk、protobuf以及spdlog。其中,lib是windows环境下使用的静态库,.a是linux环境下使用的静态库。

细心的读者会发现,这里缺失了tinyxml2的库。这不是笔者的失误,而是tinyxml2很简单,只需要一个.h和.cpp文件,直接放到项目里就可以了,不需要特意编译成库的形式。

 接下来,让我们逐一分析一下CMakeLists的内容

3.1 设置版本限制

cmake_minimum_required (VERSION 3.8)

3.2 设置编译器和C++版本

set(CMAKE_CXX_COMPILER "/opt/rh/devtoolset-11/root/usr/bin/g++")
set(CMAKE_C_COMPILER "/opt/rh/devtoolset-11/root/usr/bin/gcc")
set(CMAKE_CXX_STANDARD 17)

3.3 设置包含的路径

include_directories(.)
include_directories(lib framemk)
include_directories(third)
include_directories(third/protobuf-3.5.1)
include_directories(third/spdlog)
include_directories(third/tinyxml2)

3.4 设置库文件

if(WIN32)
    find_library(PROTOBUFLIB NAMES libprotobuf-lited PATHS lib)
    find_library(FRAMEMKLIB NAMES framemk PATHS lib)
    find_library(SPDLOGDLIB NAMES spdlogd PATHS lib)
elseif(UNIX)
    find_library(PROTOBUFLIB NAMES protobuf-lite PATHS lib)
    find_library(FRAMEMKLIB NAMES framemk PATHS lib)
    find_library(SPDLOGDLIB NAMES spdlog PATHS lib)
endif()

3.5 将源代码添加到可执行文件

add_executable (tdserver "tdserver.cpp" "tdserver.h" )

这里采用了直接使用文件名字的方法来添加,适合数量较少的情况。但一个服务器工程文件,必然是数目庞大的,因此我们需要采用一种更加简洁的写法:

file(GLOB_RECURSE SRC_LIST *.cpp)

add_executable(tdserver ${SRC_LIST})

3.6 将库链接到可执行文件

target_link_libraries(tdserver ${FRAMEMKLIB} ${PROTOBUFLIB} ${SPDLOGDLIB})

if (WIN32)
elseif(UNIX)
target_link_libraries(tdserver pthread)
endif()

在linux下使用线程,必须显式链接到pthread库。因为pthread并非Linux系统的默认库,而是POSIX线程库。在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。

补充:在CMakeLists.txt中,我们发现了WIndows和Linux两种环境变量,这就引出了多平台的处理方法。

CMake适配多个操作系统(Windows和Linux)_MKleee的博客-CSDN博客方法1:使用变量来进行判断Cmake本身提供了很多变量来判断当前的系统环境,如图下所示:编写起来:if (WIN32)#编写语句elseif(IOS)#编写语句elseif(UNIX)#编写语句endif()方法2:使用CMAKE_SYSTEM_NAME来进行判断CMake为目标操作系统定义了CMAKE_SYSTEM_NAME,编写者不需要使用定制命令、工具或脚本来查询此信息。直接使用此变量的值来分辨出当前操作系统,从而布置不同的解决方案。编写起来:if(Chttps://blog.csdn.net/qq_38815038/article/details/123263623?spm=1001.2014.3001.5501


4 总结

阅读到此处,一个简单的服务器项目已经搭建起来,后续只需要进行相应的逻辑编写即可。当然,一个完整的游戏服务器,是庞大且复杂的,涉及到多个方面的知识,未来将会以示例项目,逐渐讲解各种模块的设计和编写。

想要了解更多有关游戏服务器的信息,可以关注我以获取最新的文章信息。

你可能感兴趣的:(游戏服务器,服务器,游戏,c++,架构,后端)