跳至内容

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

选项 1:使用 nightly libarrow 二进制文件

在 Linux、macOS 和 Windows 上,您可以使用与包含编译代码的其他包相同的流程(例如,从终端使用 R CMD INSTALL .,从 R 提示符使用 devtools::load_all() 或从 RStudio 使用 Install & Restart)。如果 arrow/r/libarrow 目录未填充,则配置脚本将尝试下载最新的 nightly 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 使用“构建”选项卡中的“清理并安装”选项执行此操作,或者如果您使用的是位于 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 包之间存在不匹配时,才需要重建它们。如果您发现每次安装包或运行测试时都需要重建一个或两个,那么您的设置可能存在问题。

对于完整构建:带有所有 R 相关可选依赖项已启用的 cmake 命令。使用其他语言进行开发也可能需要不同的标志。例如,要开发 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 的搜索并尝试从给定的存储库+引用中构建相同的源代码。

  • 您可能还需要将 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 包安装的文章,以获取更多信息。