Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/scripts/windows/build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only
exit /b 3
)

set SDK_REMOTE=https://github.com/php/php-sdk-binary-tools.git
set SDK_BRANCH=%PHP_BUILD_SDK_BRANCH%
set SDK_RUNNER=%PHP_BUILD_CACHE_SDK_DIR%\phpsdk-%PHP_BUILD_CRT%-%PLATFORM%.bat

if not exist "%PHP_BUILD_CACHE_BASE_DIR%" (
echo Creating %PHP_BUILD_CACHE_BASE_DIR%
mkdir "%PHP_BUILD_CACHE_BASE_DIR%"
)

if not exist "%PHP_BUILD_OBJ_DIR%" (
echo Creating %PHP_BUILD_OBJ_DIR%
mkdir "%PHP_BUILD_OBJ_DIR%"
)

if not exist "%SDK_RUNNER%" (
if exist "%PHP_BUILD_CACHE_SDK_DIR%" rmdir /s /q "%PHP_BUILD_CACHE_SDK_DIR%"
)

if not exist "%PHP_BUILD_CACHE_SDK_DIR%" (
echo Cloning remote SDK repository
git clone --branch %SDK_BRANCH% %SDK_REMOTE% --depth 1 "%PHP_BUILD_CACHE_SDK_DIR%" 2>&1
)

for /f "tokens=*" %%a in ('type %PHP_BUILD_CACHE_SDK_DIR%\VERSION') do set GOT_SDK_VER=%%a
echo Got SDK version %GOT_SDK_VER%
if NOT "%GOT_SDK_VER%" == "%PHP_BUILD_SDK_BRANCH:~8%" (
echo Switching to the configured SDK version %SDK_BRANCH:~8%
echo Fetching remote SDK repository
git --git-dir="%PHP_BUILD_CACHE_SDK_DIR%\.git" --work-tree="%PHP_BUILD_CACHE_SDK_DIR%" fetch --prune origin 2>&1
echo Checkout SDK repository branch
git --git-dir="%PHP_BUILD_CACHE_SDK_DIR%\.git" --work-tree="%PHP_BUILD_CACHE_SDK_DIR%" checkout --force %SDK_BRANCH%
)

if not exist "%SDK_RUNNER%" (
echo "%SDK_RUNNER%" doesn't exist
exit /b 3
)

for /f "delims=" %%T in ('call .github\scripts\windows\find-vs-toolset.bat %PHP_BUILD_CRT%') do set "VS_TOOLSET=%%T"
echo Got VS Toolset %VS_TOOLSET%
cmd /c %SDK_RUNNER% -s %VS_TOOLSET% -t .github\scripts\windows\build_task.bat
if %errorlevel% neq 0 exit /b 3

exit /b 0
48 changes: 48 additions & 0 deletions .github/scripts/windows/build_clickhouse_cpp.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@echo off

rem Build the bundled clickhouse-cpp as a static library together with its
rem contrib (cityhash, lz4, zstd, absl). Runs inside the phpsdk environment, so
rem the MSVC toolset (cl/nmake) is already on PATH. A single-config "NMake
rem Makefiles" generator drops each archive in its target's build directory,
rem which is exactly where config.w32 looks for them. Flags mirror the Linux CI
rem (.github/workflows/ci.yml): native Bool, no OpenSSL (TLS goes through PHP
rem streams), no tests/benchmarks.

set CH_CPP_DIR=ext\clickhouse_async\third_party\clickhouse-cpp

if not exist "%CH_CPP_DIR%\clickhouse\client.h" (
echo ERROR: clickhouse-cpp submodule not found at %CH_CPP_DIR%
echo Run: git submodule update --init --recursive
exit /b 1
)

rem Reuse a previous build (the build directory is part of the runner cache).
if exist "%CH_CPP_DIR%\build\clickhouse\clickhouse-cpp-lib.lib" (
echo clickhouse-cpp already built, skipping.
exit /b 0
)

rem clickhouse-cpp's bundled zstd unconditionally compiles a GAS assembly file
rem (decompress/huf_decompress_amd64.S) that MSVC cannot assemble, which breaks
rem the zstdstatic link. zstd falls back to its portable C path on MSVC
rem (ZSTD_ASM_SUPPORTED=0), so the asm source is not needed -- drop it. Patching
rem the freshly checked-out submodule here keeps our repo's submodule pointer
rem clean. Idempotent: the regex no longer matches once commented out.
powershell -NoProfile -Command "$f = '%CH_CPP_DIR%\contrib\zstd\zstd\CMakeLists.txt'; (Get-Content -LiteralPath $f) -replace '^\s*decompress/huf_decompress_amd64\.S\s*$', ' # huf_decompress_amd64.S excluded on MSVC (C fallback used)' | Set-Content -LiteralPath $f"
if %errorlevel% neq 0 exit /b 3

cmake -S "%CH_CPP_DIR%" -B "%CH_CPP_DIR%\build" -G "NMake Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_C_COMPILER=cl ^
-DCMAKE_CXX_COMPILER=cl ^
-DBUILD_SHARED_LIBS=OFF ^
-DCH_MAP_BOOL_TO_UINT8=OFF ^
-DWITH_OPENSSL=OFF ^
-DBUILD_TESTS=OFF ^
-DBUILD_BENCHMARK=OFF
if %errorlevel% neq 0 exit /b 3

cmake --build "%CH_CPP_DIR%\build"
if %errorlevel% neq 0 exit /b 3

exit /b 0
58 changes: 58 additions & 0 deletions .github/scripts/windows/build_task.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
@echo off

if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only
exit /b 3
)

call %~dp0find-target-branch.bat
set STABILITY=staging
set DEPS_DIR=%PHP_BUILD_CACHE_BASE_DIR%\deps-%BRANCH%-%PHP_SDK_VS%-%PHP_SDK_ARCH%
rem SDK is cached, deps info is cached as well
echo Updating dependencies in %DEPS_DIR%
cmd /c phpsdk_deps --update --no-backup --branch %BRANCH% --stability %STABILITY% --deps %DEPS_DIR% --crt %PHP_BUILD_CRT%
if %errorlevel% neq 0 exit /b 3

rem Something went wrong, most likely when concurrent builds were to fetch deps
rem updates. It might be, that some locking mechanism is needed.
if not exist "%DEPS_DIR%" (
cmd /c phpsdk_deps --update --force --no-backup --branch %BRANCH% --stability %STABILITY% --deps %DEPS_DIR%
)
if %errorlevel% neq 0 exit /b 3

rem Copy LibUV from vcpkg to deps directory (required by ext/async).
if not exist "%DEPS_DIR%\include\libuv" mkdir "%DEPS_DIR%\include\libuv"
if not exist "%DEPS_DIR%\lib" mkdir "%DEPS_DIR%\lib"
if not exist "%DEPS_DIR%\bin" mkdir "%DEPS_DIR%\bin"
copy "C:\vcpkg\installed\x64-windows\include\uv.h" "%DEPS_DIR%\include\libuv\uv.h"
xcopy /E /I /H /Y "C:\vcpkg\installed\x64-windows\include\uv" "%DEPS_DIR%\include\libuv\uv\"
copy "C:\vcpkg\installed\x64-windows\lib\uv.lib" "%DEPS_DIR%\lib\libuv.lib"
copy "C:\vcpkg\installed\x64-windows\bin\uv.dll" "%DEPS_DIR%\bin\uv.dll"

rem Build the bundled clickhouse-cpp static library before configure: config.w32
rem requires the prebuilt archives to be present.
call .github\scripts\windows\build_clickhouse_cpp.bat
if %errorlevel% neq 0 exit /b 3

cmd /c buildconf.bat --force
if %errorlevel% neq 0 exit /b 3

if "%THREAD_SAFE%" equ "0" set ADD_CONF=%ADD_CONF% --disable-zts
if "%INTRINSICS%" neq "" set ADD_CONF=%ADD_CONF% --enable-native-intrinsics=%INTRINSICS%

cmd /c configure.bat ^
--enable-snapshot-build ^
--disable-debug-pack ^
--without-analyzer ^
--enable-object-out-dir=%PHP_BUILD_OBJ_DIR% ^
--with-php-build=%DEPS_DIR% ^
--enable-async ^
--enable-clickhouse-async ^
%ADD_CONF% ^
--disable-test-ini
if %errorlevel% neq 0 exit /b 3

nmake /NOLOGO
if %errorlevel% neq 0 exit /b 3

exit /b 0
8 changes: 8 additions & 0 deletions .github/scripts/windows/find-target-branch.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@echo off

for /f "usebackq tokens=3" %%i in (`findstr PHP_MAJOR_VERSION main\php_version.h`) do set BRANCH=%%i
for /f "usebackq tokens=3" %%i in (`findstr PHP_MINOR_VERSION main\php_version.h`) do set BRANCH=%BRANCH%.%%i

if /i "%BRANCH%" equ "8.5" (
set BRANCH=master
)
52 changes: 52 additions & 0 deletions .github/scripts/windows/find-vs-toolset.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@echo off

setlocal enabledelayedexpansion

if "%~1"=="" (
echo ERROR: Usage: %~nx0 [vc14^|vc15^|vs16^|vs17^|vs18]
exit /b 1
)

set "toolsets_vc14=14.0"
set "toolsets_vc15="
set "toolsets_vs16="
set "toolsets_vs17="
set "toolsets_vs18="


for /f "usebackq tokens=*" %%I in (`vswhere.exe -latest -find "VC\Tools\MSVC"`) do set "MSVCDIR=%%I"

if not defined MSVCDIR (
echo ERROR: could not locate VC\Tools\MSVC
exit /b 1
)

for /f "delims=" %%D in ('dir /b /ad "%MSVCDIR%"') do (
for /f "tokens=1,2 delims=." %%A in ("%%D") do (
set "maj=%%A" & set "min=%%B"
if "!maj!"=="14" (
if !min! LEQ 9 (
set "toolsets_vc14=%%D"
) else if !min! LEQ 19 (
set "toolsets_vc15=%%D"
) else if !min! LEQ 29 (
set "toolsets_vs16=%%D"
) else if !min! LEQ 49 (
set "toolsets_vs17=%%D"
) else (
set "toolsets_vs18=%%D"
)
)
)
)

set "KEY=%~1"
set "VAR=toolsets_%KEY%"
call set "RESULT=%%%VAR%%%"
if defined RESULT (
echo %RESULT%
exit /b 0
) else (
echo ERROR: no toolset found for %KEY%
exit /b 1
)
19 changes: 19 additions & 0 deletions .github/scripts/windows/smoke.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/* CI smoke check: the statically-built clickhouse_async extension loads and
* registers its public API. No ClickHouse server required. Kept as a file
* (not an inline php -r) so cmd does not mangle the '!' and quotes. */

if (!extension_loaded('true_async_clickhouse')) {
fwrite(STDERR, 'FAIL: true_async_clickhouse not loaded' . PHP_EOL);
exit(1);
}

foreach (['TrueAsync\\ClickHouse\\Client', 'TrueAsync\\ClickHouse\\Result'] as $class) {
if (!class_exists($class)) {
fwrite(STDERR, 'FAIL: ' . $class . ' missing' . PHP_EOL);
exit(1);
}
}

echo 'OK: true_async_clickhouse loaded; Client and Result present' . PHP_EOL;
16 changes: 16 additions & 0 deletions .github/scripts/windows/test.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only
exit /b 3
)

set SDK_RUNNER=%PHP_BUILD_CACHE_SDK_DIR%\phpsdk-%PHP_BUILD_CRT%-%PLATFORM%.bat
if not exist "%SDK_RUNNER%" (
echo "%SDK_RUNNER%" doesn't exist
exit /b 3
)

for /f "delims=" %%T in ('call .github\scripts\windows\find-vs-toolset.bat %PHP_BUILD_CRT%') do set "VS_TOOLSET=%%T"
cmd /c %SDK_RUNNER% -s %VS_TOOLSET% -t .github\scripts\windows\test_task.bat
if %errorlevel% neq 0 exit /b 3

exit /b 0
36 changes: 36 additions & 0 deletions .github/scripts/windows/test_task.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@echo off
rem No EnableDelayedExpansion: it would treat '!' specially and corrupt PHP code.
setlocal

if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only
exit /b 3
)

echo === clickhouse_async smoke test ===

set PHP_BUILD_DIR=%PHP_BUILD_OBJ_DIR%\Release_TS
if not exist "%PHP_BUILD_DIR%\php.exe" (
echo ERROR: php.exe not found at %PHP_BUILD_DIR%
exit /b 1
)

rem Bring dependency DLLs (libuv, ...) next to php.exe so it can start.
call %~dp0find-target-branch.bat
set DEPS_DIR=%PHP_BUILD_CACHE_BASE_DIR%\deps-%BRANCH%-%PHP_SDK_VS%-%PHP_SDK_ARCH%
if exist "%DEPS_DIR%\bin" copy /y "%DEPS_DIR%\bin\*.dll" "%PHP_BUILD_DIR%\" >nul

echo.
echo --- php -m ---
"%PHP_BUILD_DIR%\php.exe" -n -m
echo.

rem The extension is built statically into php.exe (no ini needed, -n). The
rem checks live in smoke.php so cmd does not mangle '!' and quotes in inline code.
echo --- verifying clickhouse_async ---
"%PHP_BUILD_DIR%\php.exe" -n "%~dp0smoke.php"
set RC=%errorlevel%

echo.
echo smoke test exit code: %RC%
exit /b %RC%
73 changes: 73 additions & 0 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: ClickHouse Async Windows Build

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
WINDOWS:
name: WINDOWS_X64_ZTS
runs-on: windows-2025-vs2026
timeout-minutes: 90
env:
PHP_BUILD_CACHE_BASE_DIR: C:\build-cache
PHP_BUILD_OBJ_DIR: C:\obj
PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk
PHP_BUILD_SDK_BRANCH: php-sdk-2.7.1
PHP_BUILD_CRT: vs18
PLATFORM: x64
THREAD_SAFE: "1"
INTRINSICS: AVX2
PARALLEL: -j2
OPCACHE: "1"
# php-src and php-async are separate repos whose engine ABI must match.
# These mirror the known-good pinned pair from .github/workflows/ci.yml;
# bump them together with ci.yml.
PHP_SRC_REPO: true-async/php-src
PHP_SRC_SHA: 568c83c6b307417d1f75690604353c65df865aa8
PHP_ASYNC_REPO: true-async/php-async
PHP_ASYNC_SHA: 6b5aaa5d2ea90744a8c4e8c7c4e8d2b4cd24e14a
steps:
- name: git config
run: git config --global core.autocrlf false && git config --global core.eol lf

- name: Checkout php-src to root
uses: actions/checkout@v4
with:
repository: ${{ env.PHP_SRC_REPO }}
ref: ${{ env.PHP_SRC_SHA }}

- name: Checkout async extension into ext/async
uses: actions/checkout@v4
with:
repository: ${{ env.PHP_ASYNC_REPO }}
ref: ${{ env.PHP_ASYNC_SHA }}
path: ext/async

- name: Checkout clickhouse extension (with clickhouse-cpp submodule) into ext/clickhouse_async
uses: actions/checkout@v4
with:
repository: ${{ github.repository }}
submodules: recursive
path: ext/clickhouse_async

- name: Overlay clickhouse CI scripts onto the php-src tree
shell: cmd
run: xcopy /E /I /H /Y ext\clickhouse_async\.github .github

- name: Setup LibUV (required by ext/async)
shell: powershell
run: |
if (!(Test-Path "C:\vcpkg")) {
git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat
}
C:\vcpkg\vcpkg.exe install libuv:x64-windows

- name: Build (clickhouse-cpp + PHP with async and clickhouse_async)
run: .github/scripts/windows/build.bat

- name: Smoke test (extension loads, Client class present)
run: .github/scripts/windows/test.bat
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
Expand Down
Loading
Loading