HoloLens2平台为Windows Arm,UE5打包程序时需要用到gRPC arm库

源码下载

到github克隆grpc仓库,切换到想要的tag版本,使用以下命令克隆子模块

1git submodule init
2git submodule update

克隆速度慢可以想点别的办法

安装nasm

安装nasm,把可执行文件nasm.exe所在的目录添加到系统Path环境变量

安装Windows CMake

下载最新的安装就行

生成x64的protoc和grpc_cpp_plugin

使用CMake GUI生成工程文件,指定生成文件类型为Visual Studio 2022(或者2019),添加以下变量,设置编译安装位置(可以自己指定其他位置)

1CMAKE_INSTALL_PREFIX=D:/grpc/Win64

Configure > Generate > Open Project

然后设置生成类型为RelWithDebugInfo,在解决方案资源管理器ALL_BUILD右键生成。编译完成后在INSTALL右键生成,这样编译好的可执行文件、头文件和库会拷贝到CMAKE_INSTALL_PREFIX下。

然后CMAKE_INSTALL_PREFIX下的bin到添加到系统Path环境变量

生成arm64的库

重新打开使用CMake GUI,使得配置的环境变量能够更新

添加以下变量

 1CMAKE_INSTALL_PREFIX=D:/grpc/HoloLens
 2CMAKE_CROSSCOMPILING=ON
 3// 以下两个在添加了环境变量Path应该可以不加,CMakeLists文件使用了find_program查找下面两个可执行文件
 4_gRPC_CPP_PLUGIN=D:/grpc/Win64/bin/grpc_cpp_plugin.exe
 5_gRPC_PROTOBUF_PROTOC_EXECUTABLE=D:/grpc/Win64/bin/grpc_cpp_plugin.exe
 6// 一定要加
 7OPENSSL_NO_ASM=ON
 8gRPC_BUILD_TEST=OFF
 9gRPC_BUILD_CODEGEN=OFF
10protobuf_BUILD_PROTOC_BINARIES=OFF

如果不添加OPENSSL_NO_ASM会导致c链接x64的chacha.lib导致链接失败。重复之前的操作就可以编译生成arm64的gRPC库

cares.lib链接错误

使用UE5打包HoloLens应用时报错

1UATHelper: Packaging (HoloLens): cares.lib(ares_strdup.obj) : error LNK2019: unresolved external symbol __imp_strdup referenced in function ares_strdup
2UATHelper: Packaging (HoloLens): cares.lib(ares_strsplit.obj) : error LNK2019: unresolved external symbol __imp_strnicmp referenced in function ares_strsplit
3UATHelper: Packaging (HoloLens): cares.lib(ares_strcasecmp.obj) : error LNK2001: unresolved external symbol __imp_strnicmp
4UATHelper: 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

1#undef HAVE_STRNICMP
2#undef HAVE_STRDUP
3#undef HAVE_STRCMPI
4#undef HAVE_STRICMP

修改源码third_party\cares\src\lib\ares_strsplit.c,增加strnicmp__函数,并把list_constains里的strnicmp改成该函数名

 1// from https://github.com/DigitalMars/dmc/blob/9478d25a677f70dbe4fc0ed317cc5a5e5050ef8b/src/core/STRNICMP.C
 2static int strnicmp__(const char *s1, const char *s2, size_t n)
 3{
 4    unsigned char c1, c2;
 5
 6    c1 = c2 = 0;
 7    while (n--)
 8    {
 9    c1 = tolower(*(const unsigned char *)s1);
10    s1++;
11    c2 = tolower(*(const unsigned char *)s2);
12    s2++;
13    if (!c1 || c1 != c2)
14        break;
15    }
16    return c1 - c2;
17}
18
19static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive)
20{
21  size_t len;
22  size_t i;
23
24  len = strlen(str);
25  for (i=0; i<num_elem; i++)
26  {
27    if (insensitive)
28    {
29#ifdef WIN32
30      if (strnicmp__(list[i], str, len) == 0)
31#else
32      if (strncasecmp(list[i], str, len) == 0)
33#endif
34        return 1;
35    }
36    else
37    {
38      if (strncmp(list[i], str, len) == 0)
39        return 1;
40    }
41  }
42
43  return 0;
44}

absl_symbolize.lib链接错误

报错内容:

1UATHelper: 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)
2UATHelper: 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)
3UATHelper: 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

1#ifdef _WIN32
2#include <winapifamily.h>
3#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) || \
4    WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
5// UWP doesn't have access to win32 APIs.
6#define ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32
7#endif

明确说明了UWP不支持,唯一的办法是用空函数实现后然后编译,patch文件如下

patch