Skip to content

Build PHP SDK

Build PHP SDK #34

Workflow file for this run

name: Build PHP SDK
on:
workflow_dispatch:
inputs:
php_version:
description: "PHP version to build (e.g. 8.5.2, 8.4.7, 8.3.20)"
required: true
type: string
env:
SPC_VERSION: "2.8.5"
PHP_EXTENSIONS: "bcmath,calendar,ctype,curl,dom,exif,fileinfo,filter,gd,hash,iconv,mbstring,mysqli,mysqlnd,openssl,pcntl,pcre,pdo,pdo_mysql,phar,posix,session,simplexml,sodium,tokenizer,xml,xmlreader,xmlwriter,zip,zlib"
jobs:
build-linux:
name: Linux (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: x86_64
runner: [self-hosted, linux, x64]
spc_arch: x86_64
- arch: aarch64
runner: ubuntu-24.04-arm
spc_arch: aarch64
steps:
- name: Clean up previous builds
if: ${{ !contains(matrix.runner, 'ubuntu') }}
run: rm -rf buildroot source downloads sdk *.tar.gz
- name: Install system dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq build-essential autoconf automake bison \
cmake flex libtool make pkg-config re2c
- name: Install cross-compilation tools (aarch64)
if: matrix.arch == 'aarch64'
run: sudo apt-get install -y -qq gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
- name: Download spc
run: |
mkdir -p "$HOME/bin"
curl -fsSL "https://github.com/crazywhalecc/static-php-cli/releases/download/${{ env.SPC_VERSION }}/spc-linux-${{ matrix.spc_arch }}.tar.gz" \
| tar xz -C "$HOME/bin"
echo "$HOME/bin" >> "$GITHUB_PATH"
- name: Download PHP sources
run: |
spc download \
--with-php=${{ inputs.php_version }} \
--for-extensions=${{ env.PHP_EXTENSIONS }} \
--prefer-pre-built
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run spc doctor
run: spc doctor --auto-fix || true
- name: Build libphp.a
run: |
spc build ${{ env.PHP_EXTENSIONS }} \
--build-embed \
--enable-zts \
--no-strip \
--debug
- name: Package SDK
run: |
mkdir -p sdk/lib sdk/include
cp buildroot/lib/libphp.a sdk/lib/
cp -r buildroot/include/php sdk/include/php
tar czf php-sdk-${{ inputs.php_version }}-linux-${{ matrix.arch }}.tar.gz -C sdk .
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: php-sdk-${{ inputs.php_version }}-linux-${{ matrix.arch }}
path: php-sdk-${{ inputs.php_version }}-linux-${{ matrix.arch }}.tar.gz
build-macos:
name: macOS (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: aarch64
runner: macos-latest
spc_arch: aarch64
steps:
# spc is a PHP app — needs a host PHP CLI to run. This does NOT
# affect the PHP version being built (that's inputs.php_version).
- name: Set up PHP (host toolchain for spc)
uses: shivammathur/setup-php@v2
with:
php-version: "8.5"
- name: Install system dependencies
run: |
brew install autoconf automake bison cmake flex libtool \
make pkg-config re2c
# Use Homebrew LLVM instead of Apple clang — Apple clang crashes
# on PHP's JIT code (zend_jit_vm_helpers.c, exit code 70).
- name: Install LLVM and prepend to PATH
run: |
brew install llvm
echo "$(brew --prefix llvm)/bin" >> "$GITHUB_PATH"
- name: Download spc
run: |
curl -fsSL "https://github.com/crazywhalecc/static-php-cli/releases/download/${{ env.SPC_VERSION }}/spc-macos-${{ matrix.spc_arch }}.tar.gz" \
| tar xz -C /usr/local/bin
- name: Download PHP sources
run: |
spc download \
--with-php=${{ inputs.php_version }} \
--for-extensions=${{ env.PHP_EXTENSIONS }} \
--prefer-pre-built
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run spc doctor
run: spc doctor --auto-fix || true
- name: Build libphp.a
run: |
spc build ${{ env.PHP_EXTENSIONS }} \
--build-embed \
--enable-zts \
--no-strip \
--debug
- name: Package SDK
run: |
mkdir -p sdk/lib sdk/include
cp buildroot/lib/libphp.a sdk/lib/
cp -r buildroot/include/php sdk/include/php
tar czf php-sdk-${{ inputs.php_version }}-macos-${{ matrix.arch }}.tar.gz -C sdk .
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: php-sdk-${{ inputs.php_version }}-macos-${{ matrix.arch }}
path: php-sdk-${{ inputs.php_version }}-macos-${{ matrix.arch }}.tar.gz
build-windows:
name: Windows (x86_64)
runs-on: [self-hosted, windows, x64]
# Windows doesn't support pcntl or posix
env:
WIN_PHP_EXTENSIONS: "bcmath,calendar,ctype,curl,dom,exif,fileinfo,filter,gd,hash,iconv,mbstring,mysqli,mysqlnd,openssl,pcre,pdo,pdo_mysql,phar,session,simplexml,sodium,tokenizer,xml,xmlreader,xmlwriter,zip,zlib"
steps:
- name: Clean up previous builds
shell: powershell
run: |
foreach ($dir in @('buildroot', 'source', 'downloads', 'sdk', 'php-sdk-binary-tools')) {
if (Test-Path $dir) { Remove-Item -Recurse -Force $dir }
}
Remove-Item -Force *.tar.gz -ErrorAction SilentlyContinue
- name: Add Git MinGW tools to PATH
shell: powershell
# spc shells out to MinGW utilities (patch, etc.). The fork's spc.exe
# bundles its own micro PHP runtime, so no host PHP install is needed.
run: |
"C:\Program Files\Git\usr\bin" | Out-File -Append -FilePath $env:GITHUB_PATH
- name: Install Visual Studio Build Tools
shell: powershell
# PHP requires MSVC to compile on Windows. Runner image is
# mcr.microsoft.com/windows/servercore:ltsc2025 with no compiler.
# Install Build Tools per-job (~10-15 min). Long-term: dedicated
# php-sdk runner image with VS pre-baked.
#
# Install path: C:\BuildTools (Microsoft's recommended path for
# Server Core containers; nested Program Files paths are flaky).
# spc's findVisualStudio() probes Community/Professional/Enterprise
# under standard Program Files locations, so we junction one of
# those to C:\BuildTools after install.
#
# The bootstrapper (vs_buildtools.exe) exits before the underlying
# installer engine actually finishes on Server Core, so we poll
# for MSBuild.exe rather than trusting its exit code.
run: |
$installPath = "C:\BuildTools"
$msbuild = "$installPath\MSBuild\Current\Bin\MSBuild.exe"
$communityPath = "C:\Program Files\Microsoft Visual Studio\2022\Community"
if (-not (Test-Path $msbuild)) {
Write-Host "Downloading VS Build Tools bootstrapper..."
Invoke-WebRequest -Uri "https://aka.ms/vs/17/release/vs_buildtools.exe" -OutFile vs_buildtools.exe
Write-Host "Launching install (bootstrapper may exit before install completes)..."
$proc = Start-Process -FilePath .\vs_buildtools.exe `
-ArgumentList @(
'--quiet', '--wait', '--norestart', '--nocache',
'--installPath', $installPath,
'--add', 'Microsoft.VisualStudio.Workload.VCTools',
'--includeRecommended'
) -Wait -PassThru -NoNewWindow
Write-Host "Bootstrapper exit code: $($proc.ExitCode)"
Remove-Item vs_buildtools.exe
# Poll for MSBuild.exe; bootstrapper exit is unreliable on Server Core
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$timeoutMin = 20
while (-not (Test-Path $msbuild) -and $sw.Elapsed.TotalMinutes -lt $timeoutMin) {
Start-Sleep -Seconds 30
Write-Host (" ...waiting for VS install ({0:F0}s)" -f $sw.Elapsed.TotalSeconds)
}
if (-not (Test-Path $msbuild)) {
Write-Host "::error::VS install timed out after $timeoutMin min — $msbuild never appeared"
Write-Host "==> Searching for MSBuild.exe anywhere on disk:"
Get-ChildItem -Path C:\ -Recurse -Filter MSBuild.exe -ErrorAction SilentlyContinue |
Select-Object -First 10 |
ForEach-Object { Write-Host " $($_.FullName)" }
Write-Host "==> Recent VS install logs in `$env:TEMP (dd_*.log):"
Get-ChildItem -Path $env:TEMP -Filter 'dd_*.log' -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending |
Select-Object -First 5 |
ForEach-Object {
$kb = [math]::Round($_.Length / 1024)
Write-Host "--- $($_.Name) (${kb}KB) ---"
Get-Content $_.FullName -Tail 80
}
exit 1
}
Write-Host ("MSBuild.exe found after {0:F0}s" -f $sw.Elapsed.TotalSeconds)
} else {
Write-Host "VS Build Tools already present at $installPath"
}
# Junction the path spc's hardcoded check expects -> our install path
if (-not (Test-Path $communityPath)) {
$parent = Split-Path $communityPath -Parent
if (-not (Test-Path $parent)) {
New-Item -ItemType Directory -Path $parent -Force | Out-Null
}
New-Item -ItemType Junction -Path $communityPath -Target $installPath | Out-Null
Write-Host "Junction $communityPath -> $installPath"
}
- name: Download spc
shell: powershell
# Windows uses luthermonson/static-php-cli fork (2.8.5 + embed SAPI patches);
# upstream removed embed support in v3 and won't backport. Other platforms
# still use upstream SPC_VERSION.
run: |
Invoke-WebRequest -Uri "https://github.com/luthermonson/static-php-cli/releases/download/2.8.5%2Bembed-windows/spc-windows-x64.exe" -OutFile spc.exe
"$PWD" | Out-File -Append -FilePath $env:GITHUB_PATH
- name: Download PHP sources
shell: powershell
run: |
spc download `
--with-php=${{ inputs.php_version }} `
--for-extensions=${{ env.WIN_PHP_EXTENSIONS }} `
--prefer-pre-built
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run spc doctor
shell: powershell
# --auto-fix runs install-php-sdk (clones php-sdk-binary-tools, needed
# for 7za.exe at extraction time), install-nasm, install-perl.
# Non-fatal in case any individual check has issues.
run: |
spc doctor --auto-fix
exit 0
- name: Build php8embed (patched spc with embed SAPI support)
shell: powershell
run: |
spc build ${{ env.WIN_PHP_EXTENSIONS }} `
--build-embed `
--enable-zts `
--no-strip `
--debug
- name: Find build outputs
shell: powershell
run: |
Write-Host "==> Searching for php8embed files..."
Get-ChildItem -Recurse -Filter "php8embed.*" | ForEach-Object { Write-Host $_.FullName }
Write-Host "==> Searching for php8ts files..."
Get-ChildItem -Recurse -Filter "php8ts.*" | ForEach-Object { Write-Host $_.FullName }
Write-Host "==> Searching for libphp files..."
Get-ChildItem -Recurse -Filter "libphp.*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_.FullName }
- name: Package SDK
shell: powershell
run: |
New-Item -ItemType Directory -Force -Path sdk/lib, sdk/include
# Find php8embed.lib (import library for linking)
$lib = Get-ChildItem -Recurse -Filter "php8embed.lib" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($lib) {
Copy-Item $lib.FullName sdk/lib/
Write-Host "==> Found php8embed.lib at $($lib.FullName)"
} else {
Write-Error "php8embed.lib not found anywhere in build tree"
exit 1
}
# Find the runtime DLL — spc ZTS builds produce php8ts.dll (not php8embed.dll).
# The embed .lib links against php8ts.dll at runtime.
# Check for php8embed.dll first (windows.php.net style), fall back to php8ts.dll (spc style).
$dll = Get-ChildItem -Recurse -Filter "php8embed.dll" -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $dll) {
$dll = Get-ChildItem -Recurse -Filter "php8ts.dll" -ErrorAction SilentlyContinue | Select-Object -First 1
}
if ($dll) {
# Always ship as php8embed.dll — ephpm expects this name at build time
# (include_bytes! via PHP_EMBED_DLL_PATH) and runtime (delay-load).
Copy-Item $dll.FullName sdk/lib/php8embed.dll
Write-Host "==> Found runtime DLL at $($dll.FullName) -> sdk/lib/php8embed.dll"
} else {
Write-Error "No runtime DLL found (checked php8embed.dll and php8ts.dll)"
exit 1
}
# Optional: libphp.a (static lib, may not exist on Windows)
$static = Get-ChildItem -Recurse -Filter "libphp.a" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($static) {
Copy-Item $static.FullName sdk/lib/
Write-Host "==> Found libphp.a at $($static.FullName)"
}
Copy-Item -Recurse buildroot/include/php sdk/include/php
Write-Host "==> SDK contents:"
Get-ChildItem -Recurse sdk/lib/
tar czf php-sdk-${{ inputs.php_version }}-windows-x86_64.tar.gz -C sdk .
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: php-sdk-${{ inputs.php_version }}-windows-x86_64
path: php-sdk-${{ inputs.php_version }}-windows-x86_64.tar.gz
release:
name: Create Release
needs: [build-linux, build-macos, build-windows]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -lh artifacts/
- name: Create release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ inputs.php_version }}
name: PHP ${{ inputs.php_version }}
body: |
Pre-built PHP embed SAPI SDK for ephpm.
**PHP version:** ${{ inputs.php_version }}
**Extensions:** ${{ env.PHP_EXTENSIONS }}
## Artifacts
| File | Platform |
|------|----------|
| `php-sdk-${{ inputs.php_version }}-linux-x86_64.tar.gz` | Linux x86_64 (musl static) |
| `php-sdk-${{ inputs.php_version }}-linux-aarch64.tar.gz` | Linux aarch64 (musl static) |
| `php-sdk-${{ inputs.php_version }}-macos-aarch64.tar.gz` | macOS Apple Silicon |
| `php-sdk-${{ inputs.php_version }}-windows-x86_64.tar.gz` | Windows x86_64 (ZTS) |
files: artifacts/*.tar.gz