最近项目中需要把Google protobuf加入到UnrealEngine4游戏工程中,积累下一些有用的经验分享下。
UE有一套自己的编译规则,如何在游戏中添加第三方库官方有一篇很详细的文档(Linking Static Libraries Using The Build System)。
简单来说,第三方库一般放在’Source/ThirdParty’目录下,建一个目录,把需要包含的头文件以及编译好的库都放在这里,然后写一个对应的[LIBNAME].Build.cs文件,在这个文件里需要告诉编译器需要修改的设置,例如添加那些包含目录以及链接库。在游戏工程使用时,需要在本工程文件的[APPNAME].Build.cs中添加对该库的引用,就像下面这样
1 2 |
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "libprotobuf" }); |
对第三方库的使用,可以参照UnrealEngine的源码,在它的源码目录’Source/ThirdParty’里,有一大堆第三方库,不过这些库都是预先编译好的.lib和.a,如何编译出这些库官方并没有提供详细的文档说明。对于Windows环境来说比较简单,首先是使用和UE编辑器同样的VisualStudio版本,例如目前最新的4.14使用的是VS2015,并且在编译中使用/MD选项。google protobuf本身提供了一套cmake编译脚本,可以很方便的编译出所需要的lib文件。
比较麻烦的是Linux平台,UE提供了专门的clang工具链来作为Linux和Android平台的编译工具,可以参照官方的这篇文档下载安装(Compiling For Linux),不过这套工具链中并没有对应的make工具,所以我从UE源码中的UnrealBuildTool工具中把编译参数还原出来,手动写了一套python脚本来完成probobuf的编译。
为了适应UE4的环境,需要做一些改动,首先是protobuf中使用了类似于UINT这样的数据类型,而这种数据类型在UE4的源码中已经被屏蔽,具体可以参考UE源码中DisableOldUETypes.h文件的说明,为了使两者兼容,需要在protoc产生的.pb.h文件中添加#include “AllowWindowsPlatformTypes.h”和#include “HideWindowsPlatformTypes.h”两行代码。
1 2 3 4 5 6 7 8 9 |
#ifdef _MSC_VER #include "AllowWindowsPlatformTypes.h" #endif //include other header file #ifdef _MSC_VER #include "HideWindowsPlatformTypes.h" #endif |
另外protobuf源码中有一个文件使用了byteswap.h这个头文件,不幸的是,UE4源码中有一个ByteSwap.h文件,在clang编译器中产生编译错误,需要做一定的修改。
1 2 3 4 5 6 |
//google/protobuf/stubs/port.h, line 91 //#include <byteswap.h> // IWYU pragma: export #include <bits/byteswap.h> #define bswap_16(x) __bswap_16 (x) #define bswap_32(x) __bswap_32 (x) #define bswap_64(x) __bswap_64 (x) |
我把最终编译好的库以及所使用的的编译脚本放到了github上,所需环境如下
软件 | 版本 | 备注 |
---|---|---|
Google Protobuf | 3.1.0 | |
Visual Studio | 2015 | |
clang | 3.9.0 | EPIC提供改造过的工具链,需要参照这篇官方文档下载安装 |
CMake | 2.8以上 | 需要把cmake.exe所在路径加入到PATH路径中 |
Unreal Engine Source | 4.14.3 | 参照官方文档下载并编译源码 |
Python | 3.x or 2.x |
还是这么威武,我也碰到这个问题了,然后,看到这个,发现可以解决了。这就试试去
然而今天又遇到一个问题,这种方法修改后,还是会导致ue4的include “Networking” 出现错误。楼主有没有什么解决方案呀。
我用plugin的方式去封装protobuf的lib时,4.14, 出现
error C4146: 一元负运算符应用于无符号类型,结果仍为无符号类型
error C4647: 行为更改: __is_pod(google::protobuf::internal::AuxillaryParseTableField)在各种版本中具有不同的值
这种错误,楼主又遇见过么?
这个问题你解决了没有,我也遇到了。