Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
656a58c
remove source dir after successful build in CI environment
henderkes Dec 18, 2025
0247458
we were installing to wrong dir if source name != lib name
henderkes Dec 18, 2025
ce44e00
@crazywhalecc how to use patch points to delete source dirs?
henderkes Dec 18, 2025
037d224
why does phpstan think this is necessary?
henderkes Dec 18, 2025
e677be7
remove
henderkes Dec 18, 2025
9e051c8
fix: check for link first before checking for is_dir
henderkes Dec 18, 2025
e1a14bb
fix implicit include
henderkes Dec 18, 2025
53f7cde
fix swoole compilation with php 8.5.1
henderkes Dec 18, 2025
6b52000
fix downloader selecting drafts
henderkes Dec 20, 2025
f7ca621
Test
crazywhalecc Dec 26, 2025
9a681a9
add mariadb mysqlnd plugins
henderkes Dec 27, 2025
09b89a3
WIP: use system libraries for grpc without building our own grpc lib
henderkes Dec 27, 2025
e952f1c
we don't even need to build grpc library for grpc extension...
henderkes Dec 27, 2025
5ef4623
grpc will fail for php 8.5, it's not updated yet
henderkes Dec 27, 2025
93a3590
factor grpc extension out to ext-grpc, keep library for now, even tho…
henderkes Dec 28, 2025
2f31226
make grpc php 8.5 compatible
henderkes Dec 28, 2025
e7a88f1
enable fat for gmp when next version releases
henderkes Dec 29, 2025
08388c0
force enable tailcall vm with zig
henderkes Dec 29, 2025
7688a55
don't get zig master branch
henderkes Dec 29, 2025
022fdb2
fix no-strip
henderkes Dec 29, 2025
a06cc32
pin libpng to released tags, not git
henderkes Dec 30, 2025
64f7a35
don't need it anymore
henderkes Jan 1, 2026
d1b1949
use OPENSSL_CONF directory for openssl default configuration
henderkes Jan 2, 2026
fff2484
postgresql doesn't build under c23
henderkes Jan 2, 2026
559a290
use little trick to order libargon2 before libsodium
henderkes Jan 2, 2026
890ff47
our memcache patch prevents shared building
henderkes Jan 3, 2026
54001ab
simplify logic a bit
henderkes Jan 3, 2026
1be353f
more concise message
henderkes Jan 3, 2026
76025b9
missing space
henderkes Jan 3, 2026
6bbb3c9
remove -release handling functionality
henderkes Jan 3, 2026
f8b0c2c
add release thing to extension build too
henderkes Jan 3, 2026
94644d3
fix
henderkes Jan 3, 2026
3a17cec
deploy extensions with -release flag too
henderkes Jan 3, 2026
34910d1
add patch point for shared ext build
henderkes Jan 4, 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
3 changes: 1 addition & 2 deletions bin/spc-alpine-docker
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ RUN apk update; \
wget \
xz \
gettext-dev \
binutils-gold \
patchelf
binutils-gold

RUN curl -#fSL https://dl.static-php.dev/static-php-cli/bulk/php-8.4.4-cli-linux-\$(uname -m).tar.gz | tar -xz -C /usr/local/bin && \
chmod +x /usr/local/bin/php
Expand Down
5 changes: 0 additions & 5 deletions bin/spc-gnu-docker
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,6 @@ RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc
RUN source /etc/bashrc
RUN yum install -y which

RUN curl -fsSL -o patchelf.tgz https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-$SPC_USE_ARCH.tar.gz && \
mkdir -p /patchelf && \
tar -xzf patchelf.tgz -C /patchelf --strip-components=1 && \
cp /patchelf/bin/patchelf /usr/bin/

RUN curl -o cmake.tgz -#fSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$SPC_USE_ARCH.tar.gz && \
mkdir /cmake && \
tar -xzf cmake.tgz -C /cmake --strip-components 1
Expand Down
428 changes: 221 additions & 207 deletions composer.lock

Large diffs are not rendered by default.

39 changes: 35 additions & 4 deletions config/ext.json
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,13 @@
"BSD": "wip"
},
"type": "external",
"source": "grpc",
"source": "ext-grpc",
"arg-type-unix": "enable-path",
"cpp-extension": true,
"lib-depends": [
"grpc"
"zlib",
"openssl",
"libcares"
]
},
"iconv": {
Expand Down Expand Up @@ -408,8 +410,7 @@
"ext-depends": [
"zlib",
"session"
],
"build-with-php": true
]
},
"memcached": {
"support": {
Expand Down Expand Up @@ -487,6 +488,36 @@
"zlib"
]
},
"mysqlnd_ed25519": {
"type": "external",
"source": "mysqlnd_ed25519",
"arg-type": "enable",
"target": [
"shared"
],
"ext-depends": [
"mysqlnd"
],
"lib-depends": [
"libsodium",
"openssl"
]
},
"mysqlnd_parsec": {
"type": "external",
"source": "mysqlnd_parsec",
"arg-type": "enable",
"target": [
"shared"
],
"ext-depends": [
"mysqlnd"
],
"lib-depends": [
"libsodium",
"openssl"
]
},
"oci8": {
"type": "wip",
"support": {
Expand Down
3 changes: 3 additions & 0 deletions config/lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@
"source": "libargon2",
"static-libs-unix": [
"libargon2.a"
],
"lib-suggests": [
"libsodium"
]
},
"libavif": {
Expand Down
43 changes: 37 additions & 6 deletions config/source.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@
"path": "LICENSE"
}
},
"ext-grpc": {
"type": "url",
"url": "https://pecl.php.net/get/grpc",
"path": "php-src/ext/grpc",
"filename": "grpc.tgz",
"license": {
"type": "file",
"path": [
"LICENSE"
]
}
},
"ext-imagick": {
"type": "url",
"url": "https://pecl.php.net/get/imagick",
Expand Down Expand Up @@ -670,19 +682,20 @@
}
},
"libpng": {
"type": "git",
"url": "https://github.com/glennrp/libpng.git",
"rev": "libpng16",
"type": "ghtagtar",
"repo": "pnggroup/libpng",
"match": "v1\\.6\\.\\d+",
"query": "?per_page=150",
"provide-pre-built": true,
"license": {
"type": "file",
"path": "LICENSE"
}
},
"librabbitmq": {
"type": "git",
"url": "https://github.com/alanxz/rabbitmq-c.git",
"rev": "master",
"type": "ghtar",
"repo": "alanxz/rabbitmq-c",
"prefer-stable": true,
"license": {
"type": "file",
"path": "LICENSE"
Expand Down Expand Up @@ -871,6 +884,24 @@
"path": "LICENSE"
}
},
"mysqlnd_ed25519": {
"type": "pie",
"repo": "mariadb/mysqlnd_ed25519",
"path": "php-src/ext/mysqlnd_ed25519",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"mysqlnd_parsec": {
"type": "pie",
"repo": "mariadb/mysqlnd_parsec",
"path": "php-src/ext/mysqlnd_parsec",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ncurses": {
"type": "filelist",
"url": "https://ftp.gnu.org/pub/gnu/ncurses/",
Expand Down
13 changes: 12 additions & 1 deletion src/SPC/builder/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ public function buildShared(array $visited = []): void
logger()->info('Shared extension [' . $this->getName() . '] was already built, skipping (' . $this->getName() . '.so)');
return;
}
if ((string) Config::getExt($this->getName(), 'type') === 'addon') {
return;
}
logger()->info('Building extension [' . $this->getName() . '] as shared extension (' . $this->getName() . '.so)');
foreach ($this->dependencies as $dependency) {
if (!$dependency instanceof Extension) {
Expand All @@ -398,10 +401,12 @@ public function buildShared(array $visited = []): void
if (Config::getExt($this->getName(), 'type') === 'addon') {
return;
}
$this->builder->emitPatchPoint('before-shared-ext[' . $this->getName() . ']-build');
match (PHP_OS_FAMILY) {
'Darwin', 'Linux' => $this->buildUnixShared(),
default => throw new WrongUsageException(PHP_OS_FAMILY . ' build shared extensions is not supported yet'),
};
$this->builder->emitPatchPoint('after-shared-ext[' . $this->getName() . ']-build');
} catch (SPCException $e) {
$e->bindExtensionInfo(['extension_name' => $this->getName()]);
throw $e;
Expand Down Expand Up @@ -452,12 +457,17 @@ public function buildUnixShared(): void

// process *.so file
$soFile = BUILD_MODULES_PATH . '/' . $this->getName() . '.so';
$soDest = $soFile;
preg_match('/-release\s+(\S*)/', getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), $matches);
if (!empty($matches[1])) {
$soDest = str_replace('.so', '-' . $matches[1] . '.so', $soFile);
}
if (!file_exists($soFile)) {
throw new ValidationException("extension {$this->getName()} build failed: {$soFile} not found", validation_module: "Extension {$this->getName()} build");
}
/** @var UnixBuilderBase $builder */
$builder = $this->builder;
$builder->deployBinary($soFile, $soFile, false);
$builder->deployBinary($soFile, $soDest, false);
}

/**
Expand Down Expand Up @@ -543,6 +553,7 @@ protected function getSharedExtensionEnv(): array
'CFLAGS' => $config['cflags'],
'CXXFLAGS' => $config['cflags'],
'LDFLAGS' => $config['ldflags'],
'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'),
'LIBS' => clean_spaces("{$preStatic} {$staticLibs} {$postStatic} {$sharedLibs}"),
'LD_LIBRARY_PATH' => BUILD_LIB_PATH,
];
Expand Down
25 changes: 17 additions & 8 deletions src/SPC/builder/LibraryBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,18 +184,18 @@ public function tryBuild(bool $force_build = false): int

// extract first if not exists
if (!is_dir($this->source_dir)) {
$this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-extract');
$this->getBuilder()->emitPatchPoint('before-library[' . static::NAME . ']-extract');
SourceManager::initSource(libs: [static::NAME], source_only: true);
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-extract');
$this->getBuilder()->emitPatchPoint('after-library[' . static::NAME . ']-extract');
}

if (!$this->patched && $this->patchBeforeBuild()) {
file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!');
}
$this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build');
$this->getBuilder()->emitPatchPoint('before-library[' . static::NAME . ']-build');
$this->build();
$this->installLicense();
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-build');
$this->getBuilder()->emitPatchPoint('after-library[' . static::NAME . ']-build');
return LIB_STATUS_OK;
}

Expand Down Expand Up @@ -346,19 +346,19 @@ protected function getSnakeCaseName(): string
*/
protected function installLicense(): void
{
FileSystem::createDir(BUILD_ROOT_PATH . '/source-licenses/' . $this->getName());
$source = Config::getLib($this->getName(), 'source');
FileSystem::createDir(BUILD_ROOT_PATH . "/source-licenses/{$source}");
$license_files = Config::getSource($source)['license'] ?? [];
if (is_assoc_array($license_files)) {
$license_files = [$license_files];
}
foreach ($license_files as $index => $license) {
if ($license['type'] === 'text') {
FileSystem::writeFile(BUILD_ROOT_PATH . '/source-licenses/' . $this->getName() . "/{$index}.txt", $license['text']);
FileSystem::writeFile(BUILD_ROOT_PATH . "/source-licenses/{$source}/{$index}.txt", $license['text']);
continue;
}
if ($license['type'] === 'file') {
copy($this->source_dir . '/' . $license['path'], BUILD_ROOT_PATH . '/source-licenses/' . $this->getName() . "/{$index}.txt");
copy($this->source_dir . '/' . $license['path'], BUILD_ROOT_PATH . "/source-licenses/{$source}/{$index}.txt");
}
}
}
Expand All @@ -375,8 +375,17 @@ protected function isLibraryInstalled(): bool
return false;
}
}
$pkg_config_path = getenv('PKG_CONFIG_PATH') ?: '';
$search_paths = array_filter(explode(is_unix() ? ':' : ';', $pkg_config_path));
foreach (Config::getLib(static::NAME, 'pkg-configs', []) as $name) {
if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$name}.pc")) {
$found = false;
foreach ($search_paths as $path) {
if (file_exists($path . "/{$name}.pc")) {
$found = true;
break;
}
}
if (!$found) {
return false;
}
}
Expand Down
16 changes: 6 additions & 10 deletions src/SPC/builder/extension/grpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,14 @@ public function patchBeforeBuildconf(): bool
if ($this->builder instanceof WindowsBuilder) {
throw new ValidationException('grpc extension does not support windows yet');
}
if (file_exists(SOURCE_PATH . '/php-src/ext/grpc')) {
return false;
}
// soft link to the grpc source code
if (is_dir($this->source_dir . '/src/php/ext/grpc')) {
shell()->exec('ln -s ' . $this->source_dir . '/src/php/ext/grpc ' . SOURCE_PATH . '/php-src/ext/grpc');
} else {
throw new ValidationException('Cannot find grpc source code in ' . $this->source_dir . '/src/php/ext/grpc');
}
FileSystem::replaceFileStr(
$this->source_dir . '/src/php/ext/grpc/call.c',
'zend_exception_get_default(TSRMLS_C),',
'zend_ce_exception,',
);
if (SPCTarget::getTargetOS() === 'Darwin') {
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/ext/grpc/config.m4',
$this->source_dir . '/config.m4',
'/GRPC_LIBDIR=.*$/m',
'GRPC_LIBDIR=' . BUILD_LIB_PATH . "\n" . 'LDFLAGS="$LDFLAGS -framework CoreFoundation"'
);
Expand Down
21 changes: 21 additions & 0 deletions src/SPC/builder/extension/memcache.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public function getUnixConfigureArg(bool $shared = false): string

public function patchBeforeBuildconf(): bool
{
if (!$this->isBuildStatic()) {
return false;
}
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
'if test -d $abs_srcdir/src ; then',
Expand All @@ -44,6 +47,24 @@ public function patchBeforeBuildconf(): bool
return true;
}

public function patchBeforeSharedConfigure(): bool
{
if (!$this->isBuildShared()) {
return false;
}
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
'if test -d $abs_srcdir/main ; then',
'if test -d $abs_srcdir/src ; then',
);
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
'export CPPFLAGS="$CPPFLAGS $INCLUDES -I$abs_srcdir/main"',
'export CPPFLAGS="$CPPFLAGS $INCLUDES"',
);
return true;
}

protected function getExtraEnv(): array
{
return ['CFLAGS' => '-std=c17'];
Expand Down
22 changes: 22 additions & 0 deletions src/SPC/builder/extension/mysqlnd_ed25519.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace SPC\builder\extension;

use SPC\builder\Extension;
use SPC\util\CustomExt;

#[CustomExt('mysqlnd_ed25519')]
class mysqlnd_ed25519 extends Extension
{
public function getConfigureArg(bool $shared = false): string
{
return '--with-mysqlnd_ed25519' . ($shared ? '=shared' : '');
}

public function getUnixConfigureArg(bool $shared = false): string
{
return $this->getConfigureArg();
}
}
22 changes: 22 additions & 0 deletions src/SPC/builder/extension/mysqlnd_parsec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace SPC\builder\extension;

use SPC\builder\Extension;
use SPC\util\CustomExt;

#[CustomExt('mysqlnd_parsec')]
class mysqlnd_parsec extends Extension
{
public function getConfigureArg(bool $shared = false): string
{
return '--enable-mysqlnd_parsec' . ($shared ? '=shared' : '');
}

public function getUnixConfigureArg(bool $shared = false): string
{
return $this->getConfigureArg();
}
}
Loading
Loading