HoloLens2平台为Windows Arm,UE5打包程序时需要用到gRPC arm库
源码下载
到github克隆grpc仓库,切换到想要的tag版本,使用以下命令克隆子模块
git submodule init
git submodule update
克隆速度慢可以想点别的办法
安装nasm
安装nasm,把可执行文件nasm.exe
所在的目录添加到系统Path
环境变量
安装Windows CMake
下载最新的安装就行
生成x64的protoc和grpc_cpp_plugin
使用CMake GUI生成工程文件,指定生成文件类型为Visual Studio 2022(或者2019),添加以下变量,设置编译安装位置(可以自己指定其他位置)
CMAKE_INSTALL_PREFIX=D:/grpc/Win64
Configure > Generate > Open Project
然后设置生成类型为RelWithDebugInfo,在解决方案资源管理器
的ALL_BUILD
右键生成。编译完成后在INSTALL
右键生成,这样编译好的可执行文件、头文件和库会拷贝到CMAKE_INSTALL_PREFIX
下。
然后把CMAKE_INSTALL_PREFIX
下的bin
到添加到系统Path
环境变量
生成arm64的库
重新打开使用CMake GUI,使得配置的环境变量能够更新
添加以下变量
CMAKE_INSTALL_PREFIX=D:/grpc/HoloLens
CMAKE_CROSSCOMPILING=ON
// 以下两个在添加了环境变量Path应该可以不加,CMakeLists文件使用了find_program查找下面两个可执行文件
_gRPC_CPP_PLUGIN=D:/grpc/Win64/bin/grpc_cpp_plugin.exe
_gRPC_PROTOBUF_PROTOC_EXECUTABLE=D:/grpc/Win64/bin/grpc_cpp_plugin.exe
// 一定要加
OPENSSL_NO_ASM=ON
gRPC_BUILD_TEST=OFF
gRPC_BUILD_CODEGEN=OFF
protobuf_BUILD_PROTOC_BINARIES=OFF
如果不添加OPENSSL_NO_ASM会导致c
链接x64的chacha.lib
导致链接失败。重复之前的操作就可以编译生成arm64的gRPC库
cares.lib链接错误
使用UE5打包HoloLens应用时报错
UATHelper: Packaging (HoloLens): cares.lib(ares_strdup.obj) : error LNK2019: unresolved external symbol __imp_strdup referenced in function ares_strdup
UATHelper: Packaging (HoloLens): cares.lib(ares_strsplit.obj) : error LNK2019: unresolved external symbol __imp_strnicmp referenced in function ares_strsplit
UATHelper: Packaging (HoloLens): cares.lib(ares_strcasecmp.obj) : error LNK2001: unresolved external symbol __imp_strnicmp
UATHelper: Packaging (HoloLens): cares.lib(ares_strcasecmp.obj) : error LNK2019: unresolved external symbol __imp_strcmpi referenced in function ares_strcasecmp
需要到gRPC编译目录下面的third_party\cares\cares\ares_config.h
下修改配置,把对应宏改成undef
#undef HAVE_STRNICMP
#undef HAVE_STRDUP
#undef HAVE_STRCMPI
#undef HAVE_STRICMP
修改源码third_party\cares\src\lib\ares_strsplit.c
,增加strnicmp__
函数,并把list_constains
里的strnicmp
改成该函数名
// from https://github.com/DigitalMars/dmc/blob/9478d25a677f70dbe4fc0ed317cc5a5e5050ef8b/src/core/STRNICMP.C
static int strnicmp__(const char *s1, const char *s2, size_t n)
{
unsigned char c1, c2;
= c2 = 0;
c1 while (n--)
{
= tolower(*(const unsigned char *)s1);
c1 ++;
s1= tolower(*(const unsigned char *)s2);
c2 ++;
s2if (!c1 || c1 != c2)
break;
}
return c1 - c2;
}
static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive)
{
size_t len;
size_t i;
= strlen(str);
len for (i=0; i<num_elem; i++)
{
if (insensitive)
{
#ifdef WIN32
if (strnicmp__(list[i], str, len) == 0)
#else
if (strncasecmp(list[i], str, len) == 0)
#endif
return 1;
}
else
{
if (strncmp(list[i], str, len) == 0)
return 1;
}
}
return 0;
}
absl_symbolize.lib链接错误
报错内容:
UATHelper: Packaging (HoloLens): absl_symbolize.lib(symbolize.obj) : error LNK2019: unresolved external symbol __imp_SymSetOptions referenced in function "void __cdecl absl::lts_20220623::InitializeSymbolizer(char const *)" (?InitializeSymbolizer@lts_20220623@absl@@YAXPEBD@Z)
UATHelper: Packaging (HoloLens): absl_symbolize.lib(symbolize.obj) : error LNK2019: unresolved external symbol __imp_SymInitialize referenced in function "void __cdecl absl::lts_20220623::InitializeSymbolizer(char const *)" (?InitializeSymbolizer@lts_20220623@absl@@YAXPEBD@Z)
UATHelper: Packaging (HoloLens): absl_symbolize.lib(symbolize.obj) : error LNK2019: unresolved external symbol __imp_SymFromAddr referenced in function "bool __cdecl absl::lts_20220623::Symbolize(void const *,char *,int)" (?Symbolize@lts_20220623@absl@@YA_NPEBXPEADH@Z)
打开third_party\abseil-cpp\absl\debugging\symbolize.cc
#ifdef _WIN32
#include <winapifamily.h>
#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) || \
WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// UWP doesn't have access to win32 APIs.
#define ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32
#endif
明确说明了UWP不支持,唯一的办法是用空函数实现后然后编译,patch文件如下