Skip to content
Open
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
4 changes: 2 additions & 2 deletions .github/workflows/test-php-libs-from-source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ jobs:
run: |
$artifactDirectory = $(pwd).Path
$zip = Get-ChildItem -Path $artifactDirectory -Filter "php-*.zip" -File |
Where-Object { $_.Name -match "^php-(.+?)-(?:nts-)?Win32-v[sc]\d+-${{ matrix.arch }}\.zip$" } |
Where-Object { $_.Name -match "^php-(.+?)-(?:nts-)?Win32-(?:v[sc]\d+|clang)-${{ matrix.arch }}\.zip$" } |
Select-Object -First 1
if ($null -eq $zip) {
throw "Unable to determine PHP version from build artifacts in $artifactDirectory"
}
$phpVersion = [regex]::Match($zip.Name, '^php-(.+?)-(?:nts-)?Win32-v[sc]\d+-').Groups[1].Value
$phpVersion = [regex]::Match($zip.Name, '^php-(.+?)-(?:nts-)?Win32-(?:v[sc]\d+|clang)-').Groups[1].Value

Import-Module (Join-Path $(pwd).Path '\php\BuildPhp') -Force
$cacheInfo = Get-DepsCacheInfo -PhpVersion $phpVersion -Arch '${{ matrix.arch }}' -LibsBuildRuns '${{ inputs.libs-build-runs }}' -IncludeDefaultRunsKey
Expand Down
3 changes: 3 additions & 0 deletions extension/BuildPhpExtension/private/Add-Extension.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ Function Add-Extension {
$argumentString += " $argument"
}
}
if (Test-ClangToolset -PhpVersion $Config.php_version) {
$argumentString += " --with-toolset=clang"
}
$bat_content = @()
$bat_content += ""
$bat_content += "call phpize 2>&1"
Expand Down
4 changes: 4 additions & 0 deletions extension/BuildPhpExtension/private/Get-ExtensionConfig.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ Function Get-ExtensionConfig {
}
$config.options = $config.options -join " "

if (Test-ClangToolset -PhpVersion $PhpVersion) {
$config.options += " --with-toolset=clang"
}

if($null -ne $env:CONFIGURE_ARGS -and -not([string]::IsNullOrWhiteSpace($env:CONFIGURE_ARGS))) {
$config.options += " $env:CONFIGURE_ARGS"
}
Expand Down
28 changes: 28 additions & 0 deletions extension/BuildPhpExtension/private/Test-ClangToolset.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Function Test-ClangToolset {
<#
.SYNOPSIS
Check whether the PHP version is built with the clang-cl toolset.
.PARAMETER PhpVersion
PHP Version
#>
[OutputType([bool])]
param(
[Parameter(Mandatory = $true, Position=0, HelpMessage='PHP Version')]
[ValidateNotNull()]
[ValidateLength(1, [int]::MaxValue)]
[string] $PhpVersion
)
begin {
}
process {
if ($PhpVersion -eq 'master') {
return $true
}
if ($PhpVersion -notmatch '^(\d+\.\d+(?:\.\d+)?)') {
return $false
}
return [version] $matches[1] -ge [version] '8.6'
}
end {
}
}
2 changes: 1 addition & 1 deletion php/BuildPhp/config/vs18/x64/config.nts.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--disable-zts" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--enable-pgi" %*
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--disable-zts" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--with-toolset=clang" "--enable-pgi" %*
2 changes: 1 addition & 1 deletion php/BuildPhp/config/vs18/x64/config.ts.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--enable-pgi" %*
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--with-toolset=clang" "--enable-pgi" %*
2 changes: 1 addition & 1 deletion php/BuildPhp/config/vs18/x86/config.nts.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--disable-zts" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--enable-pgi" %*
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--disable-zts" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--with-toolset=clang" "--enable-pgi" %*
2 changes: 1 addition & 1 deletion php/BuildPhp/config/vs18/x86/config.ts.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--enable-pgi" %*
cscript /nologo configure.js "--enable-snapshot-build" "--enable-debug-pack" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--with-toolset=clang" "--enable-pgi" %*
6 changes: 6 additions & 0 deletions php/BuildPhp/private/Add-TestRequirements.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ function Add-TestRequirements {

$currentDirectory = (Get-Location).Path
$binZipFilePath = Join-Path $ArtifactsDirectory $binZipFile
if(-not(Test-Path -LiteralPath $binZipFilePath)) {
$clangBinZipFilePath = Join-Path $ArtifactsDirectory "php-$versionInUrl-$tsPart-clang-$Arch.zip"
if(Test-Path -LiteralPath $clangBinZipFilePath) {
$binZipFilePath = $clangBinZipFilePath
}
}
$binDirectoryPath = Join-Path $currentDirectory phpbin

$testZipFilePath = Join-Path $ArtifactsDirectory $testZipFile
Expand Down
59 changes: 59 additions & 0 deletions php/BuildPhp/private/Get-ClangX86ProfileRuntime.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
function Get-ClangX86ProfileRuntime {
<#
.SYNOPSIS
Prepare a Clang resource directory with the x86 PGO runtime.
#>
[OutputType([string])]
param (
[Parameter(Mandatory = $true)]
[string] $BuildDirectory
)

$compiler = (Get-Command clang-cl.exe).Source
$resourceDirectory = (& $compiler --print-resource-dir | Out-String).Trim()
if($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $resourceDirectory -PathType Container)) {
throw 'Unable to locate the Clang resource directory'
}

$runtimeDirectory = Join-Path $BuildDirectory ('clang-resource-' + [guid]::NewGuid().ToString('N'))
$downloadDirectory = Join-Path $BuildDirectory ('clang-runtime-download-' + [guid]::NewGuid().ToString('N'))
try {
Copy-Item -LiteralPath $resourceDirectory -Destination $runtimeDirectory -Recurse
$profileLibrary = Join-Path $runtimeDirectory 'lib\windows\clang_rt.profile-i386.lib'
if(Test-Path -LiteralPath $profileLibrary) {
return $runtimeDirectory
}

New-Item -Path $downloadDirectory -ItemType Directory | Out-Null
$compilerVersion = & $compiler --version | Out-String
if($LASTEXITCODE -ne 0 -or $compilerVersion -notmatch 'clang version (\d+\.\d+\.\d+)') {
throw 'Unable to determine the Clang version'
}
$version = $Matches[1]
$installer = Join-Path $downloadDirectory 'llvm-win32.exe'
Get-File -Url "https://github.com/llvm/llvm-project/releases/download/llvmorg-$version/LLVM-$version-win32.exe" -OutFile $installer
$resourceVersion = Split-Path $resourceDirectory -Leaf
$libraryPath = "lib\clang\$resourceVersion\lib\windows\clang_rt.profile-i386.lib"
$sevenZip = Get-Command 7z.exe -ErrorAction SilentlyContinue
$extractor = if($sevenZip) { $sevenZip.Source } else { Join-Path $env:ProgramFiles '7-Zip\7z.exe' }
& $extractor x $installer "-o$downloadDirectory" $libraryPath -y | Out-Null
if($LASTEXITCODE -ne 0) {
throw 'Unable to extract the Clang x86 PGO runtime'
}
$extractedLibrary = Join-Path $downloadDirectory $libraryPath
if(-not (Test-Path -LiteralPath $extractedLibrary -PathType Leaf)) {
throw 'The LLVM x86 package does not contain the PGO runtime'
}
Copy-Item -LiteralPath $extractedLibrary -Destination $profileLibrary
return $runtimeDirectory
} catch {
if(Test-Path -LiteralPath $runtimeDirectory) {
Remove-Item -LiteralPath $runtimeDirectory -Recurse -Force
}
throw
} finally {
if(Test-Path -LiteralPath $downloadDirectory) {
Remove-Item -LiteralPath $downloadDirectory -Recurse -Force
}
}
}
7 changes: 7 additions & 0 deletions php/BuildPhp/private/Get-PhpSdk.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ function Get-PhpSdk {
Get-File -Url $url -OutFile php-sdk.zip
Expand-Archive -Path php-sdk.zip -DestinationPath .
Rename-Item -Path php-sdk-binary-tools-$sdkVersion php-sdk

# PHP SDK 2.8.4 only recognizes MSVC archive names in its SBOM tool.
$sbomPath = Join-Path (Get-Location).Path 'php-sdk\bin\phpsdk_sbom.php'
$sbomScript = Get-Content -LiteralPath $sbomPath -Raw
[System.IO.File]::WriteAllText($sbomPath,
$sbomScript.Replace('v[sc]\d+', '(?:v[sc]\d+|clang)'),
[System.Text.UTF8Encoding]::new($false))
}
end {
}
Expand Down
12 changes: 12 additions & 0 deletions php/BuildPhp/public/Invoke-PhpBuild.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ function Invoke-PhpBuild {

New-Item "$buildDirectory" -ItemType "directory" -Force > $null 2>&1

$clangResourceDirectory = $null
$originalClangResourceDirectory = $env:PHP_CLANG_RESOURCE_DIR

try {
Set-Location "$buildDirectory"

Expand Down Expand Up @@ -78,6 +81,11 @@ function Invoke-PhpBuild {
$task = [System.IO.Path]::GetFileName($taskTemplate)
Copy-Item -Path $taskTemplate -Destination $task -Force

if($Arch -eq 'x86' -and (Select-String -LiteralPath $configBatch -SimpleMatch '--with-toolset=clang' -Quiet)) {
$clangResourceDirectory = Get-ClangX86ProfileRuntime -BuildDirectory $buildDirectory
$env:PHP_CLANG_RESOURCE_DIR = $clangResourceDirectory
}

Invoke-PhpSdkStarter -BuildDirectory $buildDirectory -VsConfig $VsConfig -Arch $Arch -Task $task

$artifacts = if ($Ts -eq "ts") {"..\obj\Release_TS\php-*.zip"} else {"..\obj\Release\php-*.zip"}
Expand Down Expand Up @@ -107,6 +115,10 @@ function Invoke-PhpBuild {
}
} finally {
Set-Location "$currentDirectory"
$env:PHP_CLANG_RESOURCE_DIR = $originalClangResourceDirectory
if($clangResourceDirectory) {
Remove-Item -LiteralPath $clangResourceDirectory -Recurse -Force
}
}
}
end {
Expand Down
2 changes: 1 addition & 1 deletion php/BuildPhp/public/Invoke-PhpSmokeTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function Invoke-PhpSmokeTests {
}

$zipPattern = "php-*-$Arch.zip"
$zipRegex = "^php-(.+?)(-nts)?-Win32-v[sc]\d+-${Arch}\.zip$"
$zipRegex = "^php-(.+?)(-nts)?-Win32-(?:v[sc]\d+|clang)-${Arch}\.zip$"
$zipMatches = @(
Get-ChildItem -Path $artifactsPath -Filter $zipPattern -File |
Where-Object {
Expand Down
44 changes: 44 additions & 0 deletions php/BuildPhp/runner/task-nts.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
set LDFLAGS="/d2:-AllowCompatibleILVersions" 2>&1
call buildconf.bat 2>&1
if errorlevel 1 exit 1

findstr /c:"--with-toolset=clang" config.nts.bat >nul 2>&1
if errorlevel 1 goto msvc

if defined PHP_CLANG_RESOURCE_DIR (
set "CFLAGS=%CFLAGS% -resource-dir="%PHP_CLANG_RESOURCE_DIR%""
set "LDFLAGS=%LDFLAGS% /libpath:"%PHP_CLANG_RESOURCE_DIR%\lib\windows""
)

rem clang-cl PGO: --enable-pgi/--with-pgo add the profile flags via configure, phpsdk_pgo only runs the training workloads.
rem the profiles go into BUILD_DIR, which nmake clean-pgo preserves like the pgd files of the Visual Studio flow.
set "PGO_DIR=%CD%\..\obj\Release"
del /f /q "%PGO_DIR%\*.profraw" "%PGO_DIR%\php.profdata" >nul 2>&1
set "LLVM_PROFILE_FILE=%PGO_DIR%\php-%%p.profraw"
rem init only serves one request, have php-cgi exit right away so its profile is written before the training env shutdown.
set "PHP_FCGI_MAX_REQUESTS=1"
call config.nts.bat 2>&1
if errorlevel 1 exit 2
nmake 2>&1
if errorlevel 1 exit 3
call phpsdk_pgo --init 2>&1
if errorlevel 1 exit 4
rem pgo01org serves 12 requests per scenario (max_runs x 1 url); php-cgi self-exits after the last one and writes its profile.
set "PHP_FCGI_MAX_REQUESTS=12"
call phpsdk_pgo --train --scenario default 2>&1
if errorlevel 1 exit 5
call phpsdk_pgo --train --scenario cache 2>&1
if errorlevel 1 exit 6
llvm-profdata merge -output="%PGO_DIR%\php.profdata" "%PGO_DIR%\*.profraw"
if errorlevel 1 exit 7
nmake clean-pgo 2>&1
if errorlevel 1 exit 8
sed -i "s/enable-pgi/with-pgo/" config.nts.bat 2>&1
if errorlevel 1 exit 9
set "LLVM_PROFILE_FILE="
set "PHP_FCGI_MAX_REQUESTS="
call config.nts.bat 2>&1
if errorlevel 1 exit 10
nmake && nmake snap 2>&1
if errorlevel 1 exit 11
exit /b 0

:msvc
call config.nts.bat 2>&1
if errorlevel 1 exit 2
nmake 2>&1
Expand All @@ -19,3 +62,4 @@ call config.nts.bat 2>&1
if errorlevel 1 exit 9
nmake && nmake snap 2>&1
if errorlevel 1 exit 10
exit /b 0
44 changes: 44 additions & 0 deletions php/BuildPhp/runner/task-ts.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
set LDFLAGS="/d2:-AllowCompatibleILVersions" 2>&1
call buildconf.bat 2>&1
if errorlevel 1 exit 1

findstr /c:"--with-toolset=clang" config.ts.bat >nul 2>&1
if errorlevel 1 goto msvc

if defined PHP_CLANG_RESOURCE_DIR (
set "CFLAGS=%CFLAGS% -resource-dir="%PHP_CLANG_RESOURCE_DIR%""
set "LDFLAGS=%LDFLAGS% /libpath:"%PHP_CLANG_RESOURCE_DIR%\lib\windows""
)

rem clang-cl PGO: --enable-pgi/--with-pgo add the profile flags via configure, phpsdk_pgo only runs the training workloads.
rem the profiles go into BUILD_DIR, which nmake clean-pgo preserves like the pgd files of the Visual Studio flow.
set "PGO_DIR=%CD%\..\obj\Release_TS"
del /f /q "%PGO_DIR%\*.profraw" "%PGO_DIR%\php.profdata" >nul 2>&1
set "LLVM_PROFILE_FILE=%PGO_DIR%\php-%%p.profraw"
rem init only serves one request, have php-cgi exit right away so its profile is written before the training env shutdown.
set "PHP_FCGI_MAX_REQUESTS=1"
call config.ts.bat 2>&1
if errorlevel 1 exit 2
nmake 2>&1
if errorlevel 1 exit 3
call phpsdk_pgo --init 2>&1
if errorlevel 1 exit 4
rem pgo01org serves 12 requests per scenario (max_runs x 1 url); php-cgi self-exits after the last one and writes its profile.
set "PHP_FCGI_MAX_REQUESTS=12"
call phpsdk_pgo --train --scenario default 2>&1
if errorlevel 1 exit 5
call phpsdk_pgo --train --scenario cache 2>&1
if errorlevel 1 exit 6
llvm-profdata merge -output="%PGO_DIR%\php.profdata" "%PGO_DIR%\*.profraw"
if errorlevel 1 exit 7
nmake clean-pgo 2>&1
if errorlevel 1 exit 8
sed -i "s/enable-pgi/with-pgo/" config.ts.bat 2>&1
if errorlevel 1 exit 9
set "LLVM_PROFILE_FILE="
set "PHP_FCGI_MAX_REQUESTS="
call config.ts.bat 2>&1
if errorlevel 1 exit 10
nmake && nmake snap 2>&1
if errorlevel 1 exit 11
exit /b 0

:msvc
call config.ts.bat 2>&1
if errorlevel 1 exit 2
nmake 2>&1
Expand All @@ -19,3 +62,4 @@ call config.ts.bat 2>&1
if errorlevel 1 exit 9
nmake && nmake snap 2>&1
if errorlevel 1 exit 10
exit /b 0