在 Windows 上開發#

如同 Linux 和 macOS,我們已努力使建置能夠「開箱即用」,透過 CMake 支援專案中相當大的子集。

系統設定#

Microsoft 提供免費的 Visual Studio Community 版本。在 shell 中進行開發時,每次開啟 shell 都必須初始化開發環境。

對於 Visual Studio 2017,執行以下批次指令碼

"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=amd64

對於 Visual Studio 2019,指令碼如下

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -arch=amd64

可以設定如 cmder 的終端機模擬器,使其在啟動新的開發主控台時自動執行此操作。

使用 conda-forge 作為建置相依性#

Miniconda 是一個精簡的 Python 發行版,包含 conda 套件管理器。Apache Arrow 社群的某些成員參與維護 conda-forge,這是一個社群維護的跨平台 conda 套件儲存庫。

若要在 Windows 上使用 conda-forge 作為 C++ 建置相依性,首先從 Miniconda 首頁 下載並安裝 64 位元發行版

若要設定 conda 預設使用 conda-forge 頻道,請啟動命令提示字元 (cmd.exe),執行 上方 顯示的初始化命令 (vcvarsall.batVsDevCmd.bat),然後執行命令

conda config --add channels conda-forge

現在,您可以啟動建置環境 (從 Arrow codebase 的根目錄呼叫)

conda create -y -n arrow-dev --file=ci\conda_env_cpp.txt

然後使用以下命令「啟用」此 conda 環境

activate arrow-dev

如果環境已啟用,Arrow 建置系統將自動看到 %CONDA_PREFIX% 環境變數,並使用它來解析建置相依性。這相當於設定

-DARROW_DEPENDENCY_SOURCE=SYSTEM ^
-DARROW_PACKAGE_PREFIX=%CONDA_PREFIX%\Library

若要將 Visual Studio IDE 與此已啟用的 conda 環境一起使用,請從相同的命令提示字元執行 devenv 命令來啟動它。

請注意,作為 conda 套件安裝的相依性是以發布模式建置的,無法與除錯建置連結。如果您打算使用 -DCMAKE_BUILD_TYPE=debug,則必須從原始碼建置套件。-DCMAKE_BUILD_TYPE=relwithdebinfo 也可用,它產生的建置既可以與發布函式庫連結,也可以進行除錯。

注意

如果您在使用 conda 套件作為相依性時遇到任何問題,一個非常常見的問題是混合來自 defaults 頻道和 conda-forge 的套件。您可以使用 conda list 檢查環境中已安裝的套件 (及其來源)

使用 vcpkg 作為建置相依性#

vcpkg 是 Microsoft 的一個開源套件管理器。它託管社群貢獻的 C 和 C++ 套件及其相依性的 ports。Arrow 包含一個 manifest 檔案 cpp/vcpkg.json,指定建置 C++ 函式庫所需的 vcpkg 套件。

若要在 Windows 上使用 vcpkg 作為 C++ 建置相依性,首先安裝整合 vcpkg。然後在 cmd.exe 中將工作目錄變更為 Arrow 的根目錄,並執行命令

vcpkg install ^
  --triplet x64-windows ^
  --x-manifest-root cpp  ^
  --feature-flags=versions ^
  --clean-after-build

在 Windows 上,vcpkg 預設建置動態連結函式庫。使用 triplet x64-windows-static 建置靜態函式庫。vcpkg 下載原始碼套件並在本機編譯它們,因此使用 vcpkg 安裝相依性比使用 conda 更耗時。

然後在您的 cmake 命令中,若要使用 vcpkg 安裝的相依性,請設定

-DARROW_DEPENDENCY_SOURCE=VCPKG

您可以選擇性地設定其他變數來覆寫 vcpkg 的預設 CMake 設定,包括

  • -DCMAKE_TOOLCHAIN_FILE:預設情況下,CMake 指令碼會自動尋找 vcpkg CMake toolchain 檔案 vcpkg.cmake 的位置;使用此選項來改為指定其位置

  • -DVCPKG_TARGET_TRIPLET:預設情況下,CMake 指令碼會嘗試推斷 vcpkg triplet;使用此選項來改為指定 triplet

  • -DARROW_DEPENDENCY_USE_SHARED:預設值為 ON;設定為 OFF 以使用靜態函式庫

  • -DVCPKG_MANIFEST_MODE:預設值為 ON;設定為 OFF 以忽略 vcpkg.json manifest 檔案,僅尋找 vcpkg 安裝目錄下已安裝的 vcpkg 套件

使用 Visual Studio (MSVC) 方案檔建置#

cmd.exe 中將工作目錄變更為 Arrow 的根目錄,並透過產生 MSVC 方案來進行 out of source build

cd cpp
mkdir build
cd build
cmake .. -G "Visual Studio 15 2017" -A x64 ^
      -DARROW_BUILD_TESTS=ON
cmake --build . --config Release

對於較新版本的 Visual Studio,請指定 generator Visual Studio 16 2019 或參閱 cmake --help 以取得可用的 generators。

使用 Ninja 和 sccache 建置#

Ninja 建置系統提供更好的建置平行化,而選用的 sccache 編譯器快取會追蹤過去的編譯,以避免重複執行它們 (以類似於 Unix 專用的 ccache 的方式)。

較新版本的 Visual Studio 包含 Ninja。若要查看您的 Visual Studio 是否包含 Ninja,請執行 上方 顯示的初始化命令 (vcvarsall.batVsDevCmd.bat),然後執行 ninja --version

如果您的 Visual Studio 版本未包含 Ninja,且您正在使用 conda,請啟用您的 conda 環境並安裝 Ninja

activate arrow-dev
conda install -c conda-forge ninja

如果您未使用 conda,請從其他來源安裝 Ninja

安裝完成後,在 cmd.exe 中將工作目錄變更為 Arrow 的根目錄,並透過產生 Ninja 檔案來進行 out of source build

cd cpp
mkdir build
cd build
cmake -G "Ninja" ^
      -DARROW_BUILD_TESTS=ON ^
      -DGTest_SOURCE=BUNDLED ..
cmake --build . --config Release

若要在本機儲存模式中使用 sccache,您需要在呼叫 cmake 之前設定 SCCACHE_DIR 環境變數

...
set SCCACHE_DIR=%LOCALAPPDATA%\Mozilla\sccache
cmake -G "Ninja" ^
...

使用 NMake 建置#

cmd.exe 中將工作目錄變更為 Arrow 的根目錄,並使用 nmake 進行 out of source build

cd cpp
mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake

在 MSYS2 上建置#

您可以在 MSYS2 終端機、cmd.exe 或 PowerShell 終端機上建置。

在 MSYS2 終端機上

cd cpp
mkdir build
cd build
cmake -G "MSYS Makefiles" ..
make

cmd.exe 或 PowerShell 終端機上,您可以使用以下批次檔

setlocal

REM For 64bit
set MINGW_PACKAGE_PREFIX=mingw-w64-x86_64
set MINGW_PREFIX=c:\msys64\mingw64
set MSYSTEM=MINGW64

set PATH=%MINGW_PREFIX%\bin;c:\msys64\usr\bin;%PATH%

rmdir /S /Q cpp\build
mkdir cpp\build
pushd cpp\build
cmake -G "MSYS Makefiles" .. || exit /B
make || exit /B
popd

在 Windows/ARM64 上使用 Ninja 和 Clang 建置#

Ninja 和 clang 可用於在 windows/arm64 平台上建置函式庫。

cd cpp
mkdir build
cd build

set CC=clang-cl
set CXX=clang-cl

cmake -G "Ninja" ..

cmake --build . --config Release

適用於 Windows on ARM64 的 LLVM toolchain 可以從 LLVM 發布頁面 LLVM 發布頁面 下載

由於 xsimd 和 boost 函式庫等相依性的相容性問題,Visual Studio (MSVC) 尚不能用於編譯 win/arm64 建置。

注意:這僅適用於 WoA64 的實驗性建置,因為由於缺乏基礎架構,並未透過 CI 廣泛測試所有功能。

除錯建置#

若要建置 Arrow 的 Debug 版本,您應預先安裝 Debug 版本的 Boost。建議使用以下變數設定 cmake 以進行 Debug 建置

  • -DARROW_BOOST_USE_SHARED=OFF:啟用與 boost debug libs 的靜態連結,並簡化第三方套件的執行階段載入

  • -DBOOST_ROOT:設定 boost libs 的根目錄。(選用)

  • -DBOOST_LIBRARYDIR:設定包含 boost lib 檔案的目錄。(選用)

以 Debug 模式建置 Arrow 的命令列看起來會像這樣

cd cpp
mkdir build
cd build
cmake .. -G "Visual Studio 15 2017" -A x64 ^
      -DARROW_BOOST_USE_SHARED=OFF ^
      -DCMAKE_BUILD_TYPE=Debug ^
      -DBOOST_ROOT=C:/local/boost_1_63_0  ^
      -DBOOST_LIBRARYDIR=C:/local/boost_1_63_0/lib64-msvc-14.0
cmake --build . --config Debug

Windows 相依性解析問題#

由於 Windows 將 .lib 檔案用於相依性的靜態和動態連結,因此靜態函式庫有時可能會被命名為不同的名稱,例如 %PACKAGE%_static.lib 以區分自己。如果您要靜態連結某些相依性,我們提供一些選項

  • -DBROTLI_MSVC_STATIC_LIB_SUFFIX=%BROTLI_SUFFIX%

  • -DSNAPPY_MSVC_STATIC_LIB_SUFFIX=%SNAPPY_SUFFIX%

  • -LZ4_MSVC_STATIC_LIB_SUFFIX=%LZ4_SUFFIX%

  • -ZSTD_MSVC_STATIC_LIB_SUFFIX=%ZSTD_SUFFIX%

若要取得最新的建置指示,您可以參考 ci/appveyor-built.bat,它由自動化的 Appveyor 建置使用。

在 Windows 上靜態連結到 Arrow#

Windows 靜態函式庫建置 (透過 CMake 選項 ARROW_BUILD_STATIC 啟用) 上的 Arrow 標頭使用預處理器巨集 ARROW_STATIC 來抑制符號的 dllimport/dllexport 標記。在 Windows 上靜態連結 Arrow 的專案還需要此定義。Unix 建置不使用此巨集。

此外,如果使用 -DARROW_FLIGHT=ON,則需要定義 ARROW_FLIGHT_STATIC,對於 -DARROW_FLIGHT_SQL=ON 也是如此。

project(MyExample)

find_package(Arrow REQUIRED)

add_executable(my_example my_example.cc)
target_link_libraries(my_example
                      PRIVATE
                      arrow_static
                      arrow_flight_static
                      arrow_flight_sql_static)

target_compile_definitions(my_example
                           PUBLIC
                           ARROW_STATIC
                           ARROW_FLIGHT_STATIC
                           ARROW_FLIGHT_SQL_STATIC)

下載時區資料庫#

若要在 Windows 上執行某些計算單元測試,需要先下載 IANA 時區資料庫和 Windows 時區對應。請參閱 執行階段相依性 以取得下載指示。若要在執行單元測試時設定時區資料庫的非預設路徑,請設定 ARROW_TIMEZONE_DATABASE 環境變數。

複製 Appveyor 建置#

對於更熟悉 linux 開發但需要複製失敗的 appveyor 建置的人員,以下是一些複製 Static_Crt_Build 的粗略筆記 (make unittest 可能仍然會失敗,但許多單元測試可以使用其個別的 make targets 進行)。

  1. Microsoft 提供 Windows with Microsoft Visual Studio 的試用版 VM。下載並安裝一個版本。

  2. 執行 VM 並安裝 GitCMake 和 Miniconda 或 Anaconda (這些指示假設為 Anaconda)。同時安裝 “Build Tools for Visual Studio”。請確保在安裝程式精靈中選取 C++ toolchain,並在安裝後重新啟動。

  3. 下載 預先建置的 Boost debug binaries 並安裝它。

    從 Anaconda/Miniconda 命令提示字元 (不是 PowerShell 提示字元) 執行此操作,並確保先執行 “vcvarsall.bat x64”。vcvarsall.bat 的位置將會有所不同,它可能位於與通常指示的路徑不同的路徑下,例如 “C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat”,使用 2019 建置工具。

cd $EXTRACT_BOOST_DIRECTORY
.\bootstrap.bat
@rem This is for static libraries needed for static_crt_build in appveyor
.\b2 link=static --with-filesystem --with-regex --with-system install
@rem this should put libraries and headers in c:\Boost
  1. 啟用 anaconda/miniconda

@rem this might differ for miniconda
C:\Users\User\Anaconda3\Scripts\activate
  1. 克隆並變更目錄到 arrow 原始碼 (您可能需要安裝 git)。

  2. 設定環境變數

@rem Change the build type based on which appveyor job you want.
SET JOB=Static_Crt_Build
SET GENERATOR=Ninja
SET APPVEYOR_BUILD_WORKER_IMAGE=Visual Studio 2017
SET USE_CLCACHE=false
SET ARROW_BUILD_GANDIVA=OFF
SET ARROW_LLVM_VERSION=8.0.*
SET PYTHON=3.9
SET ARCH=64
SET PATH=C:\Users\User\Anaconda3;C:\Users\User\Anaconda3\Scripts;C:\Users\User\Anaconda3\Library\bin;%PATH%
SET BOOST_LIBRARYDIR=C:\Boost\lib
SET BOOST_ROOT=C:\Boost
  1. 執行 appveyor 指令碼

conda install -c conda-forge --file .\ci\conda_env_cpp.txt
.\ci\appveyor-cpp-setup.bat
@rem this might fail but at this point most unit tests should be buildable by there individual targets
@rem see next line for example.
.\ci\appveyor-cpp-build.bat
@rem you can also just invoke cmake directly with the desired options
cmake --build . --config Release --target arrow-compute-hash-test