Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6b67cb9
fix: Postgres build with ancient libc
dunglas Feb 11, 2026
1e47803
Update test-extensions.php for PHP versions and extensions
crazywhalecc Feb 11, 2026
0fe1442
Bump version from 2.8.0 to 2.8.2
crazywhalecc Feb 11, 2026
f680731
fix: Postgres build with ancient libc (#1029)
henderkes Feb 11, 2026
9a53ef3
add input with-suggested-libs for build command
yoramdelangen Feb 13, 2026
d9834d0
upload debug logs on 'build php' failures
yoramdelangen Feb 16, 2026
661723c
change logs name
yoramdelangen Feb 16, 2026
794ab16
add input with-suggested-libs for build command (#1032)
henderkes Feb 16, 2026
c680299
libavif needs at least one encoder to work
henderkes Feb 17, 2026
608c915
should depend on it instead
henderkes Feb 17, 2026
b01d3ce
Merge branch 'main' into feat/avif-dec
henderkes Feb 17, 2026
98117c3
remove pre built
henderkes Feb 17, 2026
38140d1
libavif needs at least one encoder to work (#1033)
henderkes Feb 17, 2026
5623fed
fix redownloading go-xcaddy every time
henderkes Feb 17, 2026
d83a597
unquote the string in case a shell script passes it stupidly
henderkes Feb 17, 2026
67ef8f6
fix redownloading go-xcaddy every time, version 2.8.3 (#1034)
henderkes Feb 17, 2026
471df00
Use StaticPHP instead of static-php-cli
crazywhalecc Feb 19, 2026
d495455
Remove motd for lint-config command
crazywhalecc Feb 23, 2026
2a8fa7d
Update build flags for FrankenPHP in UnixBuilderBase
dunglas Feb 23, 2026
7d7902e
Update build flags for FrankenPHP in UnixBuilderBase (#1042)
henderkes Feb 23, 2026
a357510
Add frankenphp building message for console output
crazywhalecc Feb 26, 2026
28bbdf5
Merge branch 'main' into v3-refactor/extensions
crazywhalecc Feb 26, 2026
08595cc
Add PatchDescription attribute to libacl for Unix FPM_EXTRA_LIBS fix
crazywhalecc Feb 26, 2026
0f012f2
Rename tracker file from .spc-tracker.json to .build.json
crazywhalecc Feb 26, 2026
a57b48f
Add macOS check to patchBeforePHPConfigure for explicit_bzero detection
crazywhalecc Feb 26, 2026
3238c44
Refactor FrankenPHP build and smoke test processes for Unix
crazywhalecc Feb 26, 2026
bb257cf
Add extension apcu
crazywhalecc Feb 26, 2026
e927994
Add DumpStagesCommand to dump package stages and their locations
crazywhalecc Feb 26, 2026
da1f348
Update src/StaticPHP/Package/PhpExtensionPackage.php
crazywhalecc Feb 27, 2026
0e80f29
Add DumpCapabilitiesCommand to output installable and buildable capab…
crazywhalecc Feb 27, 2026
d6ec0b7
Remove aarch64 build fix for glibc 2.17 from patchBeforeBuild method …
crazywhalecc Feb 27, 2026
cfce177
Add beforeMakeUnix method to patch TSRM.h for musl TLS symbol visibility
crazywhalecc Feb 27, 2026
28c82b8
Add PackageInfoCommand to display package configuration information a…
crazywhalecc Feb 27, 2026
f9fe2ad
Trim quotes from frankenphp app path to ensure valid directory check
crazywhalecc Feb 27, 2026
b3d67b9
Add tryPatchMakefileUnix method to fix //lib path in Makefile for Lin…
crazywhalecc Feb 27, 2026
8c7d113
Apply smoke test control option for frankenphp
crazywhalecc Feb 27, 2026
fa17596
Enable suggested libs by default in build configurations for Unix and…
crazywhalecc Feb 27, 2026
7623b9e
Deprecate '--debug' option and update logging level handling
crazywhalecc Feb 28, 2026
c218aef
Add doctor cache check and version management to ensure environment v…
crazywhalecc Feb 28, 2026
d316684
Add optional package support for libaom, libsharpyuv, libjpeg, libxml…
crazywhalecc Feb 28, 2026
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
19 changes: 19 additions & 0 deletions .github/workflows/build-unix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ on:
description: Prefer pre-built binaries (reduce build time)
type: boolean
default: true
with-suggested-libs:
description: Build with suggested libs
type: boolean
default: true
debug:
description: Show full build logs
type: boolean
Expand Down Expand Up @@ -86,6 +90,10 @@ on:
description: Prefer pre-built binaries (reduce build time)
type: boolean
default: true
with-suggested-libs:
description: Include suggested libs
type: boolean
default: false
debug:
description: Show full build logs
type: boolean
Expand Down Expand Up @@ -157,6 +165,9 @@ jobs:
if [ ${{ inputs.prefer-pre-built }} == true ]; then
DOWN_CMD="$DOWN_CMD --prefer-pre-built"
fi
if [ ${{ inputs.with-suggested-libs }} == true ]; then
BUILD_CMD="$BUILD_CMD --with-suggested-libs"
fi
if [ ${{ inputs.build-cli }} == true ]; then
BUILD_CMD="$BUILD_CMD --build-cli"
fi
Expand Down Expand Up @@ -202,6 +213,14 @@ jobs:
# if: ${{ failure() }}
# uses: mxschmitt/action-tmate@v3

# Upload debug logs
- if: ${{ inputs.debug && failure() }}
name: "Upload build logs on failure"
uses: actions/upload-artifact@v4
with:
name: spc-logs-${{ inputs.php-version }}-${{ inputs.os }}
path: log/*.log

# Upload cli executable
- if: ${{ inputs.build-cli == true }}
name: "Upload PHP cli SAPI"
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/build-windows-x86_64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ on:
description: prefer pre-built binaries (reduce build time)
type: boolean
default: true
with-suggested-libs:
description: Build with suggested libs
type: boolean
default: true
debug:
description: enable debug logs
type: boolean
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ packlib_files.txt
.php-cs-fixer.cache
.phpunit.result.cache

# doctor cache fallback (when ~/.cache/spc/ is not writable)
.spc-doctor.lock

# exclude self-runtime
/bin/*
!/bin/spc*
Expand Down Expand Up @@ -61,3 +64,6 @@ log/
# spc.phar
spc.phar
spc.exe

# dumped files from StaticPHP v3
/dump-*.json
8 changes: 4 additions & 4 deletions README-zh.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# static-php-cli
# StaticPHP

[![English readme](https://img.shields.io/badge/README-English%20%F0%9F%87%AC%F0%9F%87%A7-moccasin?style=flat-square)](README.md)
[![Chinese readme](https://img.shields.io/badge/README-%E4%B8%AD%E6%96%87%20%F0%9F%87%A8%F0%9F%87%B3-moccasin?style=flat-square)](README-zh.md)
[![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases)
[![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)

**static-php-cli** 是一个用于构建静态、独立 PHP 运行时的强大工具,支持众多流行扩展
**StaticPHP** 是一个用于构建静态编译可执行文件(包括 PHP、扩展等)的强大工具

## 特性

Expand Down Expand Up @@ -80,7 +80,7 @@ download-options:

### 3. 静态 PHP 使用

现在您可以将 static-php-cli 构建的二进制文件复制到另一台机器上,无需依赖即可运行:
现在您可以将 StaticPHP 构建的二进制文件复制到另一台机器上,无需依赖即可运行:

```
# php-cli
Expand All @@ -97,7 +97,7 @@ buildroot/bin/php-fpm -v

## 文档

当前 README 包含基本用法。有关 static-php-cli 的所有功能,
当前 README 包含基本用法。有关 StaticPHP 的所有功能,
请访问 <https://static-php.dev>。

## 直接下载
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# static-php-cli
# StaticPHP

[![Chinese readme](https://img.shields.io/badge/README-%E4%B8%AD%E6%96%87%20%F0%9F%87%A8%F0%9F%87%B3-moccasin?style=flat-square)](README-zh.md)
[![English readme](https://img.shields.io/badge/README-English%20%F0%9F%87%AC%F0%9F%87%A7-moccasin?style=flat-square)](README.md)
[![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases)
[![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)

**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
with popular extensions.
**StaticPHP** is a powerful tool designed for building portable executables including PHP, extensions, and more.

## Features

Expand Down Expand Up @@ -81,7 +80,7 @@ Run command:

### 3. Static PHP usage

Now you can copy binaries built by static-php-cli to another machine and run with no dependencies:
Now you can copy binaries built by StaticPHP to another machine and run with no dependencies:

```
# php-cli
Expand All @@ -98,7 +97,7 @@ buildroot/bin/php-fpm -v

## Documentation

The current README contains basic usage. For all the features of static-php-cli,
The current README contains basic usage. For all the features of StaticPHP,
see <https://static-php.dev> .

## Direct Download
Expand Down
9 changes: 9 additions & 0 deletions config/lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,15 @@
],
"static-libs-windows": [
"avif.lib"
],
"lib-depends": [
"libaom"
],
"lib-suggests": [
"libwebp",
"libjpeg",
"libxml2",
"libpng"
]
},
"libcares": {
Expand Down
11 changes: 11 additions & 0 deletions config/pkg/ext/ext-apcu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ext-apcu:
type: php-extension
artifact:
source:
type: url
url: 'https://pecl.php.net/get/APCu'
extract: php-src/ext/apcu
filename: apcu.tgz
metadata:
license-files: [LICENSE]
license: PHP-3.01
7 changes: 7 additions & 0 deletions config/pkg/lib/libavif.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,12 @@ libavif:
metadata:
license-files: [LICENSE]
license: BSD-2-Clause
depends:
- libaom
suggests:
- libwebp
- libjpeg
- libxml2
- libpng
static-libs@unix:
- libavif.a
2 changes: 1 addition & 1 deletion config/source.json
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@
"libavif": {
"type": "ghtar",
"repo": "AOMediaCodec/libavif",
"provide-pre-built": true,
"provide-pre-built": false,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down
2 changes: 2 additions & 0 deletions src/Package/Library/libacl.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use StaticPHP\Attribute\Package\BeforeStage;
use StaticPHP\Attribute\Package\BuildFor;
use StaticPHP\Attribute\Package\Library;
use StaticPHP\Attribute\PatchDescription;
use StaticPHP\Package\LibraryPackage;
use StaticPHP\Runtime\Executor\UnixAutoconfExecutor;
use StaticPHP\Util\FileSystem;
Expand All @@ -16,6 +17,7 @@
class libacl
{
#[BeforeStage('php', [php::class, 'makeForUnix'], 'libacl')]
#[PatchDescription('Fix FPM_EXTRA_LIBS to avoid linking with acl on Unix')]
public function patchBeforeMakePhpUnix(LibraryPackage $lib): void
{
$file_path = SOURCE_PATH . '/php-src/Makefile';
Expand Down
5 changes: 5 additions & 0 deletions src/Package/Library/libavif.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class libavif
public function buildUnix(LibraryPackage $lib): void
{
UnixCMakeExecutor::create($lib)
->optionalPackage('libaom', '-DAVIF_CODEC_AOM=SYSTEM', '-DAVIF_CODEC_AOM=OFF')
->optionalPackage('libsharpyuv', '-DAVIF_LIBSHARPYUV=SYSTEM', '-DAVIF_LIBSHARPYUV=OFF')
->optionalPackage('libjpeg', '-DAVIF_JPEG=SYSTEM', '-DAVIF_JPEG=OFF')
->optionalPackage('libxml2', '-DAVIF_LIBXML2=SYSTEM', '-DAVIF_LIBXML2=OFF')
->optionalPackage('libpng', '-DAVIF_LIBPNG=SYSTEM', '-DAVIF_LIBPNG=OFF')
->addConfigureArgs('-DAVIF_LIBYUV=OFF')
->build();
// patch pkgconfig
Expand Down
22 changes: 5 additions & 17 deletions src/Package/Library/postgresql.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use StaticPHP\Attribute\Package\Library;
use StaticPHP\Attribute\Package\PatchBeforeBuild;
use StaticPHP\Attribute\PatchDescription;
use StaticPHP\Exception\FileSystemException;
use StaticPHP\Package\LibraryPackage;
use StaticPHP\Package\PackageBuilder;
use StaticPHP\Package\PackageInstaller;
Expand All @@ -27,28 +26,17 @@ class postgresql extends LibraryPackage
#[PatchDescription('Patch to avoid explicit_bzero detection issues on some systems')]
public function patchBeforePHPConfigure(TargetPackage $package): void
{
shell()->cd($package->getSourceDir())
->exec('sed -i.backup "s/ac_cv_func_explicit_bzero\" = xyes/ac_cv_func_explicit_bzero\" = x_fake_yes/" ./configure');
if (SystemTarget::getTargetOS() === 'Darwin') {
// on macOS, explicit_bzero is available but causes build failure due to detection issues, so we fake it as unavailable
shell()->cd($package->getSourceDir())
->exec('sed -i.backup "s/ac_cv_func_explicit_bzero\" = xyes/ac_cv_func_explicit_bzero\" = x_fake_yes/" ./configure');
}
}

#[PatchBeforeBuild]
#[PatchDescription('Various patches before building PostgreSQL')]
public function patchBeforeBuild(): bool
{
// fix aarch64 build on glibc 2.17 (e.g. CentOS 7)
if (SystemTarget::getLibcVersion() === '2.17' && SystemTarget::getTargetArch() === 'aarch64') {
try {
FileSystem::replaceFileStr("{$this->getSourceDir()}/src/port/pg_popcount_aarch64.c", 'HWCAP_SVE', '0');
FileSystem::replaceFileStr(
"{$this->getSourceDir()}/src/port/pg_crc32c_armv8_choose.c",
'#if defined(__linux__) && !defined(__aarch64__) && !defined(HWCAP2_CRC32)',
'#if defined(__linux__) && !defined(HWCAP_CRC32)'
);
} catch (FileSystemException) {
// allow file not-existence to make it compatible with old and new version
}
}

// skip the test on platforms where libpq infrastructure may be provided by statically-linked libraries
FileSystem::replaceFileStr("{$this->getSourceDir()}/src/interfaces/libpq/Makefile", 'invokes exit\'; exit 1;', 'invokes exit\';');
// disable shared libs build
Expand Down
36 changes: 32 additions & 4 deletions src/Package/Target/php.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

namespace Package\Target;

use Package\Target\php\frankenphp;
use Package\Target\php\unix;
use Package\Target\php\windows;
use StaticPHP\Artifact\ArtifactCache;
use StaticPHP\Attribute\Package\BeforeStage;
use StaticPHP\Attribute\Package\Info;
use StaticPHP\Attribute\Package\InitPackage;
Expand Down Expand Up @@ -42,6 +44,7 @@ class php extends TargetPackage
{
use unix;
use windows;
use frankenphp;

/** @var string[] Supported major PHP versions */
public const array SUPPORTED_MAJOR_VERSIONS = ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'];
Expand Down Expand Up @@ -102,6 +105,24 @@ public static function getPHPVersion(?string $from_custom_source = null, bool $r
throw new WrongUsageException('PHP version file format is malformed, please remove "./source/php-src" dir and download/extract again');
}

/**
* Get PHP version from source archive filename
*
* @return null|string PHP version (e.g., "8.4.0")
*/
public static function getPHPVersionFromArchive(bool $return_null_if_failed = false): ?string
{
$archives = ApplicationContext::get(ArtifactCache::class)->getSourceInfo('php-src');
$filename = $archives['filename'] ?? '';
if (!preg_match('/php-(\d+\.\d+\.\d+(?:RC\d+|alpha\d+|beta\d+)?)\.tar\.(?:gz|bz2|xz)/', $filename, $match)) {
if ($return_null_if_failed) {
return null;
}
throw new WrongUsageException('PHP source archive filename format is malformed (got: ' . $filename . ')');
}
return $match[1];
}

#[InitPackage]
public function init(TargetPackage $package): void
{
Expand All @@ -119,6 +140,7 @@ public function init(TargetPackage $package): void
$package->addBuildOption('with-config-file-scan-dir', null, InputOption::VALUE_REQUIRED, 'Set the directory to scan for .ini files after reading php.ini', PHP_OS_FAMILY === 'Windows' ? null : '/usr/local/etc/php/conf.d');
$package->addBuildOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
$package->addBuildOption('enable-zts', null, null, 'Enable thread safe support');
$package->addBuildOption('no-smoke-test', null, InputOption::VALUE_OPTIONAL, 'Disable smoke test for specific SAPIs, or all if no value provided', false);

// phpmicro build options
if ($package->getName() === 'php' || $package->getName() === 'php-micro') {
Expand Down Expand Up @@ -198,6 +220,11 @@ public function resolveBuild(TargetPackage $package, PackageInstaller $installer
$installer->addBuildPackage('php-embed');
}

// frankenphp depends on embed SAPI (libphp.a)
if ($package->getName() === 'frankenphp') {
$installer->addBuildPackage('php-embed');
}

return [...$extensions_pkg, ...$additional_packages];
}

Expand All @@ -209,7 +236,7 @@ public function validate(Package $package): void
if (!$package->getBuildOption('enable-zts')) {
throw new WrongUsageException('FrankenPHP SAPI requires ZTS enabled PHP, build with `--enable-zts`!');
}
// frankenphp doesn't support windows, BSD is currently not supported by static-php-cli
// frankenphp doesn't support windows, BSD is currently not supported by StaticPHP
if (!in_array(PHP_OS_FAMILY, ['Linux', 'Darwin'])) {
throw new WrongUsageException('FrankenPHP SAPI is only available on Linux and macOS!');
}
Expand Down Expand Up @@ -247,6 +274,7 @@ public function info(Package $package, PackageInstaller $installer): array
'Build Target' => getenv('SPC_TARGET') ?: '',
'Build Toolchain' => ToolchainManager::getToolchainClass(),
'Build SAPI' => implode(', ', $sapis),
'PHP Version' => self::getPHPVersion(return_null_if_failed: true) ?? self::getPHPVersionFromArchive(return_null_if_failed: true) ?? 'Unknown',
'Static Extensions (' . count($static_extensions) . ')' => implode(',', array_map(fn ($x) => substr($x->getName(), 4), $static_extensions)),
'Shared Extensions (' . count($shared_extensions) . ')' => implode(',', $shared_extensions),
'Install Packages (' . count($install_packages) . ')' => implode(',', array_map(fn ($x) => $x->getName(), $install_packages)),
Expand All @@ -272,10 +300,10 @@ public function beforeBuild(PackageBuilder $builder, Package $package): void
// Patch StaticPHP version
// detect patch (remove this when 8.3 deprecated)
$file = FileSystem::readFile("{$package->getSourceDir()}/main/main.c");
if (!str_contains($file, 'static-php-cli.version')) {
if (!str_contains($file, 'StaticPHP.version')) {
$version = SPC_VERSION;
logger()->debug('Inserting static-php-cli.version to php-src');
$file = str_replace('PHP_INI_BEGIN()', "PHP_INI_BEGIN()\n\tPHP_INI_ENTRY(\"static-php-cli.version\",\t\"{$version}\",\tPHP_INI_ALL,\tNULL)", $file);
logger()->debug('Inserting StaticPHP.version to php-src');
$file = str_replace('PHP_INI_BEGIN()', "PHP_INI_BEGIN()\n\tPHP_INI_ENTRY(\"StaticPHP.version\",\t\"{$version}\",\tPHP_INI_ALL,\tNULL)", $file);
FileSystem::writeFile("{$package->getSourceDir()}/main/main.c", $file);
}

Expand Down
Loading