開發指南#

本節提供希望貢獻 C++ 程式碼庫的開發人員相關資訊。

注意

由於專案的大部分開發人員都在 Linux 或 macOS 上工作,並非所有功能或開發人員工具都完全支援 Windows。如果您使用 Windows,請參閱 在 Windows 上開發

編譯器警告等級#

BUILD_WARNING_LEVEL CMake 選項可在我們用於程式碼整潔度的預定編譯器警告等級集之間切換。對於發佈版本,預設警告等級為 PRODUCTION,而對於偵錯版本,預設為 CHECKIN

當偵錯版本使用 CHECKIN 時,使用 gcc 和 clang 時會加入 -Werror,導致任何警告都會造成建置失敗,而使用 MSVC 時會設定 /WX,效果相同。

執行單元測試#

-DARROW_BUILD_TESTS=ON CMake 選項啟用建置單元測試執行檔。然後您可以單獨執行它們,方法是啟動所需的執行檔,或透過啟動 ctest 執行檔(屬於 CMake 套件的一部分)一次執行所有測試。

可能的調用方式如下

$ ctest -j16 --output-on-failure

其中 -j16 選項平行執行最多 16 個測試,以充分利用多個 CPU 核心和硬體執行緒。

執行效能評測#

-DARROW_BUILD_BENCHMARKS=ON CMake 選項啟用建置效能評測執行檔。然後您可以從命令列啟動相應的執行檔來單獨執行效能評測,例如

$ ./build/release/arrow-builder-benchmark

注意

為了獲得有意義的效能評測數字,強烈建議在 Release 模式下建置,以便啟用編譯器最佳化。

程式碼風格、Linting 和 CI#

此專案遵循 Google 的 C++ 風格指南,但有以下例外

  • 我們將行長度限制放寬至 90 個字元。

  • 我們在標頭檔中使用 NULLPTR 巨集(而不是 nullptr),該巨集在 src/arrow/util/macros.h 中定義,以支援建置 C++/CLI (ARROW-1134)。

  • 我們放寬了指南中關於結構體的規則。對於公開標頭,我們應僅將結構體用於主要為簡單資料容器的物件,在這些物件中,可以公開所有內部成員,並且任何方法主要都是為了方便。對於私有標頭,規則進一步放寬,結構體可用於方便的類型,這些類型即使可能不是簡單的資料容器,也不需要存取控制。

  • 對於輸出和輸入/輸出參數,我們偏好使用指標(風格指南在某些情況下建議使用可變參考)。

我們的 GitHub Actions 上的持續整合建置會在各種平台和組態上執行單元測試套件,包括使用 Address Sanitizer 和 Undefined Behavior Sanitizer 來檢查各種不當行為模式,例如記憶體洩漏。此外,程式碼庫還會接受許多程式碼風格和程式碼整潔度檢查。

為了通過 CI 建置,您修改的 Git 分支必須通過以下檢查

  • 使用專案的活動版本 clang 進行 C++ 建置,且沒有編譯器警告,並使用 -DBUILD_WARNING_LEVEL=CHECKIN。請注意,有些類型的警告(例如 -Wdocumentation,請參閱下文了解更多資訊)不會被 gcc 捕獲。

  • 通過各種 C++(和其他)風格檢查,使用 Archerylint 子命令進行檢查。這也可以在本地通過執行 archery lint --cpplint --clang-format --clang-tidy --fix 來修正。

  • CMake 檔案通過風格檢查,可以通過執行 archery lint --cmake-format --fix 來修正。這需要 Python 3 和 cmake_format(注意:目前在 Windows 上無法運作)。

在 Pull Request 上,「Dev / Lint」管線將執行這些檢查,並報告需要修正的檔案/行(如果有的話)。

為了考慮到主要 LLVM 版本之間 clang-format 行為的差異,我們釘選了使用的 clang-format 版本。您可以通過在 .env 中找到 CLANG_TOOLS 變數值來確認目前釘選的版本。請注意,版本必須完全匹配;較新版本(甚至是修補程式版本)都將無法運作。LLVM 可以通過系統套件管理器或套件管理器(如 Conda 或 Homebrew)安裝,但請注意,它們可能無法提供所需的確切版本。或者,可以直接從 LLVM 網站 下載二進位檔。

為了方便起見,除了 Archery 之外,還可以通過建置來執行 C++ 風格檢查。為此,請建置一個或多個目標 format(用於 clang-format)、lint_cpp_clilint(用於 cpplint)或 clang-tidy。例如

$ cmake -GNinja ../cpp ...
$ ninja format lint clang-tidy lint_cpp_cli

根據您安裝 clang-format 的方式,建置系統可能找不到它。在這種情況下,調用 CMake 將顯示如下錯誤

-- clang-format 12 not found

或者如果安裝的版本錯誤

-- clang-format found, but version did not match "^clang-format version 12"

您可以通過環境變數 $CLANG_TOOLS_PATH 或在調用 CMake 時傳遞 -DClangTools_PATH=$PATH_TO_CLANG_TOOLS 來提供包含 clang-format 執行檔和其他執行檔的目錄的明確路徑。例如

# We unpacked LLVM here:
$ ~/tools/bin/clang-format --version
clang-format version 12.0.0
# Pass the directory containing the tools to CMake
$ cmake ../cpp -DClangTools_PATH=~/tools/bin/
...snip...
-- clang-tidy found at /home/user/tools/bin/clang-tidy
-- clang-format found at /home/user/tools/bin/clang-format
...snip...

為了使所有人都能更輕鬆地重現 linting,我們提供了一個可以從儲存庫根目錄執行的 docker compose 目標

$ docker compose run ubuntu-lint

或者,在開啟的 Pull Request 上,評論機器人可以為您格式化 C++ 程式碼(它將推送一個 commit 到分支,然後可以拉取)。只需評論以下內容

@github-actions autotune

使用 include-what-you-use (IWYU) 清理 include#

我們偶爾會使用 Google 的 include-what-you-use 工具(也稱為 IWYU)來移除不必要的匯入。

要開始使用 IWYU,您必須首先按照專案文件中的說明建置它。一旦 include-what-you-use 執行檔位於您的 $PATH 中,您必須在新的 out-of-source CMake 建置目錄中執行 CMake,並使用 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON,如下所示

mkdir -p $ARROW_ROOT/cpp/iwyu
cd $ARROW_ROOT/cpp/iwyu
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
  -DARROW_BUILD_BENCHMARKS=ON \
  -DARROW_BUILD_BENCHMARKS_REFERENCE=ON \
  -DARROW_BUILD_TESTS=ON \
  -DARROW_BUILD_UTILITIES=ON \
  -DARROW_COMPUTE=ON \
  -DARROW_CSV=ON \
  -DARROW_DATASET=ON \
  -DARROW_FILESYSTEM=ON \
  -DARROW_FLIGHT=ON \
  -DARROW_GANDIVA=ON \
  -DARROW_HDFS=ON \
  -DARROW_JSON=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 \
  ..

為了使 IWYU 在程式碼庫中的所需元件上執行,必須通過 CMake 組態標誌啟用它。完成此操作後,您可以通過執行 helper iwyu.sh 腳本在整個程式碼庫上執行 IWYU

IWYU_SH=$ARROW_ROOT/cpp/build-support/iwyu/iwyu.sh
./$IWYU_SH

由於這非常耗時,您可以使用特殊的「match」選項檢查與某些字串模式匹配的檔案子集

./$IWYU_SH match $PATTERN

例如,如果您想對 src/arrow/array 中的所有檔案執行 IWYU 檢查,您可以執行

./$IWYU_SH match arrow/array

檢查 ABI 和 API 穩定性#

要建置 ABI 相容性報告,您需要安裝兩個工具 abi-dumperabi-compliance-checker

在偵錯模式下建置 Arrow C++,或者您可以選擇使用 -Og,它也會使用必要的符號進行建置,但包含一些程式碼最佳化。建置完成後,您可以使用以下命令產生 ABI 報告

abi-dumper -lver 9 debug/libarrow.so -o ABI-9.dump

上面的版本號是可自由選擇的。由於我們要比較版本,您現在應該 git checkout 您要與之比較的版本,並使用不同的版本號重新執行上述命令。產生兩個報告後,您可以使用以下命令建置比較報告

abi-compliance-checker -l libarrow -d1 ABI-PY-9.dump -d2 ABI-PY-10.dump

然後在 compat_reports/libarrow 中以 HTML 格式產生報告。

API 文件#

我們在標頭檔中使用 Doxygen 風格的註解 (///) 作為我們希望在類別和函式的 API 文件中顯示的註解。

當使用 clang 並使用 -DBUILD_WARNING_LEVEL=CHECKIN 建置時,會使用 -Wdocumentation 標誌,它會檢查一些常見的文件不一致性,例如使用 \param 記錄部分但不是所有函式參數。有關更多資訊,請參閱 LLVM 文件警告章節

雖然我們將 API 文件作為主要基於 Sphinx 的文件網站的一部分發佈,但您也可以隨時使用 Doxygen 建置 C++ API 文件。從 cpp/apidoc 目錄執行以下命令

doxygen Doxyfile

這需要安裝 Doxygen

Apache Parquet 開發#

要為 Apache Parquet 建置 C++ 程式庫,請在調用 CMake 時加入標誌 -DARROW_PARQUET=ON。要建置具有加密支援的 Apache Parquet,請在調用 CMake 時加入標誌 -DPARQUET_REQUIRE_ENCRYPTION=ON。可以使用 parquet make 目標來建置 Parquet 程式庫和單元測試

make parquet

在 Linux 和 macOS 上,如果您沒有在系統上安裝 Apache Thrift,或者您正在使用 -DThrift_SOURCE=BUNDLED 進行建置,則必須安裝 bisonflex 套件。在 Windows 上,我們在從原始碼建置 Thrift 時自動處理這些建置依賴項。

執行 ctest -L unittest 將執行所有已建置的 C++ 單元測試,而 ctest -L parquet 將僅執行 Parquet 單元測試。單元測試依賴於環境變數 PARQUET_TEST_DATA,該變數依賴於儲存庫 apache/parquet-testing 的 git 子模組

git submodule update --init
export PARQUET_TEST_DATA=$ARROW_ROOT/cpp/submodules/parquet-testing/data

此處 $ARROW_ROOT 是 Arrow 程式碼庫的絕對路徑。

Arrow Flight RPC#

除了 Arrow 依賴項之外,Flight 還需要

  • gRPC (>= 1.14,大約)

  • Protobuf (>= 3.6,早期版本可能也可以)

  • c-ares (gRPC 使用)

預設情況下,Arrow 將嘗試在建置 Flight 時下載並建置這些依賴項。

可選的 flight 程式庫和測試可以通過傳遞 -DARROW_FLIGHT=ON 來建置。

cmake .. -DARROW_FLIGHT=ON -DARROW_BUILD_TESTS=ON
make

您也可以使用額外依賴項的現有安裝。建置時,設定環境變數 gRPC_ROOT 和/或 Protobuf_ROOT 和/或 c-ares_ROOT

我們正在針對 gRPC 的最新版本進行開發。從 https://conda-forge.dev.org.tw/ 取得的 grpc-cpp 套件是一種跨平台取得 gRPC 的可靠方法。您可以嘗試使用系統程式庫來取得 gRPC 和 Protobuf,但這些程式庫可能太舊。在 macOS 上,您可以嘗試 Homebrew

brew install grpc