|
|
|
|
@ -18,13 +18,14 @@ env: |
|
|
|
|
|
|
|
|
|
jobs: |
|
|
|
|
build-tpc: |
|
|
|
|
name: tpc.exe (PHP ${{ matrix.php }}) |
|
|
|
|
name: tpc.exe (PHP ${{ matrix.php }} ${{ matrix.thread_safety }}) |
|
|
|
|
runs-on: windows-2022 |
|
|
|
|
timeout-minutes: 90 |
|
|
|
|
strategy: |
|
|
|
|
fail-fast: false |
|
|
|
|
matrix: |
|
|
|
|
php: ["8.4", "8.5"] |
|
|
|
|
thread_safety: [nts, zts] |
|
|
|
|
|
|
|
|
|
steps: |
|
|
|
|
- name: Checkout TypePHP |
|
|
|
|
@ -38,36 +39,72 @@ jobs: |
|
|
|
|
tools: composer:v2 |
|
|
|
|
env: |
|
|
|
|
fail-fast: true |
|
|
|
|
phpts: nts |
|
|
|
|
phpts: ${{ matrix.thread_safety == 'zts' && 'ts' || 'nts' }} |
|
|
|
|
update: true |
|
|
|
|
|
|
|
|
|
- name: Install matching PHP development SDK |
|
|
|
|
- name: Resolve PHP build environment |
|
|
|
|
id: php-build-env |
|
|
|
|
shell: pwsh |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
|
|
|
|
|
$phpVersion = php -r 'echo PHP_VERSION;' |
|
|
|
|
$threadSafety = php -r 'echo PHP_ZTS ? "zts" : "nts";' |
|
|
|
|
if ($threadSafety -ne '${{ matrix.thread_safety }}') { |
|
|
|
|
throw "setup-php installed $threadSafety PHP, expected ${{ matrix.thread_safety }}" |
|
|
|
|
} |
|
|
|
|
$phpExe = (Get-Command php).Source |
|
|
|
|
$phpHome = Split-Path -Parent $phpExe |
|
|
|
|
$archiveName = "php-devel-pack-$phpVersion-nts-Win32-vs17-x64.zip" |
|
|
|
|
$threadSuffix = if ($threadSafety -eq 'nts') { '-nts' } else { '' } |
|
|
|
|
$archiveName = "php-devel-pack-$phpVersion$threadSuffix-Win32-vs17-x64.zip" |
|
|
|
|
$archive = Join-Path $env:RUNNER_TEMP $archiveName |
|
|
|
|
|
|
|
|
|
"PHP_VERSION=$phpVersion" | Out-File $env:GITHUB_ENV -Append -Encoding utf8 |
|
|
|
|
"PHP_THREAD_SAFETY=$threadSafety" | Out-File $env:GITHUB_ENV -Append -Encoding utf8 |
|
|
|
|
"PHP_HOME=$phpHome" | Out-File $env:GITHUB_ENV -Append -Encoding utf8 |
|
|
|
|
"PHPX_HOME=${{ github.workspace }}\vendor\swoole\phpx" | |
|
|
|
|
Out-File $env:GITHUB_ENV -Append -Encoding utf8 |
|
|
|
|
"PHP_DEVEL_ARCHIVE=$archive" | Out-File $env:GITHUB_ENV -Append -Encoding utf8 |
|
|
|
|
"version=$phpVersion" | Out-File $env:GITHUB_OUTPUT -Append -Encoding utf8 |
|
|
|
|
"thread_safety=$threadSafety" | Out-File $env:GITHUB_OUTPUT -Append -Encoding utf8 |
|
|
|
|
"archive=$archive" | Out-File $env:GITHUB_OUTPUT -Append -Encoding utf8 |
|
|
|
|
|
|
|
|
|
- name: Cache PHP development package |
|
|
|
|
id: cache-php-devel |
|
|
|
|
uses: actions/cache/restore@v4 |
|
|
|
|
with: |
|
|
|
|
path: ${{ steps.php-build-env.outputs.archive }} |
|
|
|
|
key: windows-2022-php-devel-${{ steps.php-build-env.outputs.version }}-${{ steps.php-build-env.outputs.thread_safety }}-vs17-x64 |
|
|
|
|
|
|
|
|
|
- name: Install matching PHP development SDK |
|
|
|
|
shell: pwsh |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
|
|
|
|
|
$phpVersion = $env:PHP_VERSION |
|
|
|
|
$phpHome = $env:PHP_HOME |
|
|
|
|
$threadSafety = $env:PHP_THREAD_SAFETY |
|
|
|
|
$archive = $env:PHP_DEVEL_ARCHIVE |
|
|
|
|
$archiveName = Split-Path -Leaf $archive |
|
|
|
|
$extractDir = Join-Path $env:RUNNER_TEMP "php-devel-$phpVersion" |
|
|
|
|
$downloaded = $false |
|
|
|
|
|
|
|
|
|
foreach ($baseUrl in @( |
|
|
|
|
'https://downloads.php.net/~windows/releases', |
|
|
|
|
'https://downloads.php.net/~windows/releases/archives' |
|
|
|
|
)) { |
|
|
|
|
try { |
|
|
|
|
Invoke-WebRequest -Uri "$baseUrl/$archiveName" -OutFile $archive |
|
|
|
|
$downloaded = $true |
|
|
|
|
break |
|
|
|
|
} catch { |
|
|
|
|
Remove-Item $archive -Force -ErrorAction SilentlyContinue |
|
|
|
|
if (-not (Test-Path $archive)) { |
|
|
|
|
$downloaded = $false |
|
|
|
|
foreach ($baseUrl in @( |
|
|
|
|
'https://downloads.php.net/~windows/releases', |
|
|
|
|
'https://downloads.php.net/~windows/releases/archives' |
|
|
|
|
)) { |
|
|
|
|
try { |
|
|
|
|
Invoke-WebRequest -Uri "$baseUrl/$archiveName" -OutFile $archive |
|
|
|
|
$downloaded = $true |
|
|
|
|
break |
|
|
|
|
} catch { |
|
|
|
|
Remove-Item $archive -Force -ErrorAction SilentlyContinue |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (-not $downloaded) { |
|
|
|
|
throw "Unable to download the PHP $phpVersion NTS development pack" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (-not $downloaded) { |
|
|
|
|
throw "Unable to download the PHP $phpVersion NTS development pack" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Expand-Archive -Path $archive -DestinationPath $extractDir -Force |
|
|
|
|
@ -91,6 +128,9 @@ jobs: |
|
|
|
|
} |
|
|
|
|
Copy-Item $embedLibrary $sdkLib -Force |
|
|
|
|
|
|
|
|
|
$coreLibrary = if ($threadSafety -eq 'zts') { 'php8ts.lib' } else { 'php8.lib' } |
|
|
|
|
$runtimeLibrary = if ($threadSafety -eq 'zts') { 'php8ts.dll' } else { 'php8.dll' } |
|
|
|
|
|
|
|
|
|
# Temporary compatibility fix for PHP packages predating php/php-src#22940. |
|
|
|
|
$hashHeader = Join-Path $sdkInclude 'ext\hash\php_hash.h' |
|
|
|
|
$hashSource = [IO.File]::ReadAllText($hashHeader) |
|
|
|
|
@ -109,33 +149,72 @@ jobs: |
|
|
|
|
|
|
|
|
|
foreach ($required in @( |
|
|
|
|
(Join-Path $sdkInclude 'main\php.h'), |
|
|
|
|
(Join-Path $sdkLib 'php8.lib'), |
|
|
|
|
(Join-Path $sdkLib $coreLibrary), |
|
|
|
|
(Join-Path $sdkLib 'php8embed.lib'), |
|
|
|
|
(Join-Path $phpHome 'php8.dll') |
|
|
|
|
(Join-Path $phpHome $runtimeLibrary) |
|
|
|
|
)) { |
|
|
|
|
if (-not (Test-Path $required)) { |
|
|
|
|
throw "Required PHP SDK file is missing: $required" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
"PHP_HOME=$phpHome" | Out-File $env:GITHUB_ENV -Append -Encoding utf8 |
|
|
|
|
"PHPX_HOME=${{ github.workspace }}\vendor\swoole\phpx" | |
|
|
|
|
Out-File $env:GITHUB_ENV -Append -Encoding utf8 |
|
|
|
|
Write-Host "Using PHP $phpVersion from $phpHome" |
|
|
|
|
|
|
|
|
|
- name: Save PHP development package |
|
|
|
|
if: steps.cache-php-devel.outputs.cache-hit != 'true' |
|
|
|
|
uses: actions/cache/save@v4 |
|
|
|
|
with: |
|
|
|
|
path: ${{ steps.php-build-env.outputs.archive }} |
|
|
|
|
key: ${{ steps.cache-php-devel.outputs.cache-primary-key }} |
|
|
|
|
|
|
|
|
|
- name: Install Composer dependencies |
|
|
|
|
run: composer install --prefer-dist --no-progress |
|
|
|
|
|
|
|
|
|
- name: Patch PHPX Windows CMake target ordering |
|
|
|
|
shell: pwsh |
|
|
|
|
run: git apply --directory=vendor/swoole/phpx .github/patches/phpx-windows-mpdecimal-target.patch |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
|
|
|
|
|
$cmakeFile = Join-Path $env:PHPX_HOME 'CMakeLists.txt' |
|
|
|
|
$source = [IO.File]::ReadAllText($cmakeFile).Replace("`r`n", "`n") |
|
|
|
|
$copyBlockPattern = '(?ms)^ # 复制 DLL 到输出目录\n file\(GLOB MPDEC_DLLS .*?^ endforeach\(\)\n' |
|
|
|
|
$copyBlock = [regex]::Match($source, $copyBlockPattern) |
|
|
|
|
if (-not $copyBlock.Success) { |
|
|
|
|
throw 'Unable to locate the pre-target PHPX mpdecimal copy block' |
|
|
|
|
} |
|
|
|
|
$source = $source.Remove($copyBlock.Index, $copyBlock.Length) |
|
|
|
|
|
|
|
|
|
$targetPattern = '(?ms)(add_library\(phpx SHARED \$\{SRC_FILES\}\)\nset_target_properties\(phpx PROPERTIES\n CLEAN_DIRECT_OUTPUT 1\n\)\n)' |
|
|
|
|
$target = [regex]::Match($source, $targetPattern) |
|
|
|
|
if (-not $target.Success) { |
|
|
|
|
throw 'Unable to locate the PHPX target declaration' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$copyBlockText = $copyBlock.Value.Replace(' # 复制 DLL 到输出目录', ' # Copy mpdecimal DLLs after the phpx target exists.') |
|
|
|
|
$guardedCopyBlock = "`nif (IS_WINDOWS)`n$copyBlockText" + "endif()`n" |
|
|
|
|
$source = $source.Insert($target.Index + $target.Length, $guardedCopyBlock) |
|
|
|
|
[IO.File]::WriteAllText($cmakeFile, $source, [Text.UTF8Encoding]::new($false)) |
|
|
|
|
|
|
|
|
|
$targetOffset = $source.IndexOf('add_library(phpx SHARED') |
|
|
|
|
$copyOffset = $source.IndexOf('add_custom_command(TARGET phpx POST_BUILD') |
|
|
|
|
if ($targetOffset -lt 0 -or $copyOffset -le $targetOffset) { |
|
|
|
|
throw 'PHPX post-build command still precedes its target declaration' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- name: Configure MSVC |
|
|
|
|
uses: ilammy/msvc-dev-cmd@v1 |
|
|
|
|
with: |
|
|
|
|
arch: x64 |
|
|
|
|
|
|
|
|
|
- name: Cache GMP and MPFR |
|
|
|
|
id: cache-gmp-mpfr |
|
|
|
|
uses: actions/cache/restore@v4 |
|
|
|
|
with: |
|
|
|
|
path: ${{ runner.temp }}\typephp-cache\vcpkg-x64-windows |
|
|
|
|
key: windows-2022-msvc-vcpkg-gmp-mpfr-x64-v1 |
|
|
|
|
|
|
|
|
|
- name: Install GMP and MPFR |
|
|
|
|
if: steps.cache-gmp-mpfr.outputs.cache-hit != 'true' |
|
|
|
|
shell: pwsh |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
@ -148,30 +227,83 @@ jobs: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$installed = Join-Path $env:VCPKG_INSTALLATION_ROOT "installed\$triplet" |
|
|
|
|
$sdkInclude = Join-Path $env:PHP_HOME 'SDK\include' |
|
|
|
|
$sdkLib = Join-Path $env:PHP_HOME 'SDK\lib' |
|
|
|
|
Copy-Item (Join-Path $installed 'include\*') $sdkInclude -Recurse -Force |
|
|
|
|
$cache = Join-Path $env:RUNNER_TEMP 'typephp-cache\vcpkg-x64-windows' |
|
|
|
|
New-Item "$cache\include", "$cache\lib", "$cache\bin" -ItemType Directory -Force | |
|
|
|
|
Out-Null |
|
|
|
|
Copy-Item (Join-Path $installed 'include\*') "$cache\include" -Recurse -Force |
|
|
|
|
|
|
|
|
|
foreach ($library in @('gmp.lib', 'gmpxx.lib', 'mpfr.lib')) { |
|
|
|
|
$source = Join-Path $installed "lib\$library" |
|
|
|
|
if (-not (Test-Path $source)) { |
|
|
|
|
throw "vcpkg did not install $library" |
|
|
|
|
} |
|
|
|
|
Copy-Item $source "$cache\lib" -Force |
|
|
|
|
} |
|
|
|
|
Copy-Item (Join-Path $installed 'bin\*.dll') "$cache\bin" -Force |
|
|
|
|
|
|
|
|
|
- name: Save GMP and MPFR |
|
|
|
|
if: steps.cache-gmp-mpfr.outputs.cache-hit != 'true' |
|
|
|
|
uses: actions/cache/save@v4 |
|
|
|
|
with: |
|
|
|
|
path: ${{ runner.temp }}\typephp-cache\vcpkg-x64-windows |
|
|
|
|
key: ${{ steps.cache-gmp-mpfr.outputs.cache-primary-key }} |
|
|
|
|
|
|
|
|
|
- name: Stage GMP and MPFR |
|
|
|
|
shell: pwsh |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
|
|
|
|
|
$cache = Join-Path $env:RUNNER_TEMP 'typephp-cache\vcpkg-x64-windows' |
|
|
|
|
$sdkInclude = Join-Path $env:PHP_HOME 'SDK\include' |
|
|
|
|
$sdkLib = Join-Path $env:PHP_HOME 'SDK\lib' |
|
|
|
|
Copy-Item "$cache\include\*" $sdkInclude -Recurse -Force |
|
|
|
|
|
|
|
|
|
foreach ($library in @('gmp.lib', 'gmpxx.lib', 'mpfr.lib')) { |
|
|
|
|
$source = Join-Path $cache "lib\$library" |
|
|
|
|
if (-not (Test-Path $source)) { |
|
|
|
|
throw "The dependency cache does not contain $library" |
|
|
|
|
} |
|
|
|
|
Copy-Item $source $sdkLib -Force |
|
|
|
|
} |
|
|
|
|
Copy-Item (Join-Path $installed 'bin\*.dll') $env:PHP_HOME -Force |
|
|
|
|
Copy-Item "$cache\bin\*.dll" $env:PHP_HOME -Force |
|
|
|
|
|
|
|
|
|
- name: Cache mpdecimal |
|
|
|
|
id: cache-mpdecimal |
|
|
|
|
uses: actions/cache/restore@v4 |
|
|
|
|
with: |
|
|
|
|
path: ${{ env.PHPX_HOME }}\thirdparty\mpdecimal\vcbuild\dist64 |
|
|
|
|
key: windows-2022-msvc-mpdecimal-x64-${{ hashFiles('vendor/swoole/phpx/thirdparty/mpdecimal/**') }} |
|
|
|
|
|
|
|
|
|
- name: Build mpdecimal |
|
|
|
|
if: steps.cache-mpdecimal.outputs.cache-hit != 'true' |
|
|
|
|
shell: pwsh |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
|
|
|
|
|
$buildScript = Join-Path $env:PHPX_HOME 'thirdparty\mpdecimal\vcbuild\vcbuild64.bat' |
|
|
|
|
& cmd.exe /d /s /c "`"$buildScript`"" |
|
|
|
|
if ($LASTEXITCODE -ne 0) { |
|
|
|
|
throw "mpdecimal build failed with exit code $LASTEXITCODE" |
|
|
|
|
$buildDirectory = Split-Path -Parent $buildScript |
|
|
|
|
Push-Location $buildDirectory |
|
|
|
|
try { |
|
|
|
|
& cmd.exe /d /s /c vcbuild64.bat |
|
|
|
|
if ($LASTEXITCODE -ne 0) { |
|
|
|
|
throw "mpdecimal build failed with exit code $LASTEXITCODE" |
|
|
|
|
} |
|
|
|
|
} finally { |
|
|
|
|
Pop-Location |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- name: Save mpdecimal |
|
|
|
|
if: steps.cache-mpdecimal.outputs.cache-hit != 'true' |
|
|
|
|
uses: actions/cache/save@v4 |
|
|
|
|
with: |
|
|
|
|
path: ${{ env.PHPX_HOME }}\thirdparty\mpdecimal\vcbuild\dist64 |
|
|
|
|
key: ${{ steps.cache-mpdecimal.outputs.cache-primary-key }} |
|
|
|
|
|
|
|
|
|
- name: Stage mpdecimal |
|
|
|
|
shell: pwsh |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
|
|
|
|
|
$dist = Join-Path $env:PHPX_HOME 'thirdparty\mpdecimal\vcbuild\dist64' |
|
|
|
|
$sdkInclude = Join-Path $env:PHP_HOME 'SDK\include' |
|
|
|
|
$sdkLib = Join-Path $env:PHP_HOME 'SDK\lib' |
|
|
|
|
@ -224,10 +356,58 @@ jobs: |
|
|
|
|
throw 'The compiler did not produce tpc.exe' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- name: Upload tpc.exe |
|
|
|
|
- name: Run Windows smoke tests |
|
|
|
|
shell: pwsh |
|
|
|
|
run: | |
|
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
|
|
|
|
|
|
$env:PATH = "$env:PHPX_HOME\build;$env:PATH" |
|
|
|
|
& .\tpc.exe tests\windows\smoke\project.yml --job 1 --no-progress |
|
|
|
|
if ($LASTEXITCODE -ne 0) { |
|
|
|
|
throw "Windows smoke project compilation failed with exit code $LASTEXITCODE" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$smokeExe = Join-Path '${{ github.workspace }}' 'tests\windows\smoke\windows_smoke.exe' |
|
|
|
|
if (-not (Test-Path $smokeExe)) { |
|
|
|
|
throw "Windows smoke executable was not generated: $smokeExe" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$processInfo = [Diagnostics.ProcessStartInfo]::new() |
|
|
|
|
$processInfo.FileName = $smokeExe |
|
|
|
|
$processInfo.ArgumentList.Add('${{ matrix.thread_safety }}') |
|
|
|
|
$processInfo.UseShellExecute = $false |
|
|
|
|
$processInfo.RedirectStandardOutput = $true |
|
|
|
|
$processInfo.RedirectStandardError = $true |
|
|
|
|
|
|
|
|
|
$process = [Diagnostics.Process]::new() |
|
|
|
|
$process.StartInfo = $processInfo |
|
|
|
|
if (-not $process.Start()) { |
|
|
|
|
throw 'Unable to start the Windows smoke executable' |
|
|
|
|
} |
|
|
|
|
$stdout = $process.StandardOutput.ReadToEnd() |
|
|
|
|
$stderr = $process.StandardError.ReadToEnd() |
|
|
|
|
$process.WaitForExit() |
|
|
|
|
|
|
|
|
|
Write-Host "Windows smoke stdout: $stdout" |
|
|
|
|
Write-Host "Windows smoke stderr: $stderr" |
|
|
|
|
Write-Host "Windows smoke exit code: $($process.ExitCode)" |
|
|
|
|
if ($process.ExitCode -ne 0) { |
|
|
|
|
throw "Windows smoke executable failed with exit code $($process.ExitCode)" |
|
|
|
|
} |
|
|
|
|
if ($stdout.Trim() -ne 'windows-smoke-ok:${{ matrix.thread_safety }}') { |
|
|
|
|
throw "Unexpected Windows smoke output: $stdout" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- name: Upload Windows build outputs |
|
|
|
|
if: always() |
|
|
|
|
uses: actions/upload-artifact@v4 |
|
|
|
|
with: |
|
|
|
|
name: tpc-windows-x64-php-${{ matrix.php }} |
|
|
|
|
if-no-files-found: error |
|
|
|
|
name: tpc-windows-x64-php-${{ matrix.php }}-${{ matrix.thread_safety }} |
|
|
|
|
if-no-files-found: warn |
|
|
|
|
retention-days: 7 |
|
|
|
|
path: tpc.exe |
|
|
|
|
path: | |
|
|
|
|
tpc.exe |
|
|
|
|
tests/windows/smoke/windows_smoke.exe |
|
|
|
|
tests/windows/smoke/build/**/*.cc |
|
|
|
|
tests/windows/smoke/build/**/*.h |
|
|
|
|
tests/windows/smoke/build/**/*.rsp |
|
|
|
|
|