构建 Arrow C++#
系统设置#
Arrow 使用 CMake 作为构建配置系统。 我们建议进行外部构建。 如果您不熟悉此术语
内部构建:从
cpp
目录直接调用cmake
。 当您希望维护多个构建环境(例如,一个用于调试构建,另一个用于发布构建)时,这可能会很不灵活外部构建:从另一个目录调用
cmake
,创建一个与任何其他构建环境不交互的隔离构建环境。 例如,您可以创建cpp/build-debug
并从此目录调用cmake $CMAKE_ARGS ..
构建需要
支持 C++17 的编译器。 在 Linux 上,gcc 7.1 及更高版本应该足够。 对于 Windows,至少需要 Visual Studio VS2017。
CMake 3.16 或更高版本
在 Linux 和 macOS 上,使用
make
或ninja
构建实用程序最少 1GB 的 RAM 用于最小构建,4GB 用于带有测试的最小调试构建,8GB 用于使用 docker 的完整构建。
在 Ubuntu/Debian 上,您可以使用以下命令安装需求
sudo apt-get install \
build-essential \
ninja-build \
cmake
在 Alpine Linux 上
apk add autoconf \
bash \
cmake \
g++ \
gcc \
ninja \
make
在 Fedora Linux 上
sudo dnf install \
cmake \
gcc \
gcc-c++ \
ninja-build \
make
在 Arch Linux 上
sudo pacman -S --needed \
base-devel \
ninja \
cmake
在 macOS 上,您可以使用 Homebrew
git clone https://github.com/apache/arrow.git
cd arrow
brew update && brew bundle --file=cpp/Brewfile
使用 vcpkg
git clone https://github.com/apache/arrow.git
cd arrow
vcpkg install \
--x-manifest-root cpp \
--feature-flags=versions \
--clean-after-build
在 MSYS2 上
pacman --sync --refresh --noconfirm \
ccache \
git \
mingw-w64-${MSYSTEM_CARCH}-boost \
mingw-w64-${MSYSTEM_CARCH}-brotli \
mingw-w64-${MSYSTEM_CARCH}-cmake \
mingw-w64-${MSYSTEM_CARCH}-gcc \
mingw-w64-${MSYSTEM_CARCH}-gflags \
mingw-w64-${MSYSTEM_CARCH}-glog \
mingw-w64-${MSYSTEM_CARCH}-gtest \
mingw-w64-${MSYSTEM_CARCH}-lz4 \
mingw-w64-${MSYSTEM_CARCH}-protobuf \
mingw-w64-${MSYSTEM_CARCH}-python3-numpy \
mingw-w64-${MSYSTEM_CARCH}-rapidjson \
mingw-w64-${MSYSTEM_CARCH}-snappy \
mingw-w64-${MSYSTEM_CARCH}-thrift \
mingw-w64-${MSYSTEM_CARCH}-zlib \
mingw-w64-${MSYSTEM_CARCH}-zstd
构建#
以下所有说明都假定您已克隆 Arrow git 存储库并导航到 cpp
子目录
$ git clone https://github.com/apache/arrow.git
$ cd arrow/cpp
CMake 预设#
使用 CMake 版本 3.21.0 或更高版本,提供了一些用于各种构建配置的预设。 您可以使用 cmake --list-presets
获取可用预设的列表
$ cmake --list-presets # from inside the `cpp` subdirectory
Available configure presets:
"ninja-debug-minimal" - Debug build without anything enabled
"ninja-debug-basic" - Debug build with tests and reduced dependencies
"ninja-debug" - Debug build with tests and more optional components
[ etc. ]
您可以使用 cmake -N --preset <preset name>
检查给定预设启用的特定选项
$ cmake --preset -N ninja-debug-minimal
Preset CMake variables:
ARROW_BUILD_INTEGRATION="OFF"
ARROW_BUILD_STATIC="OFF"
ARROW_BUILD_TESTS="OFF"
ARROW_EXTRA_ERROR_CONTEXT="ON"
ARROW_WITH_RE2="OFF"
ARROW_WITH_UTF8PROC="OFF"
CMAKE_BUILD_TYPE="Debug"
您还可以从给定的预设创建构建
$ mkdir build # from inside the `cpp` subdirectory
$ cd build
$ cmake .. --preset ninja-debug-minimal
Preset CMake variables:
ARROW_BUILD_INTEGRATION="OFF"
ARROW_BUILD_STATIC="OFF"
ARROW_BUILD_TESTS="OFF"
ARROW_EXTRA_ERROR_CONTEXT="ON"
ARROW_WITH_RE2="OFF"
ARROW_WITH_UTF8PROC="OFF"
CMAKE_BUILD_TYPE="Debug"
-- Building using CMake version: 3.21.3
[ etc. ]
然后要求编译构建目标
$ cmake --build .
[142/142] Creating library symlink debug/libarrow.so.700 debug/libarrow.so
$ tree debug/
debug/
├── libarrow.so -> libarrow.so.700
├── libarrow.so.700 -> libarrow.so.700.0.0
└── libarrow.so.700.0.0
0 directories, 3 files
$ cmake --install .
创建构建时,除了预设定义的选项之外,还可以传递自定义选项,例如
$ cmake .. --preset ninja-debug-minimal -DCMAKE_INSTALL_PREFIX=/usr/local
注意
CMake 预设提供了一些帮助,以便开始 Arrow 开发并了解常见的构建配置。 不保证它们是不变的,但将来可能会根据反馈进行更改。
强烈建议自动化构建、持续集成、发布脚本等使用手动配置,而不是依赖 CMake 预设,如下所述。
另请参阅
手动配置#
构建系统默认使用 CMAKE_BUILD_TYPE=release
,因此如果省略此参数,则会生成发布版本。
注意
您需要设置更多选项才能在 Windows 上构建。 有关详细信息,请参阅 在 Windows 上开发。
几种构建类型是可能的
Debug
:不应用任何编译器优化,并在二进制文件中添加调试信息。RelWithDebInfo
:应用编译器优化,同时在二进制文件中添加调试信息。Release
:应用编译器优化并从二进制文件中删除调试信息。
注意
这些构建类型默认提供合适的优化/调试标志,但您可以通过指定 -DARROW_C_FLAGS_${BUILD_TYPE}=...
和/或 -DARROW_CXX_FLAGS_${BUILD_TYPE}=...
来更改它们。 ${BUILD_TYPE}
是构建类型的大写形式。 例如,DEBUG
(-DARROW_C_FLAGS_DEBUG=...
/ -DARROW_CXX_FLAGS_DEBUG=...
)用于 Debug
构建类型,RELWITHDEBINFO
(-DARROW_C_FLAGS_RELWITHDEBINFO=...
/ -DARROW_CXX_FLAGS_RELWITHDEBINFO=...
)用于 RelWithDebInfo
构建类型。
例如,您可以通过传递 -DARROW_CXX_FLAGS_RELEASE=-O3
,将 -O3
用作 Release
构建类型的优化标志。 您可以通过传递 -DARROW_CXX_FLAGS_DEBUG=-g3
,将 -g3
用作 Debug
构建类型的调试标志。
您还可以使用标准 CMAKE_C_FLAGS_${BUILD_TYPE}
和 CMAKE_CXX_FLAGS_${BUILD_TYPE}
变量,但建议使用 ARROW_C_FLAGS_${BUILD_TYPE}
和 ARROW_CXX_FLAGS_${BUILD_TYPE}
变量。 CMAKE_C_FLAGS_${BUILD_TYPE}
和 CMAKE_CXX_FLAGS_${BUILD_TYPE}
变量会替换 CMake 提供的所有默认标志,而 ARROW_C_FLAGS_${BUILD_TYPE}
和 ARROW_CXX_FLAGS_${BUILD_TYPE}
只会附加指定的标志,从而可以选择性地覆盖某些默认值。
您还可以使用标志 -DARROW_EXTRA_ERROR_CONTEXT=ON
运行默认构建,请参阅 额外的调试帮助。
最小发布版本构建(建议使用 1GB 或更多的 RAM 进行构建)
$ mkdir build-release
$ cd build-release
$ cmake ..
$ make -j8 # if you have 8 CPU cores, otherwise adjust
$ make install
带有单元测试的最小调试版本构建(建议使用 4GB 或更多的 RAM 进行构建)
$ git submodule update --init --recursive
$ export ARROW_TEST_DATA=$PWD/../testing/data
$ mkdir build-debug
$ cd build-debug
$ cmake -DCMAKE_BUILD_TYPE=Debug -DARROW_BUILD_TESTS=ON ..
$ make -j8 # if you have 8 CPU cores, otherwise adjust
$ make unittest # to run the tests
$ make install
默认情况下不构建单元测试。 构建后,还可以使用 CMake 提供的 ctest
工具调用单元测试(请注意,test
依赖于 python
的可用性)。
在某些 Linux 发行版上,运行测试套件可能需要设置显式区域设置。 如果您看到任何与区域设置相关的错误,请尝试设置环境变量(这需要 locales
包或等效包)
$ export LC_ALL="en_US.UTF-8"
使用 Ninja 加快构建速度#
许多贡献者使用 Ninja 构建系统来获得更快的构建速度。 它尤其加快了增量构建。 要使用 ninja
,请在调用 cmake
时传递 -GNinja
,然后使用 ninja
命令而不是 make
。
Unity 构建#
CMake unity 构建选项可以显着加快完整构建速度,但它也会增加内存需求。 如果内存消耗不是问题,请考虑将其打开(使用 -DCMAKE_UNITY_BUILD=ON
)。
可选组件#
默认情况下,C++ 构建系统创建一个相当精简的构建。我们有几个可选的系统组件,您可以通过将布尔标志传递给 cmake
来选择构建它们。
-DARROW_BUILD_UTILITIES=ON
: 构建 Arrow 命令行实用程序-DARROW_COMPUTE=ON
: 构建所有计算内核函数-DARROW_CSV=ON
: CSV 读取器模块-DARROW_CUDA=ON
: CUDA 集成,用于 GPU 开发。 依赖于 NVIDIA CUDA 工具包。 用于构建库的 CUDA 工具链可以通过使用$CUDA_HOME
环境变量进行自定义。-DARROW_DATASET=ON
: Dataset API,隐含 Filesystem API-DARROW_FILESYSTEM=ON
: 用于访问本地和远程文件系统的 Filesystem API-DARROW_FLIGHT=ON
: Arrow Flight RPC 系统,至少依赖于 gRPC-DARROW_FLIGHT_SQL=ON
: Arrow Flight SQL-DARROW_GANDIVA=ON
: Gandiva 表达式编译器,依赖于 LLVM、Protocol Buffers 和 re2-DARROW_GANDIVA_JAVA=ON
: Gandiva JNI 绑定,用于 Java-DARROW_GCS=ON
: 构建带有 GCS 支持的 Arrow(需要用于 C++ 的 GCloud SDK)-DARROW_HDFS=ON
: Arrow 与 libhdfs 集成,用于访问 Hadoop 文件系统-DARROW_JEMALLOC=ON
: 构建基于 Arrow jemalloc 的分配器,默认启用-DARROW_JSON=ON
: JSON 读取器模块-DARROW_MIMALLOC=ON
: 构建基于 Arrow mimalloc 的分配器-DARROW_ORC=ON
: Arrow 与 Apache ORC 集成-DARROW_PARQUET=ON
: Apache Parquet 库和 Arrow 集成-DPARQUET_REQUIRE_ENCRYPTION=ON
: Parquet 模块化加密-DARROW_PYTHON=ON
: 此选项自 10.0.0 起已弃用。 将在未来的版本中删除。 请改用 CMake 预设。或者您可以直接启用ARROW_COMPUTE
、ARROW_CSV
、ARROW_DATASET
、ARROW_FILESYSTEM
、ARROW_HDFS
和ARROW_JSON
。-DARROW_S3=ON
: 支持与 Amazon S3 兼容的文件系统-DARROW_SUBSTRAIT=ON
: 构建并支持 Substrait-DARROW_WITH_RE2=ON
: 构建并支持使用 re2 库的正则表达式,默认启用,并在ARROW_COMPUTE
或ARROW_GANDIVA
为ON
时使用-DARROW_WITH_UTF8PROC=ON
: 构建并支持使用 utf8proc 库的 Unicode 属性,默认启用,并在ARROW_COMPUTE
或ARROW_GANDIVA
为ON
时使用-DARROW_TENSORFLOW=ON
: 构建启用 TensorFlow 支持的 Arrow
Arrow 中可用的压缩选项有
-DARROW_WITH_BROTLI=ON
: 构建对 Brotli 压缩的支持-DARROW_WITH_BZ2=ON
: 构建对 BZ2 压缩的支持-DARROW_WITH_LZ4=ON
: 构建对 lz4 压缩的支持-DARROW_WITH_SNAPPY=ON
: 构建对 Snappy 压缩的支持-DARROW_WITH_ZLIB=ON
: 构建对 zlib (gzip) 压缩的支持-DARROW_WITH_ZSTD=ON
: 构建对 ZSTD 压缩的支持
可以关闭核心 Arrow 共享库的某些功能,以缩短构建时间(如果您的应用程序不需要它们)
-DARROW_IPC=ON
: 构建 IPC 扩展
注意
如果您的用例仅限于读取/写入 Arrow 数据,那么默认选项应该足够了。 但是,如果您希望构建任何测试/基准测试,那么也需要 ARROW_JSON
(它将自动启用)。 如果需要扩展的格式支持,那么添加 ARROW_PARQUET
、ARROW_CSV
、ARROW_JSON
或 ARROW_ORC
不应启用任何其他组件。
注意
一般来说,如果您预计使用任何超出 cast
的计算内核,那么启用 ARROW_COMPUTE
是一个好主意。 虽然默认情况下内置了少量额外的内核(截至 12.0.0),但此列表将来可能会发生变化,因为它部分基于当前格式实现中的内核使用情况。
可选目标#
对于开发版本,您通常需要启用其他目标才能练习您的更改,使用以下 cmake
选项。
-DARROW_BUILD_BENCHMARKS=ON
: 构建可执行基准测试。-DARROW_BUILD_EXAMPLES=ON
: 构建使用 Arrow C++ API 的示例。-DARROW_BUILD_INTEGRATION=ON
: 构建其他可执行文件,这些可执行文件用于练习不同 Arrow 实现之间的协议互操作性。-DARROW_BUILD_UTILITIES=ON
: 构建可执行实用程序。-DARROW_BUILD_TESTS=ON
: 构建可执行单元测试。-DARROW_ENABLE_TIMING_TESTS=ON
: 如果构建单元测试,则启用那些依赖于挂钟计时的单元测试(此标志在 CI 上禁用,因为它可能使测试结果不稳定)。-DARROW_FUZZING=ON
: 构建模糊测试目标和相关可执行文件。
可选检查#
以下特殊检查也可用。 它们以各种方式检测生成的代码,以便在运行时检测特定类别的问题(例如,在执行单元测试时)。
-DARROW_USE_ASAN=ON
: 启用地址清理器以检查内存泄漏、缓冲区溢出或其他类型的内存管理问题。-DARROW_USE_TSAN=ON
: 启用线程清理器以检查多线程代码中的竞争。-DARROW_USE_UBSAN=ON
: 启用未定义行为清理器以检查触发 C++ 未定义行为的情况。
其中一些选项互不兼容,因此如果您想练习所有选项,您可能需要使用不同的选项构建多次。
CMake 版本要求#
我们支持 CMake 3.16 及更高版本。
LLVM 和 Clang 工具#
我们目前使用 LLVM 进行库构建以及其他开发人员工具,例如使用 clang-format
进行代码格式化。 LLVM 可以通过大多数现代软件包管理器(apt、yum、conda、Homebrew、vcpkg、chocolatey)安装。
构建依赖管理#
构建系统支持许多第三方依赖项
AWSSDK
: 用于 S3 支持,需要系统 cURL,并且可以使用下面描述的BUNDLED
方法
benchmark
: Google benchmark,用于测试
Boost
: 用于跨平台支持
Brotli
: 用于数据压缩
BZip2
: 用于数据压缩
c-ares
: gRPC 的依赖项
gflags
: 用于命令行实用程序(以前称为 Googleflags)
GLOG
: 用于日志记录
google_cloud_cpp_storage
: 用于 Google Cloud Storage 支持,需要系统 cURL,并且可以使用下面描述的BUNDLED
方法
gRPC
: 用于远程过程调用
GTest
: Googletest,用于测试
LLVM
: Gandiva 的依赖项
Lz4
: 用于数据压缩
ORC
: 用于 Apache ORC 格式支持
re2
: 用于计算内核和 Gandiva,gRPC 的依赖项
Protobuf
: Google Protocol Buffers,用于数据序列化
RapidJSON
: 用于数据序列化
Snappy
: 用于数据压缩
Thrift
: Apache Thrift,用于数据序列化
utf8proc
: 用于计算内核
ZLIB
: 用于数据压缩
zstd
: 用于数据压缩
CMake 选项 ARROW_DEPENDENCY_SOURCE
是一个全局选项,它指示构建系统如何解析每个依赖项。 有几个选项
AUTO
: 尝试在系统默认位置查找软件包,如果找不到则从源代码构建BUNDLED
: 从源代码自动构建依赖项SYSTEM
: 使用 CMake 内置的find_package
函数在系统路径中查找依赖项,或者对于没有此功能的包,使用pkg-config
CONDA
: 使用$CONDA_PREFIX
作为备用的SYSTEM
路径VCPKG
: 查找 vcpkg 安装的依赖项,如果未找到,则运行vcpkg install
来安装它们BREW
: 使用 Homebrew 默认路径作为备用的SYSTEM
路径
默认方法是 AUTO
,除非您在活动的 conda 环境中进行开发(通过是否存在 $CONDA_PREFIX
环境变量来检测),在这种情况下,它是 CONDA
。
单独依赖项解析#
虽然 -DARROW_DEPENDENCY_SOURCE=$SOURCE
为所有包设置全局默认值,但可以通过设置 -D$PACKAGE_NAME_SOURCE=..
来覆盖单个包的解析策略。 例如,要从源代码构建 Protocol Buffers,请设置
-DProtobuf_SOURCE=BUNDLED
这个变量不幸的是区分大小写;每个包的名称都在上面列出,但最新的列表可以在 cpp/cmake_modules/ThirdpartyToolchain.cmake 中找到。
捆绑依赖项版本#
当使用 BUNDLED
方法从源代码构建依赖项时,将使用 cpp/thirdparty/versions.txt
中的版本号。 还有一个依赖项源下载器脚本(见下文),可用于设置离线构建。
当使用 BUNDLED
进行依赖项解析时(如果您使用 jemalloc 或 mimalloc 分配器,这是推荐的),在第三方项目中静态链接 Arrow 库会更加复杂。 有关如何在这种情况下配置构建系统的说明,请参见下文。
离线构建#
如果您不使用上述变量将 Arrow 构建系统定向到预安装的依赖项,它们将由 Arrow 构建系统自动构建。 每个依赖项的源存档将通过互联网下载,这可能会在访问互联网受限的环境中引起问题。
要启用离线构建,您可以自己下载源文件,并使用 ARROW_$LIBRARY_URL
形式的环境变量来指示构建系统从本地文件读取,而不是访问互联网。
为了方便您,我们准备了一个脚本 thirdparty/download_dependencies.sh
,它会将每个依赖项的正确版本下载到您选择的目录中。 它将在最后打印一个 bash 风格的环境变量语句列表,用于您的构建脚本。
# Download tarballs into $HOME/arrow-thirdparty
$ ./thirdparty/download_dependencies.sh $HOME/arrow-thirdparty
然后您可以调用 CMake 来创建构建目录,它将使用声明的环境变量指向下载的存档,而不是下载它们(每个构建目录一个!)。
静态链接#
当 -DARROW_BUILD_STATIC=ON
时,所有作为静态库由 Arrow 构建系统构建的构建依赖项将被合并在一起,以创建一个静态库 arrow_bundled_dependencies
。 在类 UNIX 环境(Linux、macOS、MinGW)中,这被称为 libarrow_bundled_dependencies.a
,在带有 Visual Studio 的 Windows 上,这被称为 arrow_bundled_dependencies.lib
。 这个 “依赖项包” 库安装在与其他 Arrow 静态库相同的位置。
如果您正在使用 CMake,如果您使用 arrow_static
CMake 目标,捆绑的依赖项将自动包含在链接中。 在其他构建系统中,您可能需要显式链接到依赖项包。 我们创建了一个 基于 CMake 的构建配置示例,向您展示一个工作示例。
在 Linux 和 macOS 上,如果您的应用程序尚未链接到 pthread
库,则必须在链接器设置中包含 -pthread
。 在 CMake 中,可以使用 Threads
内置包来实现。
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(my_target PRIVATE Threads::Threads)
额外的调试帮助#
如果您使用 CMake 选项 -DARROW_EXTRA_ERROR_CONTEXT=ON
,它将在 RETURN_NOT_OK
宏内的错误检查中编译带有额外调试信息的库。 在带有 ASSERT_OK
的单元测试中,这将产生如下错误输出
../src/arrow/ipc/ipc-read-write-test.cc:609: Failure
Failed
../src/arrow/ipc/metadata-internal.cc:508 code: TypeToFlatbuffer(fbb, *field.type(), &children, &layout, &type_enum, dictionary_memo, &type_offset)
../src/arrow/ipc/metadata-internal.cc:598 code: FieldToFlatbuffer(fbb, *schema.field(i), dictionary_memo, &offset)
../src/arrow/ipc/metadata-internal.cc:651 code: SchemaToFlatbuffer(fbb, schema, dictionary_memo, &fb_schema)
../src/arrow/ipc/writer.cc:697 code: WriteSchemaMessage(schema_, dictionary_memo_, &schema_fb)
../src/arrow/ipc/writer.cc:730 code: WriteSchema()
../src/arrow/ipc/writer.cc:755 code: schema_writer.Write(&dictionaries_)
../src/arrow/ipc/writer.cc:778 code: CheckStarted()
../src/arrow/ipc/ipc-read-write-test.cc:574 code: writer->WriteRecordBatch(batch)
NotImplemented: Unable to convert type: decimal(19, 4)
弃用和 API 更改#
我们使用宏 ARROW_DEPRECATED
,它包装了已弃用的 API 的 C++ 弃用属性。 最好使用 -Werror=deprecated-declarations
(对于 GCC/Clang 或其他编译器的类似标志)编译第三方应用程序,以主动捕获和处理 API 更改。
模块化构建目标#
由于 C++ 项目有几个主要部分,我们为构建每个库组件、单元测试和基准测试组及其依赖项提供了模块化的 CMake 目标
make arrow
用于 Arrow 核心库make parquet
用于 Parquet 库make gandiva
用于 Gandiva (LLVM 表达式编译器) 库
注意
如果您选择了 Ninja 作为 CMake 生成器,请将 make arrow
替换为 ninja arrow
,依此类推。
要构建单元测试或基准测试,请将 -tests
或 -benchmarks
添加到目标名称。 因此,make arrow-tests
将构建 Arrow 核心单元测试。 使用 -all
目标,例如 parquet-all
,将构建所有内容。
如果您只想构建和安装一个或多个项目子组件,我们提供了 CMake 选项 ARROW_OPTIONAL_INSTALL
,仅安装已构建的目标。 例如,如果您只想构建 Parquet 库、其测试及其依赖项,您可以运行
cmake .. -DARROW_PARQUET=ON \
-DARROW_OPTIONAL_INSTALL=ON \
-DARROW_BUILD_TESTS=ON
make parquet
make install
如果在调用 make
时省略显式目标,则将构建所有目标。
在 macOS 上使用 Xcode 进行调试#
Xcode 是 macOS 提供的 IDE,可以通过生成 Xcode 项目来开发和调试 Arrow
cd cpp
mkdir xcode-build
cd xcode-build
cmake .. -G Xcode -DARROW_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=DEBUG
open arrow.xcodeproj
这将生成一个项目并在 Xcode 应用程序中打开它。 作为替代方案,命令 xcodebuild
将使用生成的项目执行命令行构建。 建议首次启动项目时使用 “自动创建方案” 选项。 选择自动生成的方案将允许您构建和运行启用断点的单元测试。