跳过内容

Arrow R 包与您可能贡献过的其他 R 包不同,因为它构建在庞大且功能丰富的 Arrow C++ 实现之上。由于 R 包与 Arrow C++ 紧密集成,它通常需要一个专门的库副本(即,在开发过程中通常无法链接到系统版本的 libarrow)。

选项 1:使用每夜构建的 libarrow 二进制文件

在 Linux、macOS 和 Windows 上,您可以使用与包含编译代码的其他包(例如,从终端运行 R CMD INSTALL .,从 R 提示符运行 devtools::load_all(),或从 RStudio 运行 Install & Restart)相同的工作流程。如果 arrow/r/libarrow 目录未填充,配置脚本将尝试下载最新的每夜构建 libarrow 二进制文件,将其解压到 arrow/r/libarrow 目录(macOS、Linux)或 arrow/r/windows 目录(Windows),然后照常继续构建 R 包。

大多数情况下,您不需要更新 libarrow 版本,因为 R 包很少随 C++ 库的更新而更改;但是,如果您在重新构建 R 包时开始出现错误,您可能需要删除 libarrow 目录(macOS、Linux)或 windows 目录(Windows),然后进行“干净”的重新构建。您可以通过在终端中运行 R CMD INSTALL . --preclean,在 RStudio 中使用“Build”选项卡中的“Clean and Install”选项,或者如果您正在使用 R 包根目录中的 Makefile,则使用 make clean 来完成此操作。

选项 2:使用本地 Arrow C++ 开发版本

如果您需要同时更改 libarrow 和 R 包代码,或者如果无法在其他地方获取最新 libarrow 的二进制版本,则需要从源代码构建它。本节讨论如何设置配置为与 R 包一起使用的 C++ libarrow 构建。有关更通用的资源,请参阅 Arrow C++ 开发者指南

此过程主要有五个步骤。

步骤 1 - 安装依赖项

默认情况下,在构建 libarrow 时,如果找到合适的版本,将使用系统依赖项。如果系统依赖项不存在,libarrow 将在其自己的构建过程中构建它们。您唯一需要构建过程之外安装的依赖项是 cmake(用于配置构建)和 openssl(如果您正在构建 S3 支持)。

为了加快构建速度,您可以选择在系统上预安装更多 C++ 库依赖项(例如 lz4zstd 等),这样它们就不需要在 libarrow 构建中从源代码构建。

Ubuntu
sudo apt install -y cmake libcurl4-openssl-dev libssl-dev
macOS
brew install cmake openssl

步骤 2 - 配置 libarrow 构建

我们建议您将 libarrow 配置为构建到用户级目录而不是系统目录以进行开发工作。这样,您正在使用的开发版本就不会覆盖您可能已安装的已发布版本的 libarrow,并且您还能够使用多个版本的 libarrow(通过对不同版本使用不同的 ARROW_HOME 目录)。

在下面的示例中,libarrow 安装到一个名为 dist 的目录中,该目录与 Arrow 检出具有相同的父目录。您的 Arrow R 包安装可以指向任何目录,名称不限,但我们建议不要将其放置在 Arrow Git 检出目录中,因为不必要的更改可能会导致其无法正常工作。

export ARROW_HOME=$(pwd)/dist
mkdir $ARROW_HOME

Linux 上的特殊说明:在启动 R 并使用 arrow 之前,您需要将 LD_LIBRARY_PATH 设置为 $ARROW_HOME 下的 lib 目录。一种方法是将其添加到您的配置文件中(我们在此处使用 ~/.bash_profile,但您可能需要根据您的设置将其放入不同的文件中,例如,如果您使用 bash 以外的 shell)。在 macOS 上,您不需要这样做,因为 macOS 共享库路径在构建时已硬编码到其位置。

export LD_LIBRARY_PATH=$ARROW_HOME/lib:$LD_LIBRARY_PATH
echo "export LD_LIBRARY_PATH=$ARROW_HOME/lib:$LD_LIBRARY_PATH" >> ~/.bash_profile

首先在终端中导航到 arrow 存储库。您需要创建一个目录,C++ 构建将把其内容放入其中。我们建议您在 Arrow git 存储库的 cpp 目录中创建一个 build 目录(它被 git 忽略,因此您不会意外地将其签入)。接下来,将目录更改为 cpp/build 内部。

pushd arrow
mkdir -p cpp/build
pushd cpp/build

您将首先调用 cmake 来配置构建,然后调用 make install。对于 R 包,您需要使用 -D 标志启用 libarrow 中的几个功能。

Linux / Mac OS
cmake \
  -DCMAKE_INSTALL_PREFIX=$ARROW_HOME \
  -DCMAKE_INSTALL_LIBDIR=lib \
  -DARROW_COMPUTE=ON \
  -DARROW_CSV=ON \
  -DARROW_DATASET=ON \
  -DARROW_EXTRA_ERROR_CONTEXT=ON \
  -DARROW_FILESYSTEM=ON \
  -DARROW_INSTALL_NAME_RPATH=OFF \
  -DARROW_JEMALLOC=ON \
  -DARROW_JSON=ON \
  -DARROW_PARQUET=ON \
  -DARROW_WITH_SNAPPY=ON \
  -DARROW_WITH_ZLIB=ON \
  ..

.. 指的是 C++ 源目录:您位于 cpp/build 中,源位于 cpp 中。

启用更多 Arrow 功能

要启用可选功能,包括:S3 支持、替代内存分配器和附加压缩库,请在调用 cmake 时添加部分或所有这些标志(末尾的 \ 使它们更容易在新行中粘贴到 bash shell 中)。

  -DARROW_GCS=ON \
  -DARROW_MIMALLOC=ON \
  -DARROW_S3=ON \
  -DARROW_WITH_BROTLI=ON \
  -DARROW_WITH_BZ2=ON \
  -DARROW_WITH_LZ4=ON \
  -DARROW_WITH_SNAPPY=ON \
  -DARROW_WITH_ZSTD=ON \

可能也有用的其他标志

  • -DBoost_SOURCE=BUNDLED-DThrift_SOURCE=BUNDLED,例如,或任何其他依赖项 *_SOURCE,如果您有一个无法与 Arrow 正确配合使用的 C++ 依赖项的系统版本。这会告诉构建从源代码编译它自己的依赖项版本。

  • -DCMAKE_BUILD_TYPE=debug-DCMAKE_BUILD_TYPE=relwithdebinfo 可用于调试。您通常不希望这样做,因为调试版本在运行时比默认的 release 版本慢得多。

  • -DARROW_BUILD_STATIC=ON-DARROW_BUILD_SHARED=OFF,如果您想使用静态库而不是动态库。使用静态库时,R 包没有链接到错误库的风险,但这确实意味着如果您更改 C++ 代码,则必须重新编译 C++ 库和 R 包。编译器通常仅在动态库不存在时才链接到静态库,这就是为什么我们需要设置 -DARROW_BUILD_SHARED=OFF。如果您在之前编译和安装后切换,您可能需要从 $ARROW_HOME/dist/bin 中删除 .dll.so 文件。

注意 cmake 对空格特别敏感,如果您看到错误,请检查是否没有多余的空格。

步骤 3 - 构建 libarrow

您也可以在此命令末尾添加 -j# 以通过并行运行(其中 # 是您可用的核心数)来加快编译速度。

cmake --build . --target install -j8

步骤 4 - 构建 Arrow R 包

构建 libarrow 后,您可以从 Git 检出安装 R 包及其依赖项,以及其他开发依赖项。

popd # To go back to the root directory of the project, from cpp/build
pushd r
R -e "install.packages('remotes'); remotes::install_deps(dependencies = TRUE)"
R CMD INSTALL --no-multiarch .

--no-multiarch 标志使其仅在“主”架构上编译。这将为您的路径中 R 对应的架构编译。如果您在一个架构上编译然后切换到另一个架构,请务必传递 --preclean 标志,以便为新架构重新编译 R 包代码。否则,您可能会看到诸如 LoadLibrary failure: %1 is not a valid Win32 application 之类的错误。

编译标志

如果您在构建 C++ 扩展时需要设置任何编译标志,可以使用 ARROW_R_CXXFLAGS 环境变量。例如,如果您使用 perf 分析 R 扩展,您可能需要设置:

export ARROW_R_CXXFLAGS=-fno-omit-frame-pointer
重新编译 C++ 代码

通过此处描述的设置,您在迭代和处理 R 包时,不应该需要重新构建 Arrow 库甚至 R 包中的 C++ 源代码。只有在您更改了 R 包中的 C++ 代码时(即使如此,R CMD INSTALL . 也应该只需要重新编译已更改的文件)或者 libarrow C++ 已更改且 libarrow 与 R 包之间存在不匹配时,才需要重新构建它们。如果您发现每次安装包或运行测试时都重新构建其中一个或两者,则您的设置可能存在问题。

对于完整构建:一个 cmake 命令,所有与 R 相关的可选依赖项都已开启。使用其他语言进行开发可能也需要不同的标志。例如,要开发 Python,您还需要添加 -DARROW_PYTHON=ON(尽管此处已包含所有用于 Python 的其他标志)。

cmake \
  -DCMAKE_INSTALL_PREFIX=$ARROW_HOME \
  -DCMAKE_INSTALL_LIBDIR=lib \
  -DARROW_COMPUTE=ON \
  -DARROW_CSV=ON \
  -DARROW_DATASET=ON \
  -DARROW_EXTRA_ERROR_CONTEXT=ON \
  -DARROW_FILESYSTEM=ON \
  -DARROW_GCS=ON \
  -DARROW_INSTALL_NAME_RPATH=OFF \
  -DARROW_JEMALLOC=ON \
  -DARROW_JSON=ON \
  -DARROW_MIMALLOC=ON \
  -DARROW_PARQUET=ON \
  -DARROW_S3=ON \
  -DARROW_WITH_BROTLI=ON \
  -DARROW_WITH_BZ2=ON \
  -DARROW_WITH_LZ4=ON \
  -DARROW_WITH_SNAPPY=ON \
  -DARROW_WITH_ZLIB=ON \
  -DARROW_WITH_ZSTD=ON \
  ..

安装具有特定 git 引用的 R 包版本

如果您需要从特定存储库或 git 引用安装 Arrow,在除 Windows 以外的大多数平台上,您可以运行

remotes::install_github("apache/arrow/r", build = FALSE)

build = FALSE 参数很重要,这样安装才能访问 apache/arrowcpp/ 目录中的 C++ 源代码。

与其他安装方法一样,将环境变量 LIBARROW_MINIMAL=falseARROW_R_DEV=true 分别提供功能更齐全的 Arrow 版本和更详细的输出。

例如,要从 apache/arrow 中的(虚构的)分支 bugfix 安装,您可以运行

Sys.setenv(LIBARROW_MINIMAL="false")
remotes::install_github("apache/arrow/r@bugfix", build = FALSE)

开发人员可能希望使用这种方法来安装与另一个 Arrow 开发环境或系统安装(例如,我们在 arrowbench 中使用它来安装与系统安装隔离的 libarrow 开发版本)分开的特定提交。如果您已经系统范围内安装了 libarrow,您可能需要设置一些额外的变量才能将此构建与您的系统库隔离。

  • 将环境变量 FORCE_BUNDLED_BUILD 设置为 true 将跳过 pkg-config 对 libarrow 的搜索,并尝试从给定的存储库 + ref 的同一源构建。

  • 您可能还需要将 Makevars CPPFLAGSLDFLAGS 设置为 "",以防止安装过程尝试链接到已安装的系统版本的 libarrow。一种临时实现此目的的方法是将您的 remotes::install_github() 调用包装起来,如下所示:

withr::with_makevars(list(CPPFLAGS = "", LDFLAGS = ""), remotes::install_github(...))

环境变量摘要

  • 请参阅面向用户的安装文章,了解大量决定构建方式和构建功能的环境变量。
  • ARROW_OFFLINE_BUILD:设置为 true 时,构建脚本将不会下载预编译的 C++ 库二进制文件,如果需要,也不会下载 cmake。它将关闭任何需要下载的功能,除非它们在 ARROW_THIRDPARTY_DEPENDENCY_DIRtools/thirdparty_download/ 子文件夹中可用。create_package_with_all_dependencies() 创建该子文件夹。

故障排除

请注意,对 libarrow 进行任何更改后,您必须重新安装它并运行 make cleangit clean -fdx .,以删除 r/src/ 目录中的任何缓存对象代码,然后才能重新安装 R 包。这仅在您更改 libarrow 源代码时才需要;如果您只编辑 r/ 中的 R 或 C++ 代码,则无需手动清除对象文件。

Arrow 库 - R 包不匹配

如果 libarrow 和 R 包出现分歧,您将看到类似以下错误:

Error: package or namespace load failed for ‘arrow' in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/Library/Frameworks/R.framework/Versions/4.0/Resources/library/00LOCK-r/00new/arrow/libs/arrow.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.0/Resources/library/00LOCK-r/00new/arrow/libs/arrow.so, 6): Symbol not found: __ZN5arrow2io16RandomAccessFile9ReadAsyncERKNS0_9IOContextExx
  Referenced from: /Library/Frameworks/R.framework/Versions/4.0/Resources/library/00LOCK-r/00new/arrow/libs/arrow.so
  Expected in: flat namespace
 in /Library/Frameworks/R.framework/Versions/4.0/Resources/library/00LOCK-r/00new/arrow/libs/arrow.so
Error: loading failed
Execution halted
ERROR: loading failed

要解决此问题,请尝试重新构建 Arrow 库

libarrow 的多个版本

如果您是从用户级目录安装,并且您的系统目录中已经安装了以前版本的 libarrow,那么当您安装 R 包时,可能会遇到以下错误:

Error: package or namespace load failed for ‘arrow' in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/Library/Frameworks/R.framework/Versions/4.0/Resources/library/00LOCK-r/00new/arrow/libs/arrow.so':
  dlopen(/Library/Frameworks/R.framework/Versions/4.0/Resources/library/00LOCK-r/00new/arrow/libs/arrow.so, 6): Library not loaded: /usr/local/lib/libarrow.400.dylib
  Referenced from: /usr/local/lib/libparquet.400.dylib
  Reason: image not found

如果发生这种情况,您需要确保在构建 arrow 时不要让 R 链接到您的系统库。您可以通过多种不同的方式实现这一点。

  • MAKEFLAGS 环境变量设置为 "LDFLAGS="(请参阅下面的示例),这是实现此目的的推荐方法。
  • 使用 {withr} 的 with_makevars(list(LDFLAGS = ""), ...)
  • LDFLAGS= 添加到您的 ~/.R/Makevars 文件中(最不推荐的方式,尽管它是网上建议的常见调试方法)
MAKEFLAGS="LDFLAGS=" R CMD INSTALL .

rpath 问题

如果包安装/加载失败并出现类似这样的错误:

  ** testing if installed package can be loaded from temporary location
  Error: package or namespace load failed for 'arrow' in dyn.load(file, DLLpath = DLLpath, ...):
  unable to load shared object '/Users/you/R/00LOCK-r/00new/arrow/libs/arrow.so':
  dlopen(/Users/you/R/00LOCK-r/00new/arrow/libs/arrow.so, 6): Library not loaded: @rpath/libarrow.14.dylib

请确保已传递 -DARROW_INSTALL_NAME_RPATH=OFF(这在 macOS 上很重要,可防止链接时出现问题,在其他平台上则无效)。或者,尝试将环境变量 R_LD_LIBRARY_PATH 设置为 Arrow C++ 在 make install 中安装的位置,例如 export R_LD_LIBRARY_PATH=/usr/local/lib,然后重试安装 R 包。

从源代码安装时,如果 R 和 C++ 库版本不匹配,安装可能会失败。如果您以前安装了这些库并希望升级 R 包,则需要首先更新 Arrow C++ 库。

对于任何其他构建/配置挑战,请参阅 C++ 开发者指南

其他安装问题

当安装 arrow R 包时,会触发许多脚本。对于不与底层代码交互的包用户,这些脚本都应该无需配置即可正常工作,并引入最完整的部分(例如,我们托管的官方二进制文件)。然而,了解这些脚本可以帮助包开发人员在它们出现问题或安装出现问题时进行故障排除。有关更多信息,请参阅R 包安装文章