Merge branch 'main' into feat/xdebug-dynamic

This commit is contained in:
Marc 2025-03-23 10:13:56 +01:00 committed by GitHub
commit 71b52e58b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 133 additions and 22 deletions

View File

@ -589,6 +589,12 @@
"openssl" "openssl"
] ]
}, },
"mimalloc": {
"source": "mimalloc",
"static-libs-unix": [
"mimalloc.o"
]
},
"ncurses": { "ncurses": {
"source": "ncurses", "source": "ncurses",
"static-libs-unix": [ "static-libs-unix": [

View File

@ -636,6 +636,16 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"mimalloc": {
"type": "ghtagtar",
"repo": "microsoft/mimalloc",
"match": "v2.+",
"provide-pre-built": false,
"license": {
"type": "file",
"path": "LICENSE"
}
},
"mongodb": { "mongodb": {
"type": "ghrel", "type": "ghrel",
"repo": "mongodb/mongo-php-driver", "repo": "mongodb/mongo-php-driver",

View File

@ -76,8 +76,7 @@ and this extension cannot be compiled into php by static linking, so it cannot b
## xdebug ## xdebug
1. Xdebug is a Zend extension. The functions of Xdebug depend on PHP's Zend engine and underlying code. 1. Xdebug is only buildable as a shared extension. On Linux, you need to use static-php-cli with SPC_LIBC=glibc and then compile php-xdebug from source with the option `--with-php-config=/path/to/buildroot/bin/php-config`.
If you want to statically compile it into PHP, you may need a huge amount of patch code, which is not feasible.
2. The macOS platform can compile an xdebug extension under PHP compiled on the same platform, 2. The macOS platform can compile an xdebug extension under PHP compiled on the same platform,
extract the `xdebug.so` file, and then use the `--no-strip` parameter in static-php-cli to retain the debug symbol table and add the `ffi` extension. extract the `xdebug.so` file, and then use the `--no-strip` parameter in static-php-cli to retain the debug symbol table and add the `ffi` extension.
The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`. The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`.
@ -149,3 +148,9 @@ Parallel is only supported on PHP 8.0 ZTS and above.
1. The [SPX extension](https://github.com/NoiseByNorthwest/php-spx) only supports NTS mode. 1. The [SPX extension](https://github.com/NoiseByNorthwest/php-spx) only supports NTS mode.
2. SPX does not support Windows, and the official repository does not support static compilation. static-php-cli uses a [modified version](https://github.com/static-php/php-spx). 2. SPX does not support Windows, and the official repository does not support static compilation. static-php-cli uses a [modified version](https://github.com/static-php/php-spx).
## mimalloc
1. This is not technically an extension, but a library.
2. Building with `--with-libs="mimalloc"` on Linux or macOS will override the default allocator.
3. This is experimental for now, but is recommended in threaded environments.

View File

@ -70,7 +70,7 @@ bin/spc build gd --with-libs=freetype,libjpeg,libavif,libwebp --build-cli
## xdebug ## xdebug
1. Xdebug 是一个 Zend 扩展Xdebug 的功能依赖于 PHP 的 Zend 引擎和底层代码,如果要将其静态编译到 PHP 中,可能需要巨量的 patch 代码,这是不可行的 1. Xdebug 只能作为共享扩展构建。在 Linux 上,您需要使用带有 `SPC_LIBC=glibc` 的 static-php-cli然后使用选项 `--with-php-config=/path/to/buildroot/bin/php-config` 从源代码编译 php-xdebug
2. macOS 平台可以通过在相同平台编译的 PHP 下编译一个 xdebug 扩展,并提取其中的 `xdebug.so` 文件,再在 static-php-cli 中使用 `--no-strip` 参数保留调试符号表,同时加入 `ffi` 扩展。 2. macOS 平台可以通过在相同平台编译的 PHP 下编译一个 xdebug 扩展,并提取其中的 `xdebug.so` 文件,再在 static-php-cli 中使用 `--no-strip` 参数保留调试符号表,同时加入 `ffi` 扩展。
编译的 `./php` 二进制可以通过指定 INI 配置并运行,例如`./php -d 'zend_extension=xdebug.so' your-code.php` 编译的 `./php` 二进制可以通过指定 INI 配置并运行,例如`./php -d 'zend_extension=xdebug.so' your-code.php`
@ -136,3 +136,9 @@ parallel 扩展只支持 PHP 8.0 及以上版本,并只支持 ZTS 构建(`--
1. [SPX 扩展](https://github.com/NoiseByNorthwest/php-spx) 只支持非线程模式。 1. [SPX 扩展](https://github.com/NoiseByNorthwest/php-spx) 只支持非线程模式。
2. SPX 目前不支持 Windows且官方仓库也不支持静态编译static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。 2. SPX 目前不支持 Windows且官方仓库也不支持静态编译static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。
## mimalloc
1. 从技术上讲,这不是扩展,而是一个库。
2. 在 Linux 或 macOS 上使用 `--with-libs="mimalloc"` 进行构建将覆盖默认分配器。
3. 目前,这还处于实验阶段,但建议在线程环境中使用。

View File

@ -150,12 +150,13 @@ class LinuxBuilder extends UnixBuilderBase
$enable_micro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO; $enable_micro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
$enable_embed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED; $enable_embed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
$mimallocLibs = $this->getLib('mimalloc') !== null ? BUILD_LIB_PATH . '/mimalloc.o ' : '';
// prepare build php envs // prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([ $envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'), 'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
'CPPFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS'), 'CPPFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS'),
'LDFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS'), 'LDFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS'),
'LIBS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LIBS'), 'LIBS' => $mimallocLibs . getenv('SPC_CMD_VAR_PHP_CONFIGURE_LIBS'),
]); ]);
// process micro upx patch if micro sapi enabled // process micro upx patch if micro sapi enabled
@ -310,9 +311,15 @@ class LinuxBuilder extends UnixBuilderBase
shell()->cd(SOURCE_PATH . '/php-src') shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install"); ->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install");
FileSystem::replaceFileStr(BUILD_BIN_PATH . '/php-config', 'prefix=""', 'prefix="' . BUILD_ROOT_PATH . '"');
FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', "prefix=''", "prefix='" . BUILD_ROOT_PATH . "'"); FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', "prefix=''", "prefix='" . BUILD_ROOT_PATH . "'");
FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', 's##', 's#/usr/local#'); FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', 's##', 's#/usr/local#');
$php_config_str = FileSystem::readFile(BUILD_BIN_PATH . '/php-config');
str_replace('prefix=""', 'prefix="' . BUILD_ROOT_PATH . '"', $php_config_str);
// move mimalloc to the beginning of libs
$php_config_str = preg_replace('/(libs=")(.*?)\s*(' . preg_quote(BUILD_LIB_PATH, '/') . '\/mimalloc\.o)\s*(.*?)"/', '$1$3 $2 $4"', $php_config_str);
// move lstdc++ to the end of libs
$php_config_str = preg_replace('/(libs=")(.*?)\s*(-lstdc\+\+)\s*(.*?)"/', '$1$2 $4 $3"', $php_config_str);
FileSystem::writeFile(BUILD_BIN_PATH . '/php-config', $php_config_str);
} }
private function getMakeExtraVars(): array private function getMakeExtraVars(): array

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class mimalloc extends LinuxLibraryBase
{
use \SPC\builder\unix\library\mimalloc;
public const NAME = 'mimalloc';
}

View File

@ -148,10 +148,12 @@ class MacOSBuilder extends UnixBuilderBase
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED; $enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
// prepare build php envs // prepare build php envs
$mimallocLibs = $this->getLib('mimalloc') !== null ? BUILD_LIB_PATH . '/mimalloc.o ' : '';
$envs_build_php = SystemUtil::makeEnvVarString([ $envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'), 'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
'CPPFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS'), 'CPPFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS'),
'LDFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS'), 'LDFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS'),
'LIBS' => $mimallocLibs . getenv('SPC_CMD_VAR_PHP_CONFIGURE_LIBS'),
]); ]);
if ($this->getLib('postgresql')) { if ($this->getLib('postgresql')) {
@ -298,9 +300,13 @@ class MacOSBuilder extends UnixBuilderBase
->exec('rm ' . BUILD_ROOT_PATH . '/lib/libphp.a') ->exec('rm ' . BUILD_ROOT_PATH . '/lib/libphp.a')
->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o') ->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o')
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o'); ->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o');
FileSystem::replaceFileStr(BUILD_BIN_PATH . '/php-config', 'prefix=""', 'prefix="' . BUILD_ROOT_PATH . '"');
FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', "prefix=''", "prefix='" . BUILD_ROOT_PATH . "'"); FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', "prefix=''", "prefix='" . BUILD_ROOT_PATH . "'");
FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', 's##', 's#/usr/local#'); FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', 's##', 's#/usr/local#');
$php_config_str = FileSystem::readFile(BUILD_BIN_PATH . '/php-config');
str_replace('prefix=""', 'prefix="' . BUILD_ROOT_PATH . '"', $php_config_str);
// move mimalloc to the beginning of libs
$php_config_str = preg_replace('/(libs=")(.*?)\s*(' . preg_quote(BUILD_LIB_PATH, '/') . '\/mimalloc\.o)\s*(.*?)"/', '$1$3 $2 $4"', $php_config_str);
FileSystem::writeFile(BUILD_BIN_PATH . '/php-config', $php_config_str);
} }
private function getMakeExtraVars(): array private function getMakeExtraVars(): array

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class mimalloc extends MacOSLibraryBase
{
use \SPC\builder\unix\library\mimalloc;
public const NAME = 'mimalloc';
}

View File

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait mimalloc
{
/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build(): void
{
$args = '';
if (getenv('SPC_LIBC') === 'musl') {
$args .= '-DMI_LIBC_MUSL=ON ';
}
$args .= '-DMI_BUILD_SHARED=OFF ';
$args .= '-DMI_INSTALL_TOPLEVEL=ON ';
FileSystem::resetDir($this->source_dir . '/build');
shell()->cd($this->source_dir . '/build')
->execWithEnv(
'cmake ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
$args .
'..'
)
->execWithEnv("make -j{$this->builder->concurrency}")
->execWithEnv('make install');
}
}

View File

@ -69,14 +69,19 @@ class Downloader
retry: self::getRetryTime() retry: self::getRetryTime()
), true); ), true);
if (($source['prefer-stable'] ?? false) === false) { $url = null;
$url = $data[0]['tarball_url']; for ($i = 0; $i < count($data); ++$i) {
} else { if (($data[$i]['prerelease'] ?? false) === true && ($source['prefer-stable'] ?? false)) {
$id = 0; continue;
while (($data[$id]['prerelease'] ?? false) === true) { }
++$id; if (!($source['match'] ?? null)) {
$url = $data[$i]['tarball_url'] ?? null;
break;
}
if (preg_match('|' . $source['match'] . '|', $data[$i]['tarball_url'])) {
$url = $data[$i]['tarball_url'];
break;
} }
$url = $data[$id]['tarball_url'] ?? null;
} }
if (!$url) { if (!$url) {
throw new DownloaderException("failed to find {$name} source"); throw new DownloaderException("failed to find {$name} source");

View File

@ -42,6 +42,10 @@ class SPCConfigUtil
if ($this->builder->hasCpp()) { if ($this->builder->hasCpp()) {
$libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++';
} }
// mimalloc must come first
if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) {
$libs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $libs);
}
return [ return [
'cflags' => $cflags, 'cflags' => $cflags,
'ldflags' => $ldflags, 'ldflags' => $ldflags,

View File

@ -6,12 +6,12 @@ declare(strict_types=1);
/** /**
* This is GitHub Actions automatic test extension args generator. * This is GitHub Actions automatic test extension args generator.
* You can edit $extensions, $with_libs and $base_combination. * You can edit $test_php_version, $test_os, $zts, $no_strip, $upx, $prefer_pre_built, $extensions, $with_libs and $base_combination.
*/ */
// --------------------------------- edit area --------------------------------- // --------------------------------- edit area ---------------------------------
// test php version // test php version (8.1 ~ 8.4 available, multiple for matrix)
$test_php_version = [ $test_php_version = [
'8.1', '8.1',
'8.2', '8.2',
@ -21,10 +21,10 @@ $test_php_version = [
// test os (macos-13, macos-14, ubuntu-latest, windows-latest are available) // test os (macos-13, macos-14, ubuntu-latest, windows-latest are available)
$test_os = [ $test_os = [
// 'macos-13', 'macos-13',
// 'macos-14', 'macos-14',
// 'ubuntu-latest', 'ubuntu-latest',
'windows-latest', // 'windows-latest',
]; ];
// whether enable thread safe // whether enable thread safe
@ -40,13 +40,13 @@ $prefer_pre_built = false;
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
$extensions = match (PHP_OS_FAMILY) { $extensions = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'gd', 'Linux', 'Darwin' => '',
'Windows' => 'bz2,ctype,curl,dom,filter,gd,iconv,mbstring,opcache,openssl,pdo,pdo_sqlite,phar,session,simplexml,sqlite3,tokenizer,xml,xmlwriter,yaml,zip,zlib', 'Windows' => 'bz2,ctype,curl,dom,filter,gd,iconv,mbstring,opcache,openssl,pdo,pdo_sqlite,phar,session,simplexml,sqlite3,tokenizer,xml,xmlwriter,yaml,zip,zlib',
}; };
// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`). // If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`).
$with_libs = match (PHP_OS_FAMILY) { $with_libs = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'freetype', 'Linux', 'Darwin' => 'mimalloc',
'Windows' => 'libjpeg,libavif,freetype,libwebp', 'Windows' => 'libjpeg,libavif,freetype,libwebp',
}; };
@ -54,7 +54,7 @@ $with_libs = match (PHP_OS_FAMILY) {
// You can use `common`, `bulk`, `minimal` or `none`. // You can use `common`, `bulk`, `minimal` or `none`.
// note: combination is only available for *nix platform. Windows must use `none` combination // note: combination is only available for *nix platform. Windows must use `none` combination
$base_combination = match (PHP_OS_FAMILY) { $base_combination = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'minimal', 'Linux', 'Darwin' => 'bulk',
'Windows' => 'none', 'Windows' => 'none',
}; };