Pre-built PHP embed SAPI static libraries (libphp.a / php8embed.lib) plus headers, for the OS/arch/PHP-version combinations ePHPm supports.
Built with static-php-cli — specifically the luthermonson/static-php-cli fork, pinned by SPC_VERSION in .github/workflows/build.yml. Every SDK is a spc build --build-embed output: a static libphp.a, never a shared libphp.so.
| Platform | Tarball suffix | Output |
|---|---|---|
| Linux x86_64 (glibc, floor 2.28) | -linux-x86_64-gnu |
lib/libphp.a + headers, ZTS |
| Linux aarch64 (glibc, floor 2.28) | -linux-aarch64-gnu |
lib/libphp.a + headers, ZTS |
| Linux x86_64 (musl, fully static) | -linux-x86_64 |
lib/libphp.a + headers, ZTS |
| Linux aarch64 (musl, fully static) | -linux-aarch64 |
lib/libphp.a + headers, ZTS |
| macOS aarch64 | -macos-aarch64 |
lib/libphp.a + headers, ZTS |
| Windows x86_64 | -windows-x86_64 |
lib/php8embed.lib + dep .libs + headers, ZTS |
| Linux x86_64 (glibc, NTS) | -linux-x86_64-gnu-nts |
lib/libphp.a + headers, non-thread-safe |
| Linux aarch64 (glibc, NTS) | -linux-aarch64-gnu-nts |
lib/libphp.a + headers, non-thread-safe |
The glibc floor is 2.28 (built on AlmaLinux 8 with gcc-toolset-13), so a consumer binary linked against these runs on RHEL/Alma 8, Ubuntu 20.04+, Debian 10+, Amazon Linux 2023 and Fedora 40+.
ZTS is the default and is unsuffixed. ePHPm is a threaded server and links the ZTS SDK; renaming those assets breaks it. The -gnu-nts variants exist for consumers that cannot use a thread-safe build.
Detect which one you have from include/php/main/php_config.h: thread-safe builds define ZTS 1, non-thread-safe builds do not define ZTS at all.
NTS tarballs:
- are Linux-glibc only (x86_64 and aarch64),
- are not part of a
platform=allbuild and do not gate release completeness — a failed NTS build never blocks a release, - carry
ffiin addition to the shared extension set (see below), - are kept current only for the minors listed under
minors_ntsinversions.json.
lib/ libphp.a (or php8embed.lib) + every static dep archive
include/php/
main/ includes php_config.h (ZTS marker) and php_version.h
Zend/
TSRM/
ext/
sapi/embed/php_embed.h
bin/php-config Linux and macOS only
THIRD-PARTY-NOTICES.txt
Assets are named:
php-sdk-{php_version}-{os}-{arch}[-gnu][-nts].tar.gz
A relocatable POSIX-sh shim, generated by tools/mk-sdk-metadata.sh at package time. It resolves its own prefix at run time, so the tarball can be extracted anywhere. It exists because build scripts that expect a system PHP (php-config --includes) run it unconditionally.
Supported: --prefix, --includes, --include-dir, --ldflags, --libs, --extension-dir, --version, --vernum, --php-sapis, --help.
Deliberately refused, with a message and a non-zero exit, rather than answered with a plausible lie:
--php-binary— this SDK ships no PHP executable.--configure-options— static-php-cli strips the configure line from the build.
--libs enumerates the static archives in lib/. It is a starting point, not a verified link line: whole-archive and symbol-ordering decisions belong to the consumer. See ePHPm's crates/ephpm/build.rs for a working static link against these tarballs, including the -Wl,--export-dynamic that lets extension=-loaded .so files resolve zend_* symbols against the host binary.
No php-config is generated on Windows — it is a shell script and nothing in the MSVC toolchain consumes one.
Compiled into libphp.a on Linux and macOS:
bcmath, bz2, calendar, ctype, curl, dom, exif, fileinfo, filter, ftp, gd,
gettext, gmp, hash, iconv, intl, mbregex, mbstring, mysqli, mysqlnd, opcache,
openssl, pcntl, pcre, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, pgsql, phar,
posix, session, shmop, simplexml, soap, sockets, sodium, sqlite3, sysvmsg,
sysvsem, sysvshm, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, zlib
The NTS variants additionally include ffi.
Windows drops the Unix-only entries (pcntl, posix, sysv*), plus gmp, pgsql and pdo_pgsql, which static-php-cli cannot build statically on Windows today. It also does not yet carry shmop or sockets — PHP supports both there, but neither has been validated through spc's Windows toolchain from this repo.
ffi is not in the shared extension set on purpose. static-php-cli's ext-ffi passes --enable-zend-signals, and extension arguments land after the target arguments on the configure line, so it would override the --disable-zend-signals that spc emits for ZTS builds — silently changing signal behavior in the SDK ePHPm links. NTS builds emit no --disable-zend-signals, so ffi rides along there.
Loadable shared ZTS extensions (igbinary, msgpack, apcu, redis, mongodb) are a separate artifact built by .github/workflows/extensions.yml and published under ext-<version> tags. That catalog is ZTS-only by design: Debian and Sury publish no ZTS builds, which is the gap it fills. There is no NTS catalog.
# full release
gh workflow run build.yml -f php_version=8.5.2
# one platform (uploads to the existing release, leaves other assets alone)
gh workflow run build.yml -f php_version=8.5.2 -f platform=linux-aarch64-gnu
# non-thread-safe variant
gh workflow run build.yml -f php_version=8.4.23 -f platform=linux-x86_64-gnu-ntsAny dispatch from a branch other than main MUST set release_tag_suffix. On 2026-07-13 a validation build from a side branch uploaded to the plain v8.5.7 tag and overwrote four production assets. The input exists to make that impossible:
gh workflow run build.yml --ref my-branch \
-f php_version=8.5.7 -f platform=linux-x86_64-gnu -f release_tag_suffix=-mytestwatch-php.yml polls php.net every 6 hours, mirrors new php-src tarballs to the php-sources release tag, and dispatches builds for anything missing.
Builds do not fetch PHP or its GNU dependencies from upstream. Both come from this repo's own php-sources release tag, fetched with plain curl and handed to static-php-cli as file:// custom URLs.
Asset on php-sources |
Populated by | Consumed by |
|---|---|---|
php-X.Y.Z.tar.gz |
watch-php.yml |
build.yml, extensions.yml |
libiconv-*, gettext-*, ncurses-*, libunistring-*, libidn2-* |
mirror-deps.yml |
build.yml, extensions.yml |
gnu-deps-manifest.txt, SHA256SUMS |
mirror-deps.yml |
build.yml, extensions.yml |
Those libraries resolve through static-php-cli type: filelist sources pointed at https://ftpmirror.gnu.org/gnu/<pkg>/. That host is a redirector to volunteer backend mirrors and returns HTTP errors when it picks a bad one. None of the five has a source-mirror fallback in spc, so a single bad backend fails the whole spc download and therefore the build. That took every scheduled build in this repo down from 2026-08-06 onward.
gmp is also GNU-hosted but is not in the mirror: it is the one GNU dependency with its own source-mirror fallback in spc, so mirror-deps.yml resolved it from there and correctly did not select it. The mirrored set is whatever spc actually resolved from ftpmirror.gnu.org, not a fixed list.
Refresh the mirror when you want newer dependency versions:
gh workflow run mirror-deps.yml # resolve + upload
gh workflow run mirror-deps.yml -f dry_run=true # resolve + print onlymirror-deps.yml runs on a GitHub-hosted runner (different egress from the self-hosted fleet) but resolves inside the same almalinux:8 container with the same SPC_TARGET, so it picks exactly the artifacts the fleet would have. The set is derived from spc's own downloads/.cache.json — every artifact whose source URL is on ftpmirror.gnu.org.
Note the tradeoff: filelist sources normally track the newest tarball in the directory index on every build. Once mirrored, builds pin to whatever was current when mirror-deps.yml last ran. That is the same tradeoff php-src already makes, and it stops builds drifting underneath us.
If the manifest is missing from the release tag, builds log a warning and fall back to fetching from upstream GNU mirrors — the pre-mirror behaviour, and the known failure mode.
ePHPm's release workflow:
- name: Download PHP SDK
run: |
gh release download v${{ matrix.php }} \
--repo ephpm/php-sdk \
--pattern "php-sdk-*-${{ matrix.os }}-${{ matrix.arch }}.tar.gz" \
--output php-sdk.tar.gz
mkdir -p php-sdk && tar xzf php-sdk.tar.gz -C php-sdkthen builds with PHP_SDK_PATH=php-sdk cargo build --release.
The MIT license in this repository covers the workflows and scripts here. It does not cover the contents of the published tarballs: those are an aggregate of PHP (PHP License 3.01 / Zend Engine License 2.00) and roughly twenty upstream libraries, each under its own terms — including a bundled libstdc++.a carrying the GCC Runtime Library Exception.
Every tarball ships a THIRD-PARTY-NOTICES.txt listing the components, their SPDX identifiers, and where to get the full license texts. Read it before redistributing anything built from this SDK.