Compare commits

...

47 Commits
2.8.1 ... main

Author SHA1 Message Date
Marc
4625c6a885
update default php version to 8.5 (#1058) 2026-03-11 15:09:07 +07:00
henderkes
85b0cd8b4b only disable when building ftp static, shared is fine 2026-03-11 13:54:24 +07:00
henderkes
1fcb74ad9b swoole-ftp conflicts with ftp 2026-03-11 13:42:38 +07:00
henderkes
1049a3ce66 curl is always supported now (swoole no longer supports php < 8.1) 2026-03-11 10:32:58 +07:00
henderkes
1b8b53d47f update swoole args for 6.2 2026-03-11 10:19:08 +07:00
henderkes
a232f578a4 test bulk 2026-03-11 10:11:39 +07:00
henderkes
70285cb53b actually update to 8.5 2026-03-11 09:48:50 +07:00
henderkes
a335d050cf cs fix 2026-03-11 09:46:41 +07:00
henderkes
ef4b2997a7 test 2026-03-11 09:45:56 +07:00
henderkes
901da8fa41 remove ldtl from odbc libs private (using built in ltdl) 2026-03-11 09:43:02 +07:00
henderkes
e49a5d7a50 make php 8.5 default 2026-03-11 09:42:39 +07:00
Jerry Ma
281b958075
Fix grpc build (#1055) 2026-03-10 20:35:51 +09:00
Marc
e31f64864e
fix: FrankenPHP build args (#1057) 2026-03-10 18:13:34 +07:00
Kévin Dunglas
92f5b56c74
fix: FrankenPHP build args 2026-03-10 11:57:23 +01:00
Jerry Ma
2350d2d5ca
Merge branch 'main' into fix/grpc-build 2026-03-10 14:52:21 +09:00
crazywhalecc
086c855a43
Use custom config.m4 for grpc extension 2026-03-10 13:49:53 +08:00
crazywhalecc
4fa5292913
Use custom config.m4 for grpc extension 2026-03-10 13:49:34 +08:00
Marc
9634b8bcda
set custom binary name for frankenphp, allow linking against system openssl (fix mssql issues) (#1056) 2026-03-10 11:11:36 +07:00
Marc
5d5a50a33c
Update src/SPC/builder/LibraryBase.php
Co-authored-by: Jerry Ma <jesse2061@outlook.com>
2026-03-10 10:57:49 +07:00
henderkes
1edf14e642 set custom binary name for frankenphp 2026-03-10 08:52:15 +07:00
henderkes
2277390a1a fix removeConfigureArgs in UnixAutoconfExecutor.php 2026-03-10 08:49:56 +07:00
henderkes
f93ad27c17 allow using some libs as system provided (work around mssql linking vs system openssl) 2026-03-10 08:47:38 +07:00
henderkes
b690566b39 simplify rm command 2026-03-10 08:43:48 +07:00
henderkes
16e772e1a8 add back in zig workaround as 0.16.x is not released yet 2026-03-10 08:42:17 +07:00
crazywhalecc
ad356b4a23
Fix grpc build 2026-03-09 20:12:14 +08:00
Jerry Ma
8c4e3d58a3
Add php-src mirror and use gmp mirror site (#1048) 2026-03-06 15:25:38 +09:00
Marc
8a51d64685
Add condition for ffi patch (#1050) 2026-03-06 12:59:23 +07:00
crazywhalecc
055bc7bc3c
Add condition for ffi patch 2026-03-06 13:46:55 +08:00
Marc
7d7902e0e9
Update build flags for FrankenPHP in UnixBuilderBase (#1042) 2026-02-24 06:08:14 +07:00
Kévin Dunglas
2a8fa7d155
Update build flags for FrankenPHP in UnixBuilderBase 2026-02-23 16:29:43 +01:00
Marc
67ef8f6608
fix redownloading go-xcaddy every time, version 2.8.3 (#1034) 2026-02-17 22:36:27 +07:00
henderkes
d83a597689 unquote the string in case a shell script passes it stupidly 2026-02-17 21:49:30 +07:00
henderkes
5623fed37f fix redownloading go-xcaddy every time 2026-02-17 21:05:18 +07:00
Marc
38140d115f
libavif needs at least one encoder to work (#1033) 2026-02-17 19:59:46 +07:00
henderkes
98117c3a04 remove pre built 2026-02-17 19:58:03 +07:00
Marc
b01d3ce12c
Merge branch 'main' into feat/avif-dec 2026-02-17 19:18:38 +07:00
henderkes
608c915e14 should depend on it instead 2026-02-17 19:14:29 +07:00
henderkes
c680299654 libavif needs at least one encoder to work 2026-02-17 19:12:19 +07:00
Marc
794ab16b32
add input with-suggested-libs for build command (#1032) 2026-02-16 18:38:35 +07:00
tricker
661723c99a
change logs name
Co-authored-by: Marc <m@pyc.ac>
2026-02-16 12:26:49 +01:00
Yoram
d9834d05c6 upload debug logs on 'build php' failures 2026-02-16 11:35:42 +01:00
Yoram
9a53ef3498 add input with-suggested-libs for build command 2026-02-13 14:35:01 +01:00
Marc
f680731f9d
fix: Postgres build with ancient libc (#1029) 2026-02-11 17:42:36 +01:00
Jerry Ma
0fe1442f7e
Bump version from 2.8.0 to 2.8.2 2026-02-12 00:02:38 +08:00
Jerry Ma
1e4780397b
Update test-extensions.php for PHP versions and extensions
Commented out older PHP versions and Windows 2025 in the test configuration. Updated the extensions to test for Linux and Darwin.
2026-02-11 23:32:19 +08:00
Kévin Dunglas
6b67cb90fc
fix: Postgres build with ancient libc 2026-02-11 16:24:13 +01:00
Jerry Ma
b89ff3c083
Add com_dotnet extension (#1023) 2026-02-03 19:08:19 +08:00
24 changed files with 222 additions and 86 deletions

View File

@ -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: false
debug:
description: Show full build logs
type: boolean
@ -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
@ -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
@ -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"

View File

@ -43,6 +43,14 @@
"calendar": {
"type": "builtin"
},
"com_dotnet": {
"support": {
"BSD": "no",
"Linux": "no",
"Darwin": "no"
},
"type": "builtin"
},
"ctype": {
"type": "builtin"
},
@ -244,6 +252,7 @@
"arg-type-unix": "enable-path",
"cpp-extension": true,
"lib-depends": [
"grpc",
"zlib",
"openssl",
"libcares"

View File

@ -373,6 +373,15 @@
],
"static-libs-windows": [
"avif.lib"
],
"lib-depends": [
"libaom"
],
"lib-suggests": [
"libwebp",
"libjpeg",
"libxml2",
"libpng"
]
},
"libcares": {
@ -853,6 +862,9 @@
},
"openssl": {
"source": "openssl",
"pkg-configs": [
"openssl"
],
"static-libs-unix": [
"libssl.a",
"libcrypto.a"
@ -965,6 +977,11 @@
},
"unixodbc": {
"source": "unixodbc",
"pkg-configs": [
"odbc",
"odbccr",
"odbcinst"
],
"static-libs-unix": [
"libodbc.a",
"libodbccr.a",
@ -1006,6 +1023,9 @@
},
"zlib": {
"source": "zlib",
"pkg-configs": [
"zlib"
],
"static-libs-unix": [
"libz.a"
],
@ -1019,6 +1039,9 @@
},
"zstd": {
"source": "zstd",
"pkg-configs": [
"libzstd"
],
"static-libs-unix": [
"libzstd.a"
],

View File

@ -361,7 +361,7 @@
},
"gmp": {
"type": "filelist",
"url": "https://gmplib.org/download/gmp/",
"url": "https://ftp.gnu.org/gnu/gmp/",
"regex": "/href=\"(?<file>gmp-(?<version>[^\"]+)\\.tar\\.xz)\"/",
"provide-pre-built": true,
"alt": {
@ -526,7 +526,7 @@
"libavif": {
"type": "ghtar",
"repo": "AOMediaCodec/libavif",
"provide-pre-built": true,
"provide-pre-built": false,
"license": {
"type": "file",
"path": "LICENSE"

View File

@ -34,7 +34,7 @@ use Symfony\Component\Console\Application;
*/
final class ConsoleApplication extends Application
{
public const string VERSION = '2.8.0';
public const string VERSION = '2.8.3';
public function __construct()
{

View File

@ -96,7 +96,8 @@ class Extension
fn ($x) => $x->getStaticLibFiles(),
$this->getLibraryDependencies(recursive: true)
);
return implode(' ', $ret);
$libs = implode(' ', $ret);
return deduplicate_flags($libs);
}
/**

View File

@ -365,6 +365,27 @@ abstract class LibraryBase
protected function isLibraryInstalled(): bool
{
if ($pkg_configs = Config::getLib(static::NAME, 'pkg-configs', [])) {
$pkg_config_path = getenv('PKG_CONFIG_PATH') ?: '';
$search_paths = array_unique(array_filter(explode(is_unix() ? ':' : ';', $pkg_config_path)));
foreach ($pkg_configs as $name) {
$found = false;
foreach ($search_paths as $path) {
if (file_exists($path . "/{$name}.pc")) {
$found = true;
break;
}
}
if (!$found) {
return false;
}
}
// allow using system dependencies if pkg_config_path is explicitly defined
if (count($search_paths) > 1) {
return true;
}
}
foreach (Config::getLib(static::NAME, 'static-libs', []) as $name) {
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
return false;

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('com_dotnet')]
class com_dotnet extends Extension
{
public function getWindowsConfigureArg(bool $shared = false): string
{
return '--enable-com-dotnet=yes';
}
}

View File

@ -5,11 +5,21 @@ declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\linux\SystemUtil;
use SPC\store\SourcePatcher;
use SPC\util\CustomExt;
#[CustomExt('ffi')]
class ffi extends Extension
{
public function patchBeforeBuildconf(): bool
{
if (PHP_OS_FAMILY === 'Linux' && SystemUtil::getOSRelease()['dist'] === 'centos') {
return SourcePatcher::patchFfiCentos7FixO3strncmp();
}
return false;
}
public function getUnixConfigureArg(bool $shared = false): string
{
return '--with-ffi' . ($shared ? '=shared' : '') . ' --enable-zend-signals';

View File

@ -11,7 +11,6 @@ use SPC\store\FileSystem;
use SPC\util\CustomExt;
use SPC\util\GlobalEnvManager;
use SPC\util\SPCConfigUtil;
use SPC\util\SPCTarget;
#[CustomExt('grpc')]
class grpc extends Extension
@ -21,18 +20,50 @@ class grpc extends Extension
if ($this->builder instanceof WindowsBuilder) {
throw new ValidationException('grpc extension does not support windows yet');
}
// Fix deprecated PHP API usage in call.c
FileSystem::replaceFileStr(
$this->source_dir . '/src/php/ext/grpc/call.c',
"{$this->source_dir}/src/php/ext/grpc/call.c",
'zend_exception_get_default(TSRMLS_C),',
'zend_ce_exception,',
);
if (SPCTarget::getTargetOS() === 'Darwin') {
FileSystem::replaceFileRegex(
$this->source_dir . '/config.m4',
'/GRPC_LIBDIR=.*$/m',
'GRPC_LIBDIR=' . BUILD_LIB_PATH . "\n" . 'LDFLAGS="$LDFLAGS -framework CoreFoundation"'
);
}
$config_m4 = <<<'M4'
PHP_ARG_ENABLE(grpc, [whether to enable grpc support], [AS_HELP_STRING([--enable-grpc], [Enable grpc support])])
if test "$PHP_GRPC" != "no"; then
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/include)
PHP_ADD_INCLUDE(PHP_EXT_SRCDIR()/src/php/ext/grpc)
GRPC_LIBDIR=@@build_lib_path@@
PHP_ADD_LIBPATH($GRPC_LIBDIR)
PHP_ADD_LIBRARY(grpc,,GRPC_SHARED_LIBADD)
LIBS="-lpthread $LIBS"
PHP_ADD_LIBRARY(pthread)
case $host in
*darwin*)
PHP_ADD_LIBRARY(c++,1,GRPC_SHARED_LIBADD)
;;
*)
PHP_ADD_LIBRARY(stdc++,1,GRPC_SHARED_LIBADD)
PHP_ADD_LIBRARY(rt,,GRPC_SHARED_LIBADD)
PHP_ADD_LIBRARY(rt)
;;
esac
PHP_NEW_EXTENSION(grpc, @grpc_c_files@, $ext_shared, , -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1)
PHP_SUBST(GRPC_SHARED_LIBADD)
PHP_INSTALL_HEADERS([ext/grpc], [php_grpc.h])
fi
M4;
$replace = get_pack_replace();
// load grpc c files from src/php/ext/grpc
$c_files = glob($this->source_dir . '/src/php/ext/grpc/*.c');
$replace['@grpc_c_files@'] = implode(" \\\n ", array_map(fn ($f) => 'src/php/ext/grpc/' . basename($f), $c_files));
$config_m4 = str_replace(array_keys($replace), array_values($replace), $config_m4);
file_put_contents($this->source_dir . '/config.m4', $config_m4);
copy($this->source_dir . '/src/php/ext/grpc/php_grpc.h', $this->source_dir . '/php_grpc.h');
return true;
}
@ -48,7 +79,6 @@ class grpc extends Extension
public function patchBeforeMake(): bool
{
parent::patchBeforeMake();
// add -Wno-strict-prototypes
GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS=' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') . ' -Wno-strict-prototypes');
return true;
}

View File

@ -50,19 +50,16 @@ class swoole extends Extension
// commonly used feature: coroutine-time
$arg .= ' --enable-swoole-coro-time --with-pic';
$arg .= ' --enable-swoole-ssh --enable-swoole-curl';
$arg .= $this->builder->getOption('enable-zts') ? ' --enable-swoole-thread --disable-thread-context' : ' --disable-swoole-thread --enable-thread-context';
// required features: curl, openssl (but curl hook is buggy for php 8.0)
$arg .= $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl';
$arg .= ' --enable-openssl';
// additional features that only require libraries
$arg .= $this->builder->getLib('libcares') ? ' --enable-cares' : '';
$arg .= $this->builder->getLib('brotli') ? (' --enable-brotli --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
$arg .= $this->builder->getLib('nghttp2') ? (' --with-nghttp2-dir=' . BUILD_ROOT_PATH) : '';
$arg .= $this->builder->getLib('zstd') ? ' --enable-zstd' : '';
$arg .= $this->builder->getLib('liburing') ? ' --enable-iouring' : '';
$arg .= $this->builder->getLib('liburing') ? ' --enable-iouring --enable-uring-socket' : '';
$arg .= $this->builder->getExt('sockets') ? ' --enable-sockets' : '';
// enable additional features that require the pdo extension, but conflict with pdo_* extensions
@ -74,6 +71,7 @@ class swoole extends Extension
$config = (new SPCConfigUtil($this->builder))->getLibraryConfig($this->builder->getLib('unixodbc'));
$arg .= ' --with-swoole-odbc=unixODBC,' . BUILD_ROOT_PATH . ' SWOOLE_ODBC_LIBS="' . $config['libs'] . '"';
}
$arg .= $this->builder->getExt('ftp')?->isBuildStatic() ? ' --disable-swoole-ftp' : ' --enable-swoole-ftp';
if ($this->getExtVersion() >= '6.1.0') {
$arg .= ' --enable-swoole-stdext';

View File

@ -72,6 +72,10 @@ trait UnixSystemUtilTrait
if (!is_file($symbol_file)) {
throw new SPCInternalException("The symbol file {$symbol_file} does not exist, please check if nm command is available.");
}
// https://github.com/ziglang/zig/issues/24662
if (ToolchainManager::getToolchainClass() === ZigToolchain::class) {
return '-Wl,--export-dynamic'; // needs release 0.16, can be removed then
}
// macOS/zig
if (SPCTarget::getTargetOS() !== 'Linux' || ToolchainManager::getToolchainClass() === ZigToolchain::class) {
return "-Wl,-exported_symbols_list,{$symbol_file}";

View File

@ -365,6 +365,7 @@ abstract class UnixBuilderBase extends BuilderBase
$frankenphpAppPath = $this->getOption('with-frankenphp-app');
if ($frankenphpAppPath) {
$frankenphpAppPath = trim($frankenphpAppPath, "\"'");
if (!is_dir($frankenphpAppPath)) {
throw new WrongUsageException("The path provided to --with-frankenphp-app is not a valid directory: {$frankenphpAppPath}");
}
@ -455,6 +456,8 @@ abstract class UnixBuilderBase extends BuilderBase
'CGO_LDFLAGS' => "{$this->arch_ld_flags} {$staticFlags} {$config['ldflags']} {$libs}",
'XCADDY_GO_BUILD_FLAGS' => '-buildmode=pie ' .
'-ldflags \"-linkmode=external ' . $extLdFlags . ' ' .
'-X \'github.com/caddyserver/caddy/v2/modules/caddyhttp.ServerHeader=FrankenPHP Caddy\' ' .
'-X \'github.com/caddyserver/caddy/v2.CustomBinaryName=frankenphp\' ' .
'-X \'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ' .
"v{$frankenPhpVersion} PHP {$libphpVersion} Caddy'\\\" " .
"-tags={$muslTags}nobadger,nomysql,nopgx{$nobrotli}{$nowatcher}",

View File

@ -11,6 +11,11 @@ trait libavif
protected function build(): void
{
UnixCMakeExecutor::create($this)
->optionalLib('libaom', '-DAVIF_CODEC_AOM=SYSTEM', '-DAVIF_CODEC_AOM=OFF')
->optionalLib('libsharpyuv', '-DAVIF_LIBSHARPYUV=SYSTEM', '-DAVIF_LIBSHARPYUV=OFF')
->optionalLib('libjpeg', '-DAVIF_JPEG=SYSTEM', '-DAVIF_JPEG=OFF')
->optionalLib('libxml2', '-DAVIF_LIBXML2=SYSTEM', '-DAVIF_LIBXML2=OFF')
->optionalLib('libpng', '-DAVIF_LIBPNG=SYSTEM', '-DAVIF_LIBPNG=OFF')
->addConfigureArgs('-DAVIF_LIBYUV=OFF')
->build();
// patch pkgconfig

View File

@ -4,29 +4,14 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\store\FileSystem;
use SPC\util\PkgConfigUtil;
use SPC\util\SPCConfigUtil;
use SPC\util\SPCTarget;
trait postgresql
{
public function patchBeforeBuild(): bool
{
// fix aarch64 build on glibc 2.17 (e.g. CentOS 7)
if (SPCTarget::getLibcVersion() === '2.17' && GNU_ARCH === 'aarch64') {
try {
FileSystem::replaceFileStr("{$this->source_dir}/src/port/pg_popcount_aarch64.c", 'HWCAP_SVE', '0');
FileSystem::replaceFileStr(
"{$this->source_dir}/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->source_dir}/src/interfaces/libpq/Makefile", 'invokes exit\'; exit 1;', 'invokes exit\';');
// disable shared libs build
@ -108,8 +93,7 @@ trait postgresql
// remove dynamic libs
shell()->cd($this->source_dir . '/build')
->exec("rm -rf {$this->getBuildRootPath()}/lib/*.so.*")
->exec("rm -rf {$this->getBuildRootPath()}/lib/*.so")
->exec("rm -rf {$this->getBuildRootPath()}/lib/*.so*")
->exec("rm -rf {$this->getBuildRootPath()}/lib/*.dylib");
FileSystem::replaceFileStr("{$this->getLibDir()}/pkgconfig/libpq.pc", '-lldap', '-lldap -llber');

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\util\executor\UnixAutoconfExecutor;
trait unixodbc
@ -30,7 +31,15 @@ trait unixodbc
'--enable-gui=no',
)
->make();
$this->patchPkgconfPrefix(['odbc.pc', 'odbccr.pc', 'odbcinst.pc']);
$pkgConfigs = ['odbc.pc', 'odbccr.pc', 'odbcinst.pc'];
$this->patchPkgconfPrefix($pkgConfigs);
foreach ($pkgConfigs as $file) {
FileSystem::replaceFileStr(
BUILD_LIB_PATH . "/pkgconfig/{$file}",
'$(top_build_prefix)libltdl/libltdlc.la',
''
);
}
$this->patchLaDependencyPrefix();
}
}

View File

@ -30,7 +30,7 @@ class DownloadCommand extends BaseCommand
$this->addArgument('sources', InputArgument::REQUIRED, 'The sources will be compiled, comma separated');
$this->addOption('shallow-clone', null, null, 'Clone shallow');
$this->addOption('with-openssl11', null, null, 'Use openssl 1.1');
$this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format (default 8.4)', '8.4');
$this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format (default 8.5)', '8.5');
$this->addOption('clean', null, null, 'Clean old download cache and source before fetch');
$this->addOption('all', 'A', null, 'Fetch all sources that static-php-cli needed');
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');

View File

@ -20,9 +20,9 @@ class SwitchPhpVersionCommand extends BaseCommand
$this->addArgument(
'php-major-version',
InputArgument::REQUIRED,
'PHP major version (supported: 7.4, 8.0, 8.1, 8.2, 8.3, 8.4)',
'PHP major version (supported: 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5)',
null,
fn () => ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
fn () => ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5']
);
$this->no_motd = true;
@ -32,7 +32,7 @@ class SwitchPhpVersionCommand extends BaseCommand
public function handle(): int
{
$php_ver = $this->input->getArgument('php-major-version');
if (!in_array($php_ver, ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'])) {
if (!in_array($php_ver, ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'])) {
// match x.y.z
preg_match('/^\d+\.\d+\.\d+$/', $php_ver, $matches);
if (!$matches) {

View File

@ -22,7 +22,7 @@ class SourcePatcher
FileSystem::addSourceExtractHook('swoole', [__CLASS__, 'patchSwoole']);
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchPhpLibxml212']);
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchGDWin32']);
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchFfiCentos7FixO3strncmp']);
// FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchFfiCentos7FixO3strncmp']);
FileSystem::addSourceExtractHook('sqlsrv', [__CLASS__, 'patchSQLSRVWin32']);
FileSystem::addSourceExtractHook('pdo_sqlsrv', [__CLASS__, 'patchSQLSRVWin32']);
FileSystem::addSourceExtractHook('pdo_sqlsrv', [__CLASS__, 'patchSQLSRVPhp85']);

View File

@ -30,8 +30,8 @@ class GoXcaddy extends CustomPackage
public function fetch(string $name, bool $force = false, ?array $config = null): void
{
$pkgroot = PKG_ROOT_PATH;
$go_exec = "{$pkgroot}/{$name}/bin/go";
$xcaddy_exec = "{$pkgroot}/{$name}/bin/xcaddy";
$go_exec = "{$pkgroot}/go-xcaddy/bin/go";
$xcaddy_exec = "{$pkgroot}/go-xcaddy/bin/xcaddy";
if ($force) {
FileSystem::removeDir("{$pkgroot}/{$name}");
}

View File

@ -6,15 +6,21 @@ namespace SPC\store\source;
use JetBrains\PhpStorm\ArrayShape;
use SPC\exception\DownloaderException;
use SPC\exception\SPCException;
use SPC\store\Downloader;
class PhpSource extends CustomSourceBase
{
public const NAME = 'php-src';
public const string NAME = 'php-src';
public const array WEB_PHP_DOMAINS = [
'https://www.php.net',
'https://phpmirror.static-php.dev',
];
public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWNLOAD_SOURCE): void
{
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.4';
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.5';
if ($major === 'git') {
Downloader::downloadSource('php-src', ['type' => 'git', 'url' => 'https://github.com/php/php-src.git', 'rev' => 'master'], $force);
} else {
@ -28,21 +34,26 @@ class PhpSource extends CustomSourceBase
#[ArrayShape(['type' => 'string', 'path' => 'string', 'rev' => 'string', 'url' => 'string'])]
public function getLatestPHPInfo(string $major_version): array
{
// 查找最新的小版本号
foreach (self::WEB_PHP_DOMAINS as $domain) {
try {
$info = json_decode(Downloader::curlExec(
url: "https://www.php.net/releases/index.php?json&version={$major_version}",
url: "{$domain}/releases/index.php?json&version={$major_version}",
retries: (int) getenv('SPC_DOWNLOAD_RETRIES') ?: 0
), true);
if (!isset($info['version'])) {
throw new DownloaderException("Version {$major_version} not found.");
}
$version = $info['version'];
// 从官网直接下载
return [
'type' => 'url',
'url' => "https://www.php.net/distributions/php-{$version}.tar.xz",
'url' => "{$domain}/distributions/php-{$version}.tar.xz",
];
} catch (SPCException) {
logger()->warning('Failed to fetch latest PHP version for major version {$major_version} from {$domain}, trying next mirror if available.');
continue;
}
}
// exception if all mirrors failed
throw new DownloaderException("Failed to fetch latest PHP version for major version {$major_version} from all tried mirrors.");
}
}

View File

@ -393,7 +393,7 @@ class ConfigValidator
}
// check php-version
if (isset($craft['php-version'])) {
// validdate version, accept 8.x, 7.x, 8.x.x, 7.x.x, 8, 7
// validate version, accept 8.x, 7.x, 8.x.x, 7.x.x, 8, 7
$version = strval($craft['php-version']);
if (!preg_match('/^(\d+)(\.\d+)?(\.\d+)?$/', $version, $matches)) {
throw new ValidationException('Craft file php-version is invalid');

View File

@ -16,12 +16,11 @@ class UnixAutoconfExecutor extends Executor
protected array $configure_args = [];
protected array $ignore_args = [];
public function __construct(protected BSDLibraryBase|LinuxLibraryBase|MacOSLibraryBase $library)
{
parent::__construct($library);
$this->initShell();
$this->configure_args = $this->getDefaultConfigureArgs();
}
/**
@ -29,19 +28,12 @@ class UnixAutoconfExecutor extends Executor
*/
public function configure(...$args): static
{
// remove all the ignored args
$args = array_merge($args, $this->getDefaultConfigureArgs(), $this->configure_args);
$args = array_diff($args, $this->ignore_args);
$args = array_merge($args, $this->configure_args);
$configure_args = implode(' ', $args);
return $this->seekLogFileOnException(fn () => $this->shell->exec("./configure {$configure_args}"));
}
public function getConfigureArgsString(): string
{
return implode(' ', array_merge($this->getDefaultConfigureArgs(), $this->configure_args));
}
/**
* Run make
*
@ -111,7 +103,7 @@ class UnixAutoconfExecutor extends Executor
*/
public function removeConfigureArgs(...$args): static
{
$this->ignore_args = [...$this->ignore_args, ...$args];
$this->configure_args = array_diff($this->configure_args, $args);
return $this;
}
@ -133,8 +125,8 @@ class UnixAutoconfExecutor extends Executor
private function getDefaultConfigureArgs(): array
{
return [
'--disable-shared',
'--enable-static',
'--disable-shared',
"--prefix={$this->library->getBuildRootPath()}",
'--with-pic',
'--enable-pic',

View File

@ -14,8 +14,8 @@ declare(strict_types=1);
// test php version (8.1 ~ 8.4 available, multiple for matrix)
$test_php_version = [
// '8.1',
'8.2',
'8.3',
// '8.2',
// '8.3',
'8.4',
'8.5',
// 'git',
@ -25,17 +25,17 @@ $test_php_version = [
$test_os = [
'macos-15-intel', // bin/spc for x86_64
'macos-15', // bin/spc for arm64
'ubuntu-latest', // bin/spc-alpine-docker for x86_64
// 'ubuntu-latest', // bin/spc-alpine-docker for x86_64
'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
'ubuntu-24.04', // bin/spc for x86_64
// 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
// 'ubuntu-24.04-arm', // bin/spc for arm64
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
'ubuntu-24.04-arm', // bin/spc for arm64
// 'windows-2022', // .\bin\spc.ps1
// 'windows-2025',
];
// whether enable thread safe
$zts = true;
$zts = false;
$no_strip = false;
@ -50,13 +50,13 @@ $prefer_pre_built = false;
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
$extensions = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'mysqli,gmp',
'Windows' => 'bcmath',
'Linux', 'Darwin' => 'pdo_odbc',
'Windows' => 'com_dotnet',
};
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
$shared_extensions = match (PHP_OS_FAMILY) {
'Linux' => 'grpc,mysqlnd_parsec,mysqlnd_ed25519',
'Linux' => '',
'Darwin' => '',
'Windows' => '',
};
@ -66,7 +66,7 @@ $with_suggested_libs = false;
// If you want to test extra libs for extensions, add them below (comma separated, example `libwebp,libavif`). Unnecessary, when $with_suggested_libs is true.
$with_libs = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'libwebp',
'Linux', 'Darwin' => '',
'Windows' => '',
};
@ -74,7 +74,7 @@ $with_libs = match (PHP_OS_FAMILY) {
// You can use `common`, `bulk`, `minimal` or `none`.
// note: combination is only available for *nix platform. Windows must use `none` combination
$base_combination = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'minimal',
'Linux', 'Darwin' => 'bulk',
'Windows' => 'none',
};
@ -89,7 +89,7 @@ function _getCombination(string $type = 'common'): string
'common' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,xml,mbstring,mbregex,' .
'mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,session,simplexml,soap,sockets,' .
'sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip',
'bulk' => 'apcu,bcmath,bz2,calendar,ctype,curl,dba,dom,event,exif,fileinfo,filter,ftp,gd,gmp,iconv,imagick,imap,' .
'bulk' => 'apcu,bcmath,bz2,calendar,ctype,curl,dba,dom,event,exif,fileinfo,filter,ftp,gd,gmp,iconv,imagick,' .
'intl,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,pgsql,phar,' .
'posix,protobuf,readline,redis,session,shmop,simplexml,soap,sockets,sodium,sqlite3,swoole,sysvmsg,sysvsem,' .
'sysvshm,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib',