现已推出 Windows 版 R 的全新实验性版本,其主要目的是支持 UTF-8 编码,尤其是支持非欧洲语言。CRAN 软件包的检查结果现已在其 CRAN 结果页面上提供。请帮助查看您软件包的结果,如果您是 Windows 用户,请尝试使用新版本,特别是如果您使用的是非拉丁语系语言。
新版本可从 [2] 下载,说明请见 [1]。计划至少在 2022 年发布 R 4.2.0 之前并行运行新旧版本。计划为软件包维护人员提供检查服务。
来自 2020 年 5 月 和 2020 年 7 月 的先前博客文章介绍了 Windows 上 UTF-8 的一些技术方面。
新增内容
基于 UCRT 的新工具链、R 软件包库、R-devel 和 CRAN R 二进制软件包的定期实验性版本。有一个新的 CRAN 软件包检查 版本 r-devel-windows-x86_64-gcc10-UCRT
。
从当前的 CRAN 统计数据 来看,近 98% 的 CRAN 软件包似乎可以正常工作(结果为 OK
或 NOTE
),而使用 r-devel-windows-ix86+x86_64
的软件包有 99% 可以正常工作。
大约 380 个软件包仍需修复。其中可能只有部分需要直接修复,大多数会被其依赖项阻止,但这仍然可能需要大量工作。此外,到目前为止,自动化测试已在拉丁语 1 区域设置中完成,在 UTF-8 中运行时可能会发现其他问题。
R 用户如何提供帮助
此项工作的关键原因是支持非拉丁语系语言的 R Windows 用户。亚洲用户在尝试处理欧洲或北美系统上的文本时经常会遇到问题。他们仍然可以切换区域设置,但这通常不方便或受到限制。
对于同时处理基于非拉丁语系的多种语言文本的人来说,没有解决办法。根本无法同时处理来自日本和印度的人员的进程名称,因为没有 Windows 语言环境支持所有需要的语言。
非拉丁语系语言的用户也是可以帮助进行测试的关键人员。他们可以安装此 R 实验版本,并尝试分析其语言中的一些文本。R 和不兼容 UTF-8 编码的外部软件中可能会出现许多错误。目前已知的一个问题是 RTerm 和 RGui 中的光标移动,但还会有更多问题。
当前的自动化测试无法发现许多此类错误,因为该测试不涉及此类文本:这些测试是针对当前版本的 R 设计的。类似地,这些错误不会被当前活跃的 R 开发人员发现,因为他们不是这些语言的用户。
发现的问题可以报告给 R-devel 邮件列表 或直接报告给作者。任何报告都应附有最小的可复现示例,其中包含最少的数据,理想情况下使用 \u
或 \U
转义符来表示非 ASCII 字符,以便于调试,否则按照 一般建议 报告 R 中的错误。
自动化
为了允许定期检查,工具链、库、R 安装程序和 R 二进制包的构建是自动化的。这些构建的产品可供 [2] 下载,检查结果可在 CRAN 页面上获得(例如,请参阅 tiff)。有关构建的各个组件及其版本控制的更多信息,请参阅 [4]。
自动执行构建和检查的脚本 [3] 每周运行多次。所有组件都可能因重建和正在进行的工作而发生变化。与其他一些 CRAN 检查不同,目前所有包在每次运行时都会重新构建、重新安装和重新检查。
工具链和库在 Linux 上使用定制版本的 MXE(交叉编译)构建,也可以在 Docker 容器中构建。
R 和 R 安装程序使用工具链和库在 Windows 上本机构建。也可以在 Docker 容器中完成此操作,包括将必要的依赖项自动安装到干净的 Windows 虚拟机中。此脚本还可用于快速设置虚拟机,以进行包的手动实验/调试。
R 二进制包在 Windows 上以原生方式构建。但请注意,Windows Docker 容器只能在 Windows 主机上运行。
R 包的检查使用安装程序和在上一步中自动构建的二进制 R 包,因此与为最终用户/测试人员构建和分发的包相同。
R 更新
在 R-devel 中对上游进行了两个相关的安装程序更改。R 安装程序通常针对 32 位和 64 位架构进行构建,但现在也可以仅针对其中一个进行构建。以前,根本不支持仅 64 位的安装程序,而仅 32 位的安装程序已损坏。此实验性工具链仅支持 64 位架构。不计划支持 32 位架构。
现在,R 安装程序可用于在没有管理权限的情况下进行按用户安装。此类安装可以从命令行运行,因此适用于自动化测试。
其余更改仅在 R 的修补实验版本中。其中一些可能会在以后移植,一些仅用于实验。
为 UCRT 构建的二进制包在其 DESCRIPTION 文件中标记为 UCRT,并且 R 将拒绝安装没有此标记的带有本机代码(又称“需要编译”)的二进制包。这可防止将不兼容的包安装到此实验性版本的 R 中。反之则不然,如果有人尝试在 R-devel 的常规构建中重新使用由 R-devel 的 UCRT 构建安装的包,则它将不起作用,此类包可能会以意外的方式失败。
R 已修补,可从 [2] 下的预设位置优先下载二进制包。此位置有需要编译的 CRAN 包的二进制构建。它还具有几个 BIOC 依赖项。但是,其他二进制包(例如不需要编译的包)和源包是从标准 CRAN 位置下载的。
当包可用且是最新的时,此实验性功能效果很好。在其他情况下,可能会提示用户从官方 CRAN 存储库安装包,但随后安装将失败,并显示一条错误消息,指出该包未针对 UCRT 构建,或者由于 UCRT 的补丁过时,导致包构建失败。当包支持 UCRT 时,可以通过指定 type="binary"
或 type="source"
来解决此问题(有关这些安装模式如何工作的详细信息,请参阅 ?install.packages
)。
为了更轻松地从源代码安装包,此版本的 R 会在包安装时自动应用 R 包的补丁,这也是构建二进制包的时间。此自动修补仅作为临时措施,在包维护者更新其包之前使用。
源包是完整的,但根据包名称,R 将检查补丁存储库并在可用时应用补丁。这在安装输出、二进制包元数据中明确标记,补丁也包含在包的二进制构建中。它可以被关闭。
借助此功能,用户可以轻松地“照常”安装更多源软件包。补丁库位于 [2],主副本版本为 [3]。
R 现在理解 Makevars
和 Makefile
文件的 .ucrt
后缀。在此 UCRT 构建中,这些文件优先于后缀为 .win
的文件。R 的原始版本会忽略 .ucrt
文件,因此它们已经可以在上游软件包中用于实现 UCRT 所需的自定义设置。
补丁库中的补丁大多只是添加了这些 Makevars.ucrt
文件(Makevars.win
的自定义版本),到目前为止,只有几个软件包需要代码更改。如果软件包作者希望支持 UCRT,欢迎他们在代码中重新使用这些补丁。
覆盖范围以及软件包维护人员如何提供帮助
自上次迭代(2020 年 7 月)以来,R 软件包的覆盖范围已得到改善,这是通过对 R 软件包应用更多补丁、通过工具链提供的更多外部库(因此有更多 MXE 软件包)以及通过使用此新工具链构建外部应用程序 JAGS 来实现的。
软件包作者可以访问说明 [1] 和下载内容,以使用此工具链对他们的软件包进行试验和调试。这需要 Windows,理想情况下为 Windows 10。Microsoft 提供了 用于测试的免费 Windows 10 计算机(尽管时间有限),可以在 VirtualBox 和其他虚拟化软件中于 Linux、Mac 和 Windows 上使用。
如果软件包作者希望他们的软件包得到支持,他们可以做很多事情。首先,软件包作者可以查看软件包补丁,对其进行改进并将其合并到他们的代码中,并要求将它们从中央库中删除。
然后,几个当前的 CRAN 软件包需要工具链尚未提供的外部库。软件包作者可以通过提供 MXE 软件包(构建配置)来帮助添加对这些外部库的支持。理想情况下,这种支持将提供给上游 MXE,但也使用用于构建此工具链和库的修改版 MXE 进行了测试。这将降低维护成本,并让更多人受益于这项工作。请参阅 [1] 了解更多信息。
当 R 软件包以需要使用此工具链为 UCRT 重新构建该应用程序的方式使用外部应用程序时,也适用相同的情况。理想情况下,将提供对这些应用程序进行此操作的支持,以降低维护成本并增加对开源社区的总体收益。可以预期此类添加将受到欢迎,因为使用免费编译器构建的 Windows 开源软件不太可能永远使用 MSVCRT。
限制
正如 2020 年 5 月 的文章中所述,通过 UCRT 在 Windows 上支持 UTF-8 似乎是唯一可行的方法。不过,仍有一些限制。
要在 R 中可靠地使用 UTF-8 作为原生编码,Windows 系统编码(“活动代码页”)和 C 运行时编码都必须是 UTF-8。仅可在应用程序构建时将 UTF-8 设置为系统编码。这意味着当 R 嵌入(作为 DLL 链接)到另一个应用程序时,该应用程序必须将 UTF-8 设置为系统编码。这确实可行,RGui 和 RTerm 在实验性构建中确实执行了此操作,但并非所有嵌入 R 的应用程序都可能已准备好将 UTF-8 作为系统编码。根据这些应用程序决定在 Windows 上提供编码支持的方式,可能需要重新设计它们。
如果无法将 UTF-8 用作系统编码,R 的实验性构建仍将像现在的普通 R 一样使用 Windows 上的区域设置编码运行。在较旧的 Windows 系统(包括 Windows Server 2016 及更早版本)上也会发生这种情况,这些系统不允许将 UTF-8 设置为系统编码,并且会忽略此类请求。这就是 CRAN 检查仍使用 Latin 1 编码运行的原因。
当 R 包链接到外部 DLL 时,例如链接到 JAGS DLL 的 R 包 runjags,则存在与嵌入 R 相反的问题。根据外部 DLL 如何实现编码支持,这可能无法与 UTF-8 作为系统编码配合使用。它不适用于针对 MSVCRT 构建并也使用 -A
Windows API 调用(例如当前 R)的应用程序,这也是所有 R 包都必须使用新工具链重新构建的原因。
然后在同一应用程序中使用多个 C 运行时时还有其他问题。例如,C 运行时实现自己的堆,因此必须通过分配它们的同一运行时释放动态分配的对象,以便通过同一 DLL 保证安全。对于纯 C 而言,此限制并不那么明显,但它使 C++ 的使用变得复杂,其中通常通过头文件内联代码中的某些分配/取消分配,而另一些则在 DLL 中。在 JAGS 的情况下,通过使用此工具链为 UCRT [1] 重新构建 JAGS 来解决此问题,并且这通常可能是最直接的解决方案。
参考资料
方法:在 Windows 上的 R 中将 UTF-8 作为原生编码。 适用于所有用户。始终从头开始阅读,但大多数用户只需要前几节,最后几节仅适用于希望提供帮助的专家或志愿者。
下载。 R 安装程序、工具链和库。由于仍在进行此项工作,因此各个组件可能会发生更改或暂时消失。
脚本和补丁。 用于构建工具链、库、R 安装程序、R 包、检查 R 包等的资源。
CRAN 检查风格 r-devel-windows-x86_64-gcc10-UCRT 的详细信息。包括有关生成版本详细信息。
MXE 交叉编译环境。参考,使用此工具构建工具链和库,并添加或升级了多个包。一些添加内容受到 MXE-Octave 和 MSys2 的启发。
MinGW-w64 项目。参考,允许 R 使用 GCC 为 Windows 生成(提供与 Windows 交互的标头和库)。