TeamTalk 是一款蘑菇街开源的企业内部即时通讯软件,代码质量优秀,具有较高的学习价值。源码由张小方老师提供,在此表示感谢。
此次的任务仍然是在 Visual Studio 中将源码跑起来,这个过程碰到了许多编译和链接的问题,通过不断调整试错终于跑通了代码,实属不易!学习源码,往往就难在这第一步,只要将源码运行起来,我们就成功了一半。后续的代码细节直接边调试边理解,再爽不过!这个过程大大加深了我对编译与链接的理解,也熟悉了 Visual Studio 的开发环境。

勘误:文中图片的路径有时候为 TeamTalk,有时为 TeamTalk_test,前者是笔者为写此博客而重新开的项目,后者是之前的项目,由于本人疏忽不小心混淆了,大家直接将 TeamTalk_test 视作 TeamTalk 即可。

1)从 github 上拉取源码,然后打开客户端的 .sln 解决方案文件:

2)VS可能提示我们更新项目的编译工具集,默认即可:

3)配置 configuration manager,指定 Build Solution 时是将该方案下的所有项目进行编译。

4)点击 Build Solution,编译完成后报错如下:
我们一个一个来解决错误。


先看 <hash_map> 的报错。该错误出现在 network 项目中,提示 <hashmap> 已经被废弃,如果要使用它,请先定义指定的宏。 右击 侧边栏的 network 项目,点击最下方的 property 选项;然后在 C/C++ 栏目中找到 Preprocessor 预处理栏,然后打开 Preprocessor Definitions ,向其中添加提示的宏 _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS 即可。Modules 和 teamtalk 项目也有此错误,相同操作。


之前的报错中还提示 ‘function’: is not a member of ‘std’ ,这个简单,直接在对应文件中添加头文件 <functional> 即可。


再次编译,报错如下:

mbstate_t 是结构体,无法直接赋值,应该使用初始化列表,将 0 改为 {0} 即可。


再次编译,报错如下:

先看后三个错误。在 utility 项目中无法打开 mfcs120ud.lib 文件,而在 Modules 和 teamtalk 项目中无法打开 utility.lib显然,是因为 mfcs120ud.lib 无法被打开导致 utility 项目无法生成 utility.lib ,继而使得 Modules 和 teamtalk 项目无法使用 utility.lib 所以我们必须先解决 mfcs120ud.lib 的问题。从这个静态链接库的名字我们可以知道,它不由任何项目生成,所以它应该是一个第三方库。打开文件夹,在整个 teamtalk 中搜索该文件,没有找到相关内容:

所以我们可以大胆猜测这个库应该是系统库或编译器自带库。让 chatgpt 来告诉我们:
image-20230501220445545

ok,我们现在知道它是 MFC 的库,而且对应的版本是 Visual Studio 2013 。而当前我们的 VS 版本为 2022,所以极有可能是版本不匹配的原因。还是不确定,那让我们在 VS 的 VC 目录下搜索 mfcs 的相关内容:

因此可以推断,2022 版本的对应库为 mfcs140u.lib 而不是 mfcs120ud.lib 。所以我们修改 utility 项目的依赖库,如下:

然后再次编译:

果然,utility 的 mfcs120ud.lib 错误解决。Modules 也有相同问题,步骤如法炮制。


再次编译:

尼玛!问题又多了,头大!现在提示在 Modules 项目中的 libprotobuf-lite.lib 文件中有_MSC_VER 相关的错误。 _MSC_VER 是什么?chatgpt 告诉你:

真清晰!OK,现在我们大概知道报错是因为 libprotobuf-lite.lib 的编译版本较低造成的。同样,libprotobuf-lite.lib 依然不是我们的项目生成的库文件,让我们看看它在哪:

嗯,从路径中的 3rdParty(第三方)也可以看出这是第三方库,而不是我们自己编译的库。那么问题来了,我们应该如何将 libprotobuf-lite.lib 转换为高编译器版本呢?大多数第三方库都是知名库,可以直接从官方下载最新版本,比如这个库就可以在github下载。不过仔细搜寻后发现第三方库下有相关的压缩包(最下方的 protobuf):

解压后进入 vsprojects 目录,使用 VS 打开其中的 libprotobuf-lite.vcxproj ,这是工程文件:

打开后 Build 这个解决方案,编译成功,最新编译版本的 libprotobuf-lite.lib 的输出位置见图:

由于 Modules 项目的 linker 输入目录(Additional Library Directories)为 D:\VSProjects\TeamTalk\win-client\3rdParty\lib\debug

所以我们用新的 lib 将久版本的 lib 替换掉:

然后再次编译,该错误已经消失。teamwork 也有相同错误,同样加上前缀即可:

啊哦,出现了关于 security.lib 的新错误…还是关于编译版本的问题。不过这次和之前的 libprotobuf-lite.lib 不同,第三方库目录下没有相关的压缩包。不过我们在 3rdParty\src 下发现了 security.cpp 源文件,所以为什么不直接编译呢?将这个源文件作为一个项目引入到 solution 下:

发现有多个源文件找不到路径,搜索后发现它们位于 \TeamTalk\server\src\libsecurity\src 下,所以将此目录包含进项目的头文件搜寻范围:

现在头文件已经能够检测到,不过还有些类型报错:

小问题,typedef unsigned char uchar_t 即可。然后单独编译 security 项目,报错如下:

预编译头文件?这是什么?还是问问 chatgpt 吧:

我们无需使用预编译头文件,这里报错是因为项目默认开启了预编译头文件的功能,关闭即可:

再次编译 security 项目,报错如下:

好,我们在项目中添加 SECURITY_WIN32 宏:

于是 security 项目编译成功:

好,同样,我们用新生成的 security.lib 把之前的替换掉:

然后编译整个 solution,报错:

提示在 security.lib 中调用了一些没有定义的函数。回想一下,刚才我们是不是只为 security 项目引入了头文件目录以确保头文件能够找到,却没有把这些头文件对应的源文件包含进来,这样的话,如果 security.cpp 中调用了这些头文件声明的函数,只有声明而没有定义,就一定会导致上图所示的链接错误 。因此我们需要把头文件对应的源文件包含进 security 项目,它们仍位于 \TeamTalk\server\src\libsecurity\src 中:

ok,编译 security 项目,报错如下:

问题不大,定义该宏就行。然后再次编译,成功!然后把新的 security.lib 替换掉之前的即可。然后编译整个 solution,报错如下:

Please verify that you have sufficient right to run this command ,权限不够?那我们关闭 VS,以管理员身份重新运行:

哟呼!跑起来啦!!!!大功告成。

接下来我们就可以随意打断点,单步调试 teamtalk 了,这样来学习源码真是不要太爽!

文章作者: 极简
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 后端技术分享
工程组织
喜欢就支持一下吧