使您的库在 Windows on Arm 设备上运行





0/5 (0投票)
本文将介绍为几个流行的库创建原生 Windows on Arm 构建所需的步骤。
引言
许多用 C 和 C++ 编写的库都提供了二进制构建,可以方便地立即使用。这些库涵盖从 SDL 等游戏库,到 OpenSSL 等加密库,再到 Curl 等网络库。本文将介绍为几个流行的库创建原生 Windows on Arm 构建所需的步骤。这将作为一本指南,供希望提供 Arm 原生构建的库作者以及在没有 Windows on Arm 二进制文件(根据作者的经验,这种情况似乎很可能)时需要从源代码构建库的库用户使用。
获取工具
直到最近,如果您需要为 Arm 处理器(例如为 Asus NovaGo 2 合 1 便携式计算机提供动力的高通骁龙 835)上的 Windows 编写代码,您将仅限于 GCC 编译器集合,而很少有 Windows 开发者拥有或想要使用它。设置 GCC 是一个重大的工程,需要许多步骤。来自微软的最新进展已将这条崎岖的道路变成了四车道高速公路,而这正是本教程的重点。第一则公告是“Visual Studio 对 Windows 10 on Arm 开发的早期预览版”,发布于 2018 年 5 月 8 日。11 月 15 日带来了更多消息,包括对 64 位二进制文件的支持,在“Windows 10 on Arm 开发的官方支持”中宣布。较近的文章包含了将必要的交叉编译器添加到 Visual Studio 安装中的分步说明;相同的说明适用于所有版本,包括作者使用的社区版。
呈现这些说明的最简单方法是一系列带标题的屏幕截图;请跟随以下图片及其教学标题,假设您的互联网连接相当稳定,只需几分钟即可安装好工具。
上面,我们看到 Visual Studio Installer 程序出现在“开始”菜单中。激活后,安装程序会显示用户帐户控制(UAC)的提升提示,因为所有安装程序都需要管理员权限。
接下来,我们看到主 Visual Studio Installer 窗口,在它花费几秒钟整理机器上已安装项目列表后出现。在页面向下约 2/3 处,屏幕左侧的三行按钮中选择“修改”按钮。
这是在上一个图像中显示“修改”按钮后不久出现的窗口。虽然它们看起来并不太像,但屏幕顶部的四个超链接行为类似标签页;选择标记为“Individual Components”的第二个标签页。
这是选择上一个图像中窗口的“Individual Components”标签页时出现的窗口。虽然乍一看并不明显,但在“Installation Details”列的左侧有一个滚动条,您必须使用它来滚动组件列表。向下滚动,直到您的窗口看起来更像下一个图像。
这显示了用于 **Arm** 和 **Arm64** 的 Visual C++ 编译器和库。由于这张图片是在它们安装之后制作的,所以两者都已选中。
这些是 SDK、库和框架组,其中最大的一个,您可以在其中找到 Arm 处理器的 **ATL** 和 **MFC** 库。
为运行您的 Visual C/C++ 代码的目标计算机提供 Arm 支持
虽然上述步骤是在您的 Intel 或 AMD 驱动的开发机上安装了工具,但您期望运行 Arm 软件的机器还需要添加一些非标准 Windows 安装的内容。除非您打算将您编写的所有内容与 Visual C/C++ 运行时库静态链接,否则您必须在 Arm 计算机上安装一份副本。
要在任何受支持的平台上使用这些库,您必须获取并安装 **Microsoft C Runtime Library**,版本 14.00.24234.1 或更高版本,在所有平台上称为 vcruntime140.dll。Microsoft 将其作为“Microsoft Visual C++ 2015 Redistributable Update 3 RC”包的一部分分发,可在 https://www.microsoft.com/en-us/download/details.aspx?id=52685 (适用于 Intel 和 AMD CPU) 和 https://dotnet.myget.org/F/dotnet-core/api/v2/package/vc-runtime/2.0.0/ (适用于 Arm 处理器) 获取。
**Arm** 包以 .nupkg 扩展名的 NuGet 包形式提供。由于您从上述 URL 下载的副本并非通过 NuGet 包管理器获得,因此最佳的处理方式是将其文件扩展名更改为 .zip,并将其视为普通的 **ZIP** 存档。 **Arm** 和 **Arm64** (32 位和 64 位) 运行时都包含在一个包中。
要获取所需文件,请将存档提取到一个新目录中,然后使用文件资源管理器逐级进入。在目录 content\VC\Redist\MSVC\14.14.26405\onecore 中,有两个子目录,分别命名为 Arm 和 Arm64。与 Intel/AMD 包不同,**Arm** 包是一个直接、尽管不透明的 ZIP 存档,只需将两个叶子目录的内容复制到一个在您的 **PATH** 列表中的目录中即可使用。
毫不奇怪,运行时包含在您安装到 Visual Studio 的包中,但从上述 URL 获取 NuGet 包要容易得多。
构建库
现在您已经有了编译器和库,就可以构建您的第一个 Windows on Arm 兼容代码了。我们将使用 zlib,这是一个著名且广泛使用的用于创建和提取 zip 存档的库。
- 获取源代码。对于 zlib,这需要访问 https://www.zlib.net/,您可以在那里找到各种存档格式的源代码,包括标准的 Zip 存档和 GZip (tar.gz) 以及 tar.xx 混合格式。
- 提取源代码通常会产生一个庞大而深的目录树。例如,zlib 源存档会产生一个目录树,其中对 Windows 程序员最有价值的分支是 contrib/vstudio/vc14,假设您的 Visual Studio 安装是最新的(2017 年)。除其他事项外,此目录包含 zlibvc.sln,一个 Visual Studio 2012 解决方案文件,以及一系列 Visual Studio C/C++ 项目(.vcxproj)文件。
- 第一次打开 zlibvc.sln 时,Visual Studio 会提示您升级解决方案和其中的项目,以便它们能够使用最新的工具集进行构建。当这个简短的任务完成后,您就拥有了一个标准的 Visual C/C++ 项目,可以进行工作了。
- 在为 Windows on Arm 构建之前,您必须添加至少两个新配置,由新平台 **Arm** 的调试和发布配置组成。感谢您安装的新工具,Arm,也许还有 Arm64(如果您在前面所示的 Individual components 中选择了 **Arm64** 编译器和库)。实现这一目标的最简单方法是让 **Configuration Manager**(“构建”菜单上的倒数第二项)复制另一个项目配置。
- 虽然这通常就足够了,但在尝试为 Arm 构建之前,请查看 **表 1** 中列出的设置。
- 为 Windows on Arm 构建与为 Windows on Intel 处理器构建并没有太大区别。
节 | 设置 | Intel | Arm |
C++ | 浮点异常 | 启用或禁用 | 禁用 |
| 增强指令集 | 无,SSE,SSE2 | 无 |
链接 | 图像具有安全异常处理程序 | 是,如果它们确实是 | 否 |
| 省略帧指针 | 是或否 | 否 |
**表 1** 列出了必须为 Arm 配置更改的设置。
请注意,您的 Arm 二进制文件与其 Intel 兼容的兄弟文件在外观上没有明显区别;它们具有属性、版本资源以及为在 Intel 处理器上运行而构建的程序的其他所有属性。与 Windows on Intel 处理器一样,您的库可以是静态的也可以是动态的,并且动态链接库必须放置在何处(的规则)在两个平台上都相同。
展示与讲解
让我们来看看当我们在 Arm 驱动的 Windows 笔记本上尝试运行 zlib 的多个构建时发生了什么。
标题显示了 zlib 库构建的四个平台的进度。
在这里,我们看到 Win32 构建在集成到 Windows 10 Arm 版本中的 Intel x86 模拟器中运行。虽然它对测试程序影响相对较小,但所有程序在模拟器中运行通常都会稍慢一些,因为它必须将机器指令转换为目标处理器的等效指令。
接下来,我们看到 x64 构建的运行情况不佳。这是意料之中的,因为 Windows 10 Arm 版本中包含的模拟器目前仅支持 32 位应用程序。
接下来,我们看到 32 位 Arm 二进制文件如预期运行。
在这里,我们看到 Arm64 二进制文件也如预期工作。
当您尝试在 Intel 驱动的 Windows 计算机上运行 Arm 映像时,会发生这种情况。
亲自看看
除了向您展示如何将您拥有源代码的任何库移植为原生的 Arm 应用程序外,在撰写本文的过程中,我还修改了几个流行的库,使其能够在 Windows Arm 设备上运行。
请随意直接使用它们,或者查看所做的更改,以了解您可能需要做什么才能将您自己的复杂库和应用程序移植到 Windows on Arm。
库 | 存储库 URL | 注意 |
zlib | 1 | |
iconv | 2 | |
libxml2 | 3 | |
LZMA |
|
**表 2** 是流行开源库的 GitHub 存储库索引。
- 这个 zip 存档库 zlib 包含四个平台的构建:Win32 (x86)、Win64 (x64)、Arm (32 位原生 Arm 指令集) 和 Arm64 (原生 64 位 Arm 指令集)。其中四个可以运行在 Arm 上,而两个 Intel 目标可以在 Intel 驱动的桌面上运行。
- 这个国际编码转换库 iconv 的存储库包含四个平台的构建,其中两个 32 位构建如预期工作。由于指针溢出问题,两个 64 位构建都不可靠。解决此问题超出了本文的范围,但作者打算解决指针溢出问题,以便 64 位构建可以被信任。
- 由于 XML 解析库依赖于其他两个库,因此在两个平台上对它的支持仅限于 32 位,直到 iconv 中的 64 位指针问题得到解决。
每个存储库的解决方案目录都包含一个目录,其中包含每个工作平台的 zip 存档,其中包含预构建的二进制文件以及相应版本的 vcruntime140.dll。由于解决方案目录的嵌套很深,zlib 存档位于 https://github.com/txwizard/zlib_x64_and_Arm/tree/master/contrib/vstudio/vc14/Binaries_Built。根目录是另外两个存储库的解决方案目录。
结论
正如我们所见,为 Windows on Arm 构建现有的 C 和 C++ 应用程序并非难事。如果您有任何使用 CPU 特定功能的代码,您需要在继续之前进行修改。除此之外,移植到 Arm 通常就像安装 Visual Studio 工具并添加新的构建目标一样简单。