This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 6d3d91caf build: package wheels for Windows/ARM (#4691)
6d3d91caf is described below
commit 6d3d91cafd0659e1594941ffafb08f1a38403fd5
Author: David Li <[email protected]>
AuthorDate: Tue Aug 25 15:37:59 2026 +0900
build: package wheels for Windows/ARM (#4691)
Closes #4684.
Assisted-by: GPT-5.6 Sol <[email protected]>
---
.github/workflows/java.yml | 8 +-
.github/workflows/packaging.yml | 191 +++++++++++++++++++---
LICENSE.txt | 3 +-
c/vendor/backward/backward.hpp | 40 ++++-
ci/scripts/python_wheel_windows_build.bat | 96 -----------
ci/scripts/python_wheel_windows_build_drivers.ps1 | 127 ++++++++++++++
ci/scripts/python_wheel_windows_build_manager.ps1 | 56 +++++++
ci/scripts/python_wheel_windows_test.bat | 41 -----
ci/scripts/python_wheel_windows_test.ps1 | 102 ++++++++++++
python/adbc_driver_flightsql/LICENSE.txt | 5 +-
python/adbc_driver_postgresql/LICENSE.txt | 5 +-
python/adbc_driver_sqlite/LICENSE.txt | 5 +-
12 files changed, 503 insertions(+), 176 deletions(-)
diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml
index 6b3a956da..8f418b7e0 100644
--- a/.github/workflows/java.yml
+++ b/.github/workflows/java.yml
@@ -159,10 +159,12 @@ jobs:
./ci/scripts/python_wheel_unix_build.sh ${{ matrix.arch }} $(pwd)
$(pwd)/build
- name: Build artifacts (Windows)
if: matrix.os == 'Windows'
- # TODO(https://github.com/apache/arrow-adbc/issues/4269): remove
cmd.exe usage
- shell: cmd # zizmor: ignore[misfeature]
+ shell: pwsh
run: |
- .\ci\scripts\python_wheel_windows_build.bat %cd% %cd%\build\${{
matrix.vcpkg_arch }}
+ .\ci\scripts\python_wheel_windows_build_drivers.ps1 `
+ -SourceDir $PWD.Path `
+ -BuildDir (Join-Path $PWD.Path "build/${{ matrix.vcpkg_arch }}") `
+ -Architecture "amd64"
- name: Build driver manager (Windows)
if: matrix.os == 'Windows'
diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml
index 78f27d153..2d44d140b 100644
--- a/.github/workflows/packaging.yml
+++ b/.github/workflows/packaging.yml
@@ -952,16 +952,18 @@ jobs:
path: ~/logs
python-windows:
- name: "Python ${{ matrix.python_version }} Windows"
- runs-on: windows-latest
+ name: "Python ${{ matrix.arch }} Windows"
+ runs-on: ${{ matrix.runner }}
needs:
- source
strategy:
fail-fast: false
matrix:
- python_version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
+ include:
+ - { arch: amd64, python_arch: x64, runner: windows-latest }
+ - { arch: arm64, python_arch: arm64, runner: windows-11-vs2026-arm }
env:
- PYTHON_VERSION: "${{ matrix.python_version }}"
+ VCPKG_DEFAULT_TRIPLET: ${{ matrix.python_arch }}-windows-static-release
VCPKG_ROOT: "${{ github.workspace }}/vcpkg"
steps:
- uses:
actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -999,6 +1001,26 @@ jobs:
choco install --no-progress -y cmake --installargs
'ADD_CMAKE_TO_PATH=System'
choco install --no-progress -y visualcpp-build-tools
+ - name: Install MSYS2
+ if: matrix.arch == 'arm64'
+ id: msys2
+ uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 #
v2.32.0
+ with:
+ msystem: CLANGARM64
+ update: true
+ install: |
+ mingw-w64-clang-aarch64-gcc-compat
+ mingw-w64-clang-aarch64-tools
+
+ - name: Add MSYS2 toolchain to PATH
+ if: matrix.arch == 'arm64'
+ env:
+ MSYS_LOCATION: ${{ steps.msys2.outputs.msys2-location }}
+ shell: pwsh
+ run: |
+ "$env:MSYS_LOCATION\clangarm64\bin" |
+ Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+
- name: Install vcpkg
shell: bash
run: |
@@ -1009,28 +1031,117 @@ jobs:
with:
go-version: "${{ env.GO_VERSION }}"
check-latest: true
- cache: false
+ cache: false # disable to protect against cache poisoning
cache-dependency-path: adbc/go/adbc/go.sum
- - name: Install Python ${{ matrix.python_version }}
+ - name: Install Python 3.10
+ if: matrix.arch == 'amd64'
+ id: python310
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 #
v7.0.0
with:
+ architecture: ${{ matrix.python_arch }}
check-latest: true
- python-version: ${{ matrix.python_version }}
+ python-version: "3.10"
+ update-environment: false
- - name: Build wheel
- # TODO(https://github.com/apache/arrow-adbc/issues/4269): remove
cmd.exe usage
- shell: cmd # zizmor: ignore[misfeature]
- run: |
- pushd adbc
- set SETUPTOOLS_SCM_PRETEND_VERSION=%VERSION%
- .\ci\scripts\python_wheel_windows_build.bat %cd% %cd%\build
- popd
+ - name: Install Python 3.11
+ id: python311
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 #
v7.0.0
+ with:
+ architecture: ${{ matrix.python_arch }}
+ check-latest: true
+ python-version: "3.11"
+ update-environment: false
+
+ - name: Install Python 3.12
+ id: python312
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 #
v7.0.0
+ with:
+ architecture: ${{ matrix.python_arch }}
+ check-latest: true
+ python-version: "3.12"
+ update-environment: false
+
+ - name: Install Python 3.13
+ id: python313
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 #
v7.0.0
+ with:
+ architecture: ${{ matrix.python_arch }}
+ check-latest: true
+ python-version: "3.13"
+ update-environment: false
+
+ - name: Install Python 3.14
+ id: python314
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 #
v7.0.0
+ with:
+ architecture: ${{ matrix.python_arch }}
+ check-latest: true
+ python-version: "3.14"
+ update-environment: false
+
+ - name: Install Python 3.14t
+ id: python314t
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 #
v7.0.0
+ with:
+ architecture: ${{ matrix.python_arch }}
+ check-latest: true
+ python-version: "3.14t"
+ update-environment: false
+
+ - name: Build driver wheels
+ shell: pwsh
+ env:
+ PYTHON_PATH: ${{ steps.python311.outputs.python-path }}
+ SETUPTOOLS_SCM_PRETEND_VERSION: ${{ env.VERSION }}
+ run: |
+ $PythonDir = Split-Path $env:PYTHON_PATH
+ $env:PATH = "$PythonDir;$env:PATH"
+ Set-Location adbc
+ .\ci\scripts\python_wheel_windows_build_drivers.ps1 `
+ -SourceDir $PWD.Path `
+ -BuildDir (Join-Path $PWD.Path "build") `
+ -Architecture "${{ matrix.arch }}"
+ if (-not $?) { throw "Failed to build driver wheels" }
+
+ - name: Build driver manager wheels
+ shell: pwsh
+ env:
+ PYTHON_310: ${{ steps.python310.outputs.python-path }}
+ PYTHON_311: ${{ steps.python311.outputs.python-path }}
+ PYTHON_312: ${{ steps.python312.outputs.python-path }}
+ PYTHON_313: ${{ steps.python313.outputs.python-path }}
+ PYTHON_314: ${{ steps.python314.outputs.python-path }}
+ PYTHON_314T: ${{ steps.python314t.outputs.python-path }}
+ SETUPTOOLS_SCM_PRETEND_VERSION: ${{ env.VERSION }}
+ run: |
+ $OriginalPath = $env:PATH
+ $Pythons = @(
+ @{ Version = "3.10"; Path = $env:PYTHON_310 },
+ @{ Version = "3.11"; Path = $env:PYTHON_311 },
+ @{ Version = "3.12"; Path = $env:PYTHON_312 },
+ @{ Version = "3.13"; Path = $env:PYTHON_313 },
+ @{ Version = "3.14"; Path = $env:PYTHON_314 },
+ @{ Version = "3.14t"; Path = $env:PYTHON_314T }
+ )
+ Set-Location adbc
+ foreach ($Python in $Pythons) {
+ if ([string]::IsNullOrEmpty($Python.Path)) {
+ continue
+ }
+ Write-Host "::group::Building driver manager for Python
$($Python.Version)"
+ $env:PYTHON_VERSION = $Python.Version
+ $PythonDir = Split-Path $Python.Path
+ $env:PATH = "$PythonDir;$OriginalPath"
+ .\ci\scripts\python_wheel_windows_build_manager.ps1 -SourceDir
$PWD.Path
+ if (-not $?) { throw "Failed to build the Python
$($Python.Version) driver manager wheel" }
+ Write-Host "::endgroup::"
+ }
- name: Archive wheels
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
# v7.0.1
with:
- name: python${{ matrix.python_version }}-windows
+ name: python-windows-${{ matrix.arch }}
retention-days: 7
path: |
adbc/python/adbc_driver_flightsql/repaired_wheels/*.whl
@@ -1040,17 +1151,45 @@ jobs:
adbc/build/**/*.pdb
- name: Test wheel
- # TODO(https://github.com/apache/arrow-adbc/issues/4269): remove
cmd.exe usage
- shell: cmd # zizmor: ignore[misfeature]
+ shell: pwsh
env:
- PYTHON_VERSION: ${{ matrix.python_version }}
- run: |
- pushd adbc
- where python.exe
- python -m venv venv
- CALL venv\Scripts\activate.bat
- .\ci\scripts\python_wheel_windows_test.bat %cd%
- popd
+ PYTHON_310: ${{ steps.python310.outputs.python-path }}
+ PYTHON_311: ${{ steps.python311.outputs.python-path }}
+ PYTHON_312: ${{ steps.python312.outputs.python-path }}
+ PYTHON_313: ${{ steps.python313.outputs.python-path }}
+ PYTHON_314: ${{ steps.python314.outputs.python-path }}
+ PYTHON_314T: ${{ steps.python314t.outputs.python-path }}
+ run: |
+ $DriverDir = Join-Path $PWD "adbc/build/bin"
+ $OriginalPath = "$DriverDir;$env:PATH"
+ $Pythons = @(
+ @{ Version = "3.10"; Path = $env:PYTHON_310 },
+ @{ Version = "3.11"; Path = $env:PYTHON_311 },
+ @{ Version = "3.12"; Path = $env:PYTHON_312 },
+ @{ Version = "3.13"; Path = $env:PYTHON_313 },
+ @{ Version = "3.14"; Path = $env:PYTHON_314 },
+ @{ Version = "3.14t"; Path = $env:PYTHON_314T }
+ )
+ Set-Location adbc
+ foreach ($Python in $Pythons) {
+ if ([string]::IsNullOrEmpty($Python.Path)) {
+ continue
+ }
+ Write-Host "::group::Testing wheels with Python $($Python.Version)"
+ $env:PYTHON_VERSION = $Python.Version
+ $PythonDir = Split-Path $Python.Path
+ $env:PATH = "$PythonDir;$OriginalPath"
+ $VenvDir = Join-Path $env:RUNNER_TEMP
"adbc-wheel-test-$($Python.Version)"
+ python -m venv $VenvDir
+ if (-not $?) { throw "Failed to create the Python
$($Python.Version) test environment" }
+ $env:PATH = "$(Join-Path $VenvDir 'Scripts');$env:PATH"
+ .\ci\scripts\python_wheel_windows_test.ps1 `
+ -SourceDir $PWD.Path `
+ -Architecture "${{ matrix.arch }}"
+ if (-not $?) { throw "Failed to test the Python $($Python.Version)
wheels" }
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $VenvDir
+ Write-Host "::endgroup::"
+ }
python-sdist:
name: "Python sdist"
diff --git a/LICENSE.txt b/LICENSE.txt
index 6e1393ec3..836f349e2 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
backward-cpp has the following license:
Copyright 2013 Google Inc. All Rights Reserved.
diff --git a/c/vendor/backward/backward.hpp b/c/vendor/backward/backward.hpp
index a42c481c7..bab33dd57 100644
--- a/c/vendor/backward/backward.hpp
+++ b/c/vendor/backward/backward.hpp
@@ -954,7 +954,7 @@ public:
reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_EIP]);
++index;
ctx = *reinterpret_cast<unw_context_t *>(uctx);
-#elif defined(__arm__)
+#elif defined(__arm__) // clang libunwind/arm
// libunwind uses its own context type for ARM unwinding.
// Copy the registers from the signal handler's context so we can
// unwind
@@ -985,6 +985,24 @@ public:
}
_stacktrace[index] = reinterpret_cast<void *>(ctx.regs[UNW_ARM_R15]);
++index;
+#elif defined(__aarch64__) // gcc libunwind/arm64
+ unw_getcontext(&ctx);
+ // If the IP is the same as the crash address we have a bad function
+ // dereference The caller's address is pointed to by the link pointer, so
+ // we dereference that value and set it to be the next frame's IP.
+ if (uctx->uc_mcontext.pc == reinterpret_cast<__uint64_t>(error_addr())) {
+ uctx->uc_mcontext.pc = uctx->uc_mcontext.regs[UNW_TDEP_IP];
+ }
+
+ // 29 general purpose registers
+ for (int i = UNW_AARCH64_X0; i <= UNW_AARCH64_X28; i++) {
+ ctx.uc_mcontext.regs[i] = uctx->uc_mcontext.regs[i];
+ }
+ ctx.uc_mcontext.sp = uctx->uc_mcontext.sp;
+ ctx.uc_mcontext.pc = uctx->uc_mcontext.pc;
+ ctx.uc_mcontext.fault_address = uctx->uc_mcontext.fault_address;
+ _stacktrace[index] = reinterpret_cast<void *>(ctx.uc_mcontext.pc);
+ ++index;
#elif defined(__APPLE__) && defined(__x86_64__)
unw_getcontext(&ctx);
// OS X's implementation of libunwind uses its own context object
@@ -1160,10 +1178,18 @@ public:
s.AddrStack.Mode = AddrModeFlat;
s.AddrFrame.Mode = AddrModeFlat;
s.AddrPC.Mode = AddrModeFlat;
-#ifdef _M_X64
+#if defined(_M_X64)
s.AddrPC.Offset = ctx_->Rip;
s.AddrStack.Offset = ctx_->Rsp;
s.AddrFrame.Offset = ctx_->Rbp;
+#elif defined(_M_ARM64)
+ s.AddrPC.Offset = ctx_->Pc;
+ s.AddrStack.Offset = ctx_->Sp;
+ s.AddrFrame.Offset = ctx_->Fp;
+#elif defined(_M_ARM)
+ s.AddrPC.Offset = ctx_->Pc;
+ s.AddrStack.Offset = ctx_->Sp;
+ s.AddrFrame.Offset = ctx_->R11;
#else
s.AddrPC.Offset = ctx_->Eip;
s.AddrStack.Offset = ctx_->Esp;
@@ -1171,8 +1197,12 @@ public:
#endif
if (!machine_type_) {
-#ifdef _M_X64
+#if defined(_M_X64)
machine_type_ = IMAGE_FILE_MACHINE_AMD64;
+#elif defined(_M_ARM64)
+ machine_type_ = IMAGE_FILE_MACHINE_ARM64;
+#elif defined(_M_ARM)
+ machine_type_ = IMAGE_FILE_MACHINE_ARMNT;
#else
machine_type_ = IMAGE_FILE_MACHINE_I386;
#endif
@@ -4260,6 +4290,8 @@ public:
#elif defined(__mips__)
error_addr = reinterpret_cast<void *>(
reinterpret_cast<struct sigcontext *>(&uctx->uc_mcontext)->sc_pc);
+#elif defined(__APPLE__) && defined(__POWERPC__)
+ error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__srr0);
#elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) ||
\
defined(__POWERPC__)
error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.regs->nip);
@@ -4271,6 +4303,8 @@ public:
error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__rip);
#elif defined(__APPLE__)
error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__eip);
+#elif defined(__loongarch__)
+ error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.__pc);
#else
#warning ":/ sorry, ain't know no nothing none not of your architecture!"
#endif
diff --git a/ci/scripts/python_wheel_windows_build.bat
b/ci/scripts/python_wheel_windows_build.bat
deleted file mode 100644
index 0a81ea792..000000000
--- a/ci/scripts/python_wheel_windows_build.bat
+++ /dev/null
@@ -1,96 +0,0 @@
-@rem Licensed to the Apache Software Foundation (ASF) under one
-@rem or more contributor license agreements. See the NOTICE file
-@rem distributed with this work for additional information
-@rem regarding copyright ownership. The ASF licenses this file
-@rem to you under the Apache License, Version 2.0 (the
-@rem "License"); you may not use this file except in compliance
-@rem with the License. You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing,
-@rem software distributed under the License is distributed on an
-@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@rem KIND, either express or implied. See the License for the
-@rem specific language governing permissions and limitations
-@rem under the License.
-
-@echo on
-
-set source_dir=%1
-set build_dir=%2
-
-echo "=== (%PYTHON_VERSION%) Building ADBC libpq driver ==="
-
-set CMAKE_BUILD_TYPE=RelWithDebInfo
-set CMAKE_GENERATOR=Visual Studio 18 2026
-set CMAKE_GENERATOR_PLATFORM=x64
-set CMAKE_UNITY_BUILD=ON
-set VCPKG_FEATURE_FLAGS=-manifests
-set VCPKG_TARGET_TRIPLET=x64-windows-static
-set VCPKG_DEFAULT_HOST_TRIPLET=x64-windows-static
-
-IF NOT DEFINED VCPKG_ROOT (echo "Must set VCPKG_ROOT" && exit /B 1)
-IF NOT DEFINED ADBC_BUILD_STATIC SET ADBC_BUILD_STATIC=OFF
-
-%VCPKG_ROOT%\vcpkg install --triplet=%VCPKG_TARGET_TRIPLET% libpq
"sqlite3[dbstat,fts3,fts4,fts5,geopoly,json1,limit,math,rtree,session,snapshot,soundex]"
-IF %errorlevel% NEQ 0 EXIT /B %errorlevel%
-
-mkdir %build_dir%
-pushd %build_dir%
-
-cmake ^
- -G "%CMAKE_GENERATOR%" ^
- -A "%CMAKE_GENERATOR_PLATFORM%" ^
- -DADBC_BUILD_SHARED=ON ^
- -DADBC_BUILD_STATIC=%ADBC_BUILD_STATIC% ^
- -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% ^
- -DCMAKE_INSTALL_PREFIX=%build_dir% ^
- -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake ^
- -DCMAKE_UNITY_BUILD=%CMAKE_UNITY_BUILD% ^
- -DVCPKG_TARGET_TRIPLET=%VCPKG_TARGET_TRIPLET% ^
- -DADBC_DRIVER_FLIGHTSQL=ON ^
- -DADBC_DRIVER_MANAGER=ON ^
- -DADBC_DRIVER_POSTGRESQL=ON ^
- -DADBC_DRIVER_SQLITE=ON ^
- %source_dir%\c || exit /B 1
-
-cmake --build . --config %CMAKE_BUILD_TYPE% --target install --verbose -j ||
exit /B 1
-
-set ADBC_FLIGHTSQL_LIBRARY=%build_dir%\bin\adbc_driver_flightsql.dll
-set ADBC_POSTGRESQL_LIBRARY=%build_dir%\bin\adbc_driver_postgresql.dll
-set ADBC_SQLITE_LIBRARY=%build_dir%\bin\adbc_driver_sqlite.dll
-
-# Build with Cython debug info
-set ADBC_BUILD_TYPE=debug
-
-popd
-
-python -m pip install --upgrade pip delvewheel wheel || exit /B 1
-
-FOR /F %%i IN ('python -c "import sysconfig;
print(sysconfig.get_platform())"') DO set PLAT_NAME=%%i
-
-FOR %%c IN (adbc_driver_manager adbc_driver_flightsql adbc_driver_postgresql
adbc_driver_sqlite) DO (
- pushd %source_dir%\python\%%c
-
- echo "=== (%PYTHON_VERSION%) Checking %%c version ==="
- python %%c\_version.py || exit /B 1
-
- echo "=== (%PYTHON_VERSION%) Building %%c wheel ==="
- python -m pip wheel --no-deps -w dist -vvv . || exit /B 1
-
- echo "=== (%PYTHON_VERSION%) Re-tag %%c wheel ==="
- FOR %%w IN (dist\*.whl) DO (
- python %source_dir%\ci\scripts\python_wheel_fix_tag.py %%w || exit /B 1
- )
-
- echo "=== (%PYTHON_VERSION%) Repair %%c wheel ==="
- REM Always copy the wheel once since delvewheel doesn't copy if no changes
needed
- mkdir repaired_wheels
- FOR %%w IN (dist\*.whl) DO (
- copy %%w repaired_wheels\
- delvewheel repair -w repaired_wheels\ %%w || exit /B 1
- )
-
- popd
-)
diff --git a/ci/scripts/python_wheel_windows_build_drivers.ps1
b/ci/scripts/python_wheel_windows_build_drivers.ps1
new file mode 100755
index 000000000..6f67840fc
--- /dev/null
+++ b/ci/scripts/python_wheel_windows_build_drivers.ps1
@@ -0,0 +1,127 @@
+#!/usr/bin/env pwsh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$SourceDir,
+ [Parameter(Mandatory = $true)]
+ [string]$BuildDir,
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("amd64", "arm64")]
+ [string]$Architecture
+)
+
+$ErrorActionPreference = "Stop"
+
+if (-not $env:VCPKG_ROOT) {
+ throw "Must set VCPKG_ROOT"
+}
+
+if ($Architecture -eq "amd64") {
+ $CMakePlatform = "x64"
+ $PlatformTag = "win_amd64"
+ $VcpkgTriplet = "x64-windows-static-release"
+} else {
+ $CMakePlatform = "ARM64"
+ $PlatformTag = "win_arm64"
+ $VcpkgTriplet = "arm64-windows-static-release"
+}
+
+$BuildType = "RelWithDebInfo"
+$env:VCPKG_FEATURE_FLAGS = "-manifests"
+$env:VCPKG_TARGET_TRIPLET = $VcpkgTriplet
+$env:VCPKG_DEFAULT_HOST_TRIPLET = $VcpkgTriplet
+
+Write-Host "=== Building ADBC drivers for $Architecture ==="
+
+& (Join-Path $env:VCPKG_ROOT "vcpkg.exe") install `
+ "--triplet=$VcpkgTriplet" `
+ "libpq" `
+
"sqlite3[dbstat,fts3,fts4,fts5,geopoly,json1,limit,math,rtree,session,snapshot,soundex]"
`
+ --overlay-triplets $(Join-Path $SourceDir "ci\vcpkg\triplets")
+if (-not $?) { throw "Failed to install vcpkg dependencies" }
+
+New-Item -ItemType Directory -Force -Path $BuildDir | Out-Null
+
+cmake `
+ -S (Join-Path $SourceDir "c") `
+ -B $BuildDir `
+ -G "Visual Studio 18 2026" `
+ -A $CMakePlatform `
+ -DADBC_BUILD_SHARED=ON `
+ "-DCMAKE_BUILD_TYPE=$BuildType" `
+ "-DCMAKE_INSTALL_PREFIX=$BuildDir" `
+ "-DCMAKE_TOOLCHAIN_FILE=$(Join-Path $env:VCPKG_ROOT
'scripts/buildsystems/vcpkg.cmake')" `
+ -DCMAKE_UNITY_BUILD=ON `
+ "-DVCPKG_OVERLAY_TRIPLETS=$(Join-Path $SourceDir 'ci\vcpkg\triplets')" `
+ "-DVCPKG_TARGET_TRIPLET=$VcpkgTriplet" `
+ -DADBC_DRIVER_FLIGHTSQL=ON `
+ -DADBC_DRIVER_MANAGER=ON `
+ -DADBC_DRIVER_POSTGRESQL=ON `
+ -DADBC_DRIVER_SQLITE=ON
+if (-not $?) { throw "Failed to configure the CMake build" }
+
+cmake --build $BuildDir --config $BuildType --target install --verbose -j
+if (-not $?) { throw "Failed to build and install the CMake project" }
+
+$env:ADBC_FLIGHTSQL_LIBRARY = Join-Path $BuildDir
"bin/adbc_driver_flightsql.dll"
+$env:ADBC_POSTGRESQL_LIBRARY = Join-Path $BuildDir
"bin/adbc_driver_postgresql.dll"
+$env:ADBC_SQLITE_LIBRARY = Join-Path $BuildDir "bin/adbc_driver_sqlite.dll"
+
+python -m pip install --upgrade pip delvewheel wheel
+if (-not $?) { throw "Failed to install Python build dependencies" }
+
+$env:ADBC_BUILD_TYPE = "debug"
+$Components = @(
+ "adbc_driver_flightsql",
+ "adbc_driver_postgresql",
+ "adbc_driver_sqlite"
+)
+
+foreach ($Component in $Components) {
+ $ComponentDir = Join-Path $SourceDir "python/$Component"
+ Push-Location $ComponentDir
+ try {
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue build, dist,
repaired_wheels
+
+ Write-Host "=== Checking $Component version ==="
+ python "$Component/_version.py"
+ if (-not $?) { throw "Failed to check the $Component version" }
+
+ Write-Host "=== Building $Component wheel ==="
+ python -m pip wheel --no-deps -w dist -vvv .
+ if (-not $?) { throw "Failed to build the $Component wheel" }
+
+ $Wheels = @(Get-ChildItem -Path "dist/*.whl")
+ foreach ($Wheel in $Wheels) {
+ python (Join-Path $SourceDir "ci/scripts/python_wheel_fix_tag.py")
`
+ "--plat-name=$PlatformTag" $Wheel.FullName
+ if (-not $?) { throw "Failed to update the $Component wheel tag" }
+ }
+
+ New-Item -ItemType Directory -Force -Path repaired_wheels | Out-Null
+ $Wheels = @(Get-ChildItem -Path "dist/*.whl")
+ foreach ($Wheel in $Wheels) {
+ Copy-Item $Wheel.FullName repaired_wheels
+ python -m delvewheel repair -w repaired_wheels $Wheel.FullName
+ if (-not $?) { throw "Failed to repair the $Component wheel" }
+ }
+ } finally {
+ Pop-Location
+ }
+}
diff --git a/ci/scripts/python_wheel_windows_build_manager.ps1
b/ci/scripts/python_wheel_windows_build_manager.ps1
new file mode 100755
index 000000000..a5c7559eb
--- /dev/null
+++ b/ci/scripts/python_wheel_windows_build_manager.ps1
@@ -0,0 +1,56 @@
+#!/usr/bin/env pwsh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$SourceDir
+)
+
+$ErrorActionPreference = "Stop"
+$Component = "adbc_driver_manager"
+$ComponentDir = Join-Path $SourceDir "python/$Component"
+$TemporaryWheelDir = Join-Path $ComponentDir "temp_wheels"
+
+python -m pip install --upgrade pip delvewheel wheel
+if (-not $?) { throw "Failed to install Python build dependencies" }
+
+$env:ADBC_BUILD_TYPE = "debug"
+
+Push-Location $ComponentDir
+try {
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue build,
$TemporaryWheelDir
+
+ Write-Host "=== Checking $Component version ==="
+ python "$Component/_version.py"
+ if (-not $?) { throw "Failed to check the $Component version" }
+
+ Write-Host "=== Building $Component wheel ==="
+ python -m pip wheel --no-deps -w $TemporaryWheelDir -vvv .
+ if (-not $?) { throw "Failed to build the $Component wheel" }
+
+ New-Item -ItemType Directory -Force -Path repaired_wheels | Out-Null
+ $Wheels = @(Get-ChildItem -Path "$TemporaryWheelDir/*.whl")
+ foreach ($Wheel in $Wheels) {
+ Copy-Item $Wheel.FullName repaired_wheels
+ python -m delvewheel repair -w repaired_wheels $Wheel.FullName
+ if (-not $?) { throw "Failed to repair the $Component wheel" }
+ }
+} finally {
+ Pop-Location
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
$TemporaryWheelDir
+}
diff --git a/ci/scripts/python_wheel_windows_test.bat
b/ci/scripts/python_wheel_windows_test.bat
deleted file mode 100644
index 78e60681f..000000000
--- a/ci/scripts/python_wheel_windows_test.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-@rem Licensed to the Apache Software Foundation (ASF) under one
-@rem or more contributor license agreements. See the NOTICE file
-@rem distributed with this work for additional information
-@rem regarding copyright ownership. The ASF licenses this file
-@rem to you under the Apache License, Version 2.0 (the
-@rem "License"); you may not use this file except in compliance
-@rem with the License. You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing,
-@rem software distributed under the License is distributed on an
-@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@rem KIND, either express or implied. See the License for the
-@rem specific language governing permissions and limitations
-@rem under the License.
-
-@echo on
-
-set source_dir=%1
-
-echo "=== (%PYTHON_VERSION%) Installing wheels ==="
-
-FOR %%c IN (adbc_driver_manager adbc_driver_flightsql adbc_driver_postgresql
adbc_driver_sqlite) DO (
- FOR %%w IN (%source_dir%\python\%%c\dist\*.whl) DO (
- pip install --no-deps --force-reinstall %%w || exit /B 1
- )
-)
-
-pip install pytest pyarrow pandas protobuf
-
-echo "=== (%PYTHON_VERSION%) Testing wheels ==="
-
-IF [%PYTHON_VERSION:~-1%]==[t] SET PYTHON_GIL=0
-
-FOR %%c IN (adbc_driver_manager adbc_driver_flightsql adbc_driver_postgresql
adbc_driver_sqlite) DO (
- echo "=== Testing %%c ==="
- python -c "import %%c" || exit /B 1
- python -c "import %%c.dbapi" || exit /B 1
- python -m pytest -vvx --import-mode append -k "not duckdb and not sqlite
and not polars" %source_dir%\python\%%c\tests || exit /B 1
-)
diff --git a/ci/scripts/python_wheel_windows_test.ps1
b/ci/scripts/python_wheel_windows_test.ps1
new file mode 100755
index 000000000..2c1a525be
--- /dev/null
+++ b/ci/scripts/python_wheel_windows_test.ps1
@@ -0,0 +1,102 @@
+#!/usr/bin/env pwsh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$SourceDir,
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("amd64", "arm64")]
+ [string]$Architecture
+)
+
+$ErrorActionPreference = "Stop"
+$Components = @(
+ "adbc_driver_manager",
+ "adbc_driver_flightsql",
+ "adbc_driver_postgresql",
+ "adbc_driver_sqlite"
+)
+$PythonTag = python -c "import sysconfig; print('cp' +
sysconfig.get_python_version().replace('.', ''))"
+if (-not $?) { throw "Failed to determine the Python tag" }
+# https://github.com/python/cpython/issues/127405: unlike Unix, Windows does
not
+# expose free-threading through abiflags, so use Py_GIL_DISABLED instead.
+$PythonFlags = python -c "import sysconfig; print('t' if
sysconfig.get_config_var('Py_GIL_DISABLED') else '')"
+if (-not $?) { throw "Failed to determine whether Python is free-threaded" }
+$PythonTag = $PythonTag.Trim()
+$PythonFlags = $PythonFlags.Trim()
+if ($PythonFlags.Contains("t")) {
+ $env:PYTHON_GIL = "0"
+}
+
+Write-Host "=== ($PythonTag$PythonFlags) Installing wheels ==="
+
+foreach ($Component in $Components) {
+ if ($Component -eq "adbc_driver_manager") {
+ $WheelPattern = "*-$PythonTag-$PythonTag$PythonFlags-*.whl"
+ } else {
+ $WheelPattern = "*-py3-none-*.whl"
+ }
+
+ $WheelDir = Join-Path $SourceDir "python/$Component/repaired_wheels"
+ $Wheels = @(Get-ChildItem -Path (Join-Path $WheelDir $WheelPattern))
+ if ($Wheels.Count -ne 1) {
+ throw "Expected one $Component wheel matching $WheelPattern, found
$($Wheels.Count)"
+ }
+
+ python -m pip install --no-deps --force-reinstall $Wheels[0].FullName
+ if (-not $?) { throw "Failed to install the $Component wheel" }
+}
+
+python -m pip install pytest typing-extensions
+if (-not $?) { throw "Failed to install Python test dependencies" }
+
+foreach ($Component in $Components) {
+ python -c "import $Component; import $Component.dbapi"
+ if (-not $?) { throw "Failed to import $Component" }
+}
+
+# TODO(lidavidm): make tests consistent with Unix, also consistently mark
+# tests with what they require so we can easily filter them here
+if ($PythonFlags.Contains("t") -and $Architecture -ne "amd64") {
+ Write-Host "=== Testing free-threaded driver manager without PyArrow or
Polars ==="
+ # We don't have pyarrow or polars, so most tests won't work
+ python -m pytest -vvx --import-mode append `
+ -k "unknown_driver or missing_platform or bad" `
+ (Join-Path $SourceDir
"python/adbc_driver_manager/tests/test_manifest.py")
+ if (-not $?) { throw "Failed to test the free-threaded driver manager" }
+} elseif ($Architecture -eq "amd64") {
+ python -m pip install pyarrow pandas protobuf
+ if (-not $?) { throw "Failed to install amd64 Python test dependencies" }
+
+ foreach ($Component in $Components) {
+ Write-Host "=== Testing $Component ==="
+ python -m pytest -vvx --import-mode append `
+ -k "not duckdb and not sqlite and not polars" `
+ (Join-Path $SourceDir "python/$Component/tests")
+ if (-not $?) { throw "Failed to test $Component" }
+ }
+} else {
+ python -m pip install polars
+ if (-not $?) { throw "Failed to install Polars" }
+
+ Write-Host "=== Testing driver manager with Polars and without PyArrow ==="
+ $env:ADBC_NO_SKIP_TESTS = "1"
+ python -m pytest -vvx --import-mode append `
+ (Join-Path $SourceDir
"python/adbc_driver_manager/tests/test_dbapi_polars_nopyarrow.py")
+ if (-not $?) { throw "Failed to test the driver manager with Polars" }
+}
diff --git a/python/adbc_driver_flightsql/LICENSE.txt
b/python/adbc_driver_flightsql/LICENSE.txt
index 61aa66933..234146c77 100644
--- a/python/adbc_driver_flightsql/LICENSE.txt
+++ b/python/adbc_driver_flightsql/LICENSE.txt
@@ -271,7 +271,7 @@ All rights reserved.
--------------------------------------------------------------------------------
-The files under c/vendor/fmt contain code from {fmt}.
+The files under c/vendor/fmt contain code from {fmt}, version 12.2.0.
{fmt} is under the MIT license:
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
backward-cpp has the following license:
Copyright 2013 Google Inc. All Rights Reserved.
diff --git a/python/adbc_driver_postgresql/LICENSE.txt
b/python/adbc_driver_postgresql/LICENSE.txt
index 2880ddafe..674e4fa1f 100644
--- a/python/adbc_driver_postgresql/LICENSE.txt
+++ b/python/adbc_driver_postgresql/LICENSE.txt
@@ -271,7 +271,7 @@ All rights reserved.
--------------------------------------------------------------------------------
-The files under c/vendor/fmt contain code from {fmt}.
+The files under c/vendor/fmt contain code from {fmt}, version 12.2.0.
{fmt} is under the MIT license:
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
backward-cpp has the following license:
Copyright 2013 Google Inc. All Rights Reserved.
diff --git a/python/adbc_driver_sqlite/LICENSE.txt
b/python/adbc_driver_sqlite/LICENSE.txt
index 8ba94fd8d..5fd5ba981 100644
--- a/python/adbc_driver_sqlite/LICENSE.txt
+++ b/python/adbc_driver_sqlite/LICENSE.txt
@@ -271,7 +271,7 @@ All rights reserved.
--------------------------------------------------------------------------------
-The files under c/vendor/fmt contain code from {fmt}.
+The files under c/vendor/fmt contain code from {fmt}, version 12.2.0.
{fmt} is under the MIT license:
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
backward-cpp has the following license:
Copyright 2013 Google Inc. All Rights Reserved.