Build PHP SDK #34
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |