在 Windows 上进行开发#

与 Linux 和 macOS 一样,我们致力于让 CMake 在 Windows 上能够开箱即用地支持项目的大部分构建工作。

系统设置#

微软提供了免费的 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 是一个包含 conda 包管理器的最小化 Python 发行版。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 代码库的根目录下执行):

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

要在激活了此 conda 环境的情况下使用 Visual Studio IDE,请从同一个命令提示符通过运行 devenv 命令来启动它。

请注意,作为 conda 包安装的依赖项是以发布(Release)模式构建的,无法与调试(Debug)构建版本链接。如果您打算使用 -DCMAKE_BUILD_TYPE=debug,则必须从源代码构建这些包。您也可以使用 -DCMAKE_BUILD_TYPE=relwithdebinfo,它生成的构建版本既可以与发布版库链接,也可以进行调试。

注意

如果您在使用 conda 包作为依赖项时遇到任何问题,一个非常常见的原因是将 defaults 通道的包与 conda-forge 的包混合使用。您可以使用 conda list 查看环境中安装的包(及其来源)。

使用 vcpkg 进行构建依赖管理#

vcpkg 是微软推出的开源包管理器。它托管了社区贡献的 C 和 C++ 包及其依赖项。Arrow 包含一个清单文件 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 默认构建动态链接库。若要构建静态库,请使用 x64-windows-static 三元组(triplet)。vcpkg 会下载源代码包并在本地进行编译,因此使用 vcpkg 安装依赖项比使用 conda 更耗时。

然后,在您的 cmake 命令中,要使用由 vcpkg 安装的依赖项,请设置:

-DARROW_DEPENDENCY_SOURCE=VCPKG

您可以选择设置其他变量以覆盖 vcpkg 的默认 CMake 配置,包括:

  • -DCMAKE_TOOLCHAIN_FILE:默认情况下,CMake 脚本会自动查找 vcpkg CMake 工具链文件 vcpkg.cmake 的位置;使用此选项可手动指定其位置。

  • -DVCPKG_TARGET_TRIPLET:默认情况下,CMake 脚本会尝试推断 vcpkg 三元组;使用此选项可手动指定。

  • -DARROW_DEPENDENCY_USE_SHARED:默认为 ON;设置为 OFF 以使用静态库。

  • -DVCPKG_MANIFEST_MODE:默认为 ON;设置为 OFF 以忽略 vcpkg.json 清单文件,仅查找已安装在 vcpkg 目录下的 vcpkg 包。

使用 Visual Studio (MSVC) 解决方案文件构建#

cmd.exe 中将工作目录更改为 Arrow 的根目录,并通过生成 MSVC 解决方案来进行源码外(out-of-source)构建:

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

对于较新版本的 Visual Studio,请指定生成器 Visual Studio 17 2022,或通过 cmake --help 查看可用的生成器。

使用 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 文件来进行源码外构建:

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 进行源码外构建。

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 工具链可以从 LLVM 发布页面下载。

由于 xsimd 和 boost 库等依赖项的兼容性问题,目前尚无法使用 Visual Studio (MSVC) 来编译 win/arm64 版本。

注意:这仅是 WoA64 的实验性构建版本,由于缺乏基础设施,并非所有功能都经过了 CI 的全面测试。

调试(Debug)构建#

要构建 Arrow 的 Debug 版本,您需要预先安装 Boost 的 Debug 版本。建议使用以下变量配置 cmake 进行 Debug 构建:

  • -DARROW_BOOST_USE_SHARED=OFF:启用与 Boost 调试库的静态链接,并简化第三方库的运行时加载。

  • -DBOOST_ROOT:设置 Boost 库的根目录(可选)。

  • -DBOOST_LIBRARYDIR:设置包含 Boost 库文件的目录(可选)。

在 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

根据您使用的 CMake 变量或预设,您可能需要在 PATH 中配置 patch 工具。有多种方法可以做到这一点。例如,如果您已经在使用 Git for Windows,您可以将 C:\Program Files\Git\usr\bin 添加到您的 PATH 中。

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%

在 Windows 上静态链接到 Arrow#

Windows 静态库构建中的 Arrow 头文件(通过 CMake 选项 ARROW_BUILD_STATIC 启用)使用预处理器宏 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)

下载时区数据库#

当使用 MSVC 或较新的 MinGW GCC(版本 13+)构建时,Arrow 分别使用 Windows 时区数据库或系统提供的 tzdata,无需额外设置。

当使用 Clang/libc++(例如 MSYS2 Clang64)构建时,需要先下载 IANA 时区数据库和 Windows 时区映射,以便运行某些计算单元测试。请参阅 运行时依赖项获取下载说明。要在运行单元测试时设置非默认的时区数据库路径,请设置 ARROW_TIMEZONE_DATABASE 环境变量。

复现 Windows CI 构建#

对于更熟悉 Linux 开发但需要复现失败的 Windows CI 构建的用户,这里是一些简要说明(make unittest 可能仍然会失败,但许多单元测试可以通过其各自的 make 目标来完成)。

  1. 微软提供用于 Windows with Microsoft Visual Studio 的试用虚拟机。下载并安装一个版本。

  2. 运行虚拟机并安装 GitCMake 以及 Miniconda 或 Anaconda(这些说明假设使用 Anaconda)。同时安装 “Build Tools for Visual Studio”。确保在安装向导中选择 C++ 工具链,并在安装后重新启动。

  3. 下载 预构建的 Boost 调试二进制文件并安装。

    在 Anaconda/Miniconda 命令提示符(*不是* PowerShell 提示符)下运行此操作,并确保先运行“vcvarsall.bat x64”。vcvarsall.bat 的位置取决于具体情况,可能与通常指示的路径不同,例如使用 2019 构建工具时位于“C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat”。

cd $EXTRACT_BOOST_DIRECTORY
.\bootstrap.bat
@rem This is for static libraries needed for static_crt_build
.\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. 设置环境变量。

SET JOB=Static_Crt_Build
SET GENERATOR=Ninja
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. 安装依赖项并构建。

conda install -c conda-forge --file .\ci\conda_env_cpp.txt
git submodule update --init
@rem you can also just invoke cmake directly with the desired options
cmake --build . --config Release --target arrow-compute-hash-test