Compare commits

...

5 Commits
2.4.4 ... 2.4.5

Author SHA1 Message Date
Klaas Skelte van der Werf
15af034b34 Report why the sanity check for the cli target failed (#605) 2025-02-11 10:34:43 +08:00
Jerry Ma
1f281cd376 Fix gettext multithread segment fault bug (#603)
* Fix gettext included with multithreaded bug

* Change --enable-zts to BuildCommand
2025-02-10 20:28:00 +08:00
Jerry Ma
95d741496e Fix windows curl build (using cmake) (#600) 2025-02-06 22:59:02 +08:00
Alexander Over
21de1a2291 add opentelemetry extension support (#593)
* add opentelemetry extension support

* config sort

* cleanup build args

* Update docs

* Adjust custom extension overrides for opentelemetry

* Add tests

* Update README.md and remove windows limitation

* Fix windows static build for opentelemetry

---------

Co-authored-by: crazywhalecc <jesse2061@outlook.com>
2025-02-06 12:27:43 +08:00
Jerry Ma
f19e90afd7 Add extension dio support (#590)
* Add extension dio support

* cs-fix
2025-01-25 17:43:12 +08:00
19 changed files with 184 additions and 25 deletions

View File

@@ -57,6 +57,13 @@
"qdbm" "qdbm"
] ]
}, },
"dio": {
"support": {
"BSD": "wip"
},
"type": "external",
"source": "dio"
},
"dom": { "dom": {
"support": { "support": {
"BSD": "wip" "BSD": "wip"
@@ -438,6 +445,13 @@
"zlib" "zlib"
] ]
}, },
"opentelemetry": {
"support": {
"BSD": "wip"
},
"type": "external",
"source": "opentelemetry"
},
"parallel": { "parallel": {
"support": { "support": {
"BSD": "wip" "BSD": "wip"

View File

@@ -34,7 +34,7 @@
"libcurl.a" "libcurl.a"
], ],
"static-libs-windows": [ "static-libs-windows": [
"libcurl_a.lib" "libcurl.lib"
], ],
"headers": [ "headers": [
"curl" "curl"

View File

@@ -69,6 +69,16 @@
"path": "COPYING" "path": "COPYING"
} }
}, },
"dio": {
"type": "url",
"url": "https://pecl.php.net/get/dio",
"path": "php-src/ext/dio",
"filename": "dio.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-ds": { "ext-ds": {
"type": "url", "type": "url",
"url": "https://pecl.php.net/get/ds", "url": "https://pecl.php.net/get/ds",
@@ -673,6 +683,16 @@
"path": "LICENSE.txt" "path": "LICENSE.txt"
} }
}, },
"opentelemetry": {
"type": "url",
"url": "https://pecl.php.net/get/opentelemetry",
"path": "php-src/ext/opentelemetry",
"filename": "opentelemetry.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"parallel": { "parallel": {
"type": "url", "type": "url",
"url": "https://pecl.php.net/get/parallel", "url": "https://pecl.php.net/get/parallel",

View File

@@ -8,8 +8,15 @@ here will describe how to check the errors by yourself and report Issue.
Problems with downloading resources are one of the most common problems with spc. Problems with downloading resources are one of the most common problems with spc.
The main reason is that the addresses used for SPC download resources are generally the official website of the corresponding project or GitHub, etc., The main reason is that the addresses used for SPC download resources are generally the official website of the corresponding project or GitHub, etc.,
and these websites may occasionally go down and block IP addresses. and these websites may occasionally go down and block IP addresses.
Currently, version 2.0.0 has not added an automatic retry mechanism, so after encountering a download failure, After encountering a download failure,
you can try to call the download command multiple times. If you confirm that the address is indeed inaccessible, you can try to call the download command multiple times.
When downloading extensions, you may eventually see errors like `curl: (56) The requested URL returned error: 403` which are often caused by github rate limiting.
You can verify this by adding `--debug` to the command and will see something like `[DEBU] Running command (no output) : curl -sfSL "https://api.github.com/repos/openssl/openssl/releases"`.
To fix this, [create](https://github.com/settings/tokens) a personal access token on GitHub and set it as an environment variable `GITHUB_TOKEN=<XXX>`.
If you confirm that the address is indeed inaccessible,
you can submit an Issue or PR to update the url or download type. you can submit an Issue or PR to update the url or download type.
## Doctor Can't Fix Something ## Doctor Can't Fix Something

View File

@@ -5,7 +5,14 @@
## 下载失败问题 ## 下载失败问题
下载资源问题是 spc 最常见的问题之一。主要是由于 spc 下载资源使用的地址一般均为对应项目的官方网站或 GitHub 等,而这些网站可能偶尔会宕机、屏蔽 IP 地址。 下载资源问题是 spc 最常见的问题之一。主要是由于 spc 下载资源使用的地址一般均为对应项目的官方网站或 GitHub 等,而这些网站可能偶尔会宕机、屏蔽 IP 地址。
目前 2.0.0 版本还没有加入自动重试机制,所以在遇到下载失败后,可以多次尝试调用下载命令。如果确认地址确实无法正常访问,可以提交 Issue 或 PR 更新地址 在遇到下载失败后,可以多次尝试调用下载命令
当下载资源时,你可能最终会看到类似 `curl: (56) The requested URL returned error: 403` 的错误,这通常是由于 GitHub 限制导致的。
你可以通过在命令中添加 `--debug` 来验证,会看到类似 `[DEBU] Running command (no output) : curl -sfSL "https://api.github.com/repos/openssl/openssl/releases"` 的输出。
要解决这个问题,可以在 GitHub 上 [创建](https://github.com/settings/token) 一个个人访问令牌,并将其设置为环境变量 `GITHUB_TOKEN=<XXX>`
如果确认地址确实无法正常访问,可以提交 Issue 或 PR 更新地址。
## doctor 无法修复 ## doctor 无法修复

View File

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

View File

@@ -203,7 +203,7 @@ class Extension
// Run compile check if build target is cli // Run compile check if build target is cli
// If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php // If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php
// If check failed, throw RuntimeException // If check failed, throw RuntimeException
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe --ri "' . $this->getDistName() . '"', false); [$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -n --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
} }
@@ -216,7 +216,7 @@ class Extension
file_get_contents(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php')) file_get_contents(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php'))
); );
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -r "' . trim($test) . '"'); [$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -n -r "' . trim($test) . '"');
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check'); throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
} }

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('dio')]
class dio extends Extension
{
public function patchBeforeBuildconf(): bool
{
if (!file_exists(SOURCE_PATH . '/php-src/ext/dio/php_dio.h')) {
FileSystem::writeFile(SOURCE_PATH . '/php-src/ext/dio/php_dio.h', FileSystem::readFile(SOURCE_PATH . '/php-src/ext/dio/src/php_dio.h'));
return true;
}
return false;
}
}

View File

@@ -34,7 +34,7 @@ class mbregex extends Extension
public function runCliCheckWindows(): void public function runCliCheckWindows(): void
{ {
[$ret, $out] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring"', false); [$ret, $out] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n --ri "mbstring"', false);
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli does not contain mbstring !'); throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli does not contain mbstring !');
} }

View File

@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
use SPC\util\GlobalEnvManager;
#[CustomExt('opentelemetry')]
class opentelemetry extends Extension
{
public function validate(): void
{
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
throw new \RuntimeException('The opentelemetry extension requires PHP 8.0 or later');
}
}
public function patchBeforeBuildconf(): bool
{
if (PHP_OS_FAMILY === 'Windows') {
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/opentelemetry/config.w32',
"EXTENSION('opentelemetry', 'opentelemetry.c otel_observer.c', '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1');",
"EXTENSION('opentelemetry', 'opentelemetry.c otel_observer.c', PHP_OPENTELEMETRY_SHARED, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1');"
);
return true;
}
return false;
}
public function patchBeforeMake(): bool
{
// 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

@@ -143,8 +143,9 @@ abstract class UnixBuilderBase extends BuilderBase
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
logger()->info('running cli sanity check'); logger()->info('running cli sanity check');
[$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"'); [$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"');
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') { $raw_output = implode('', $output);
throw new RuntimeException('cli failed sanity check'); if ($ret !== 0 || trim($raw_output) !== 'hello') {
throw new RuntimeException("cli failed sanity check: ret[{$ret}]. out[{$raw_output}]");
} }
foreach ($this->exts as $ext) { foreach ($this->exts as $ext) {

View File

@@ -10,14 +10,21 @@ trait gettext
{ {
$extra = $this->builder->getLib('ncurses') ? ('--with-libncurses-prefix=' . BUILD_ROOT_PATH . ' ') : ''; $extra = $this->builder->getLib('ncurses') ? ('--with-libncurses-prefix=' . BUILD_ROOT_PATH . ' ') : '';
$extra .= $this->builder->getLib('libxml2') ? ('--with-libxml2-prefix=' . BUILD_ROOT_PATH . ' ') : ''; $extra .= $this->builder->getLib('libxml2') ? ('--with-libxml2-prefix=' . BUILD_ROOT_PATH . ' ') : '';
$zts = $this->builder->getOption('enable-zts') ? '--enable-threads=isoc+posix ' : '--disable-threads ';
$cflags = $this->builder->getOption('enable-zts') ? '-lpthread -D_REENTRANT' : '';
$ldflags = $this->builder->getOption('enable-zts') ? '-lpthread' : '';
shell()->cd($this->source_dir) shell()->cd($this->source_dir)
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) ->setEnv(['CFLAGS' => $this->getLibExtraCFlags() ?: $cflags, 'LDFLAGS' => $this->getLibExtraLdFlags() ?: $ldflags, 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv( ->execWithEnv(
'./configure ' . './configure ' .
'--enable-static ' . '--enable-static ' .
'--disable-shared ' . '--disable-shared ' .
'--disable-java ' . '--disable-java ' .
'--disable-c+ ' . '--disable-c+ ' .
$zts .
$extra . $extra .
'--with-included-gettext ' . '--with-included-gettext ' .
'--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' . '--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' .

View File

@@ -277,7 +277,7 @@ class WindowsBuilder extends BuilderBase
// sanity check for php-cli // sanity check for php-cli
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
logger()->info('running cli sanity check'); logger()->info('running cli sanity check');
[$ret, $output] = cmd()->execWithResult(BUILD_ROOT_PATH . '\bin\php.exe -r "echo \"hello\";"'); [$ret, $output] = cmd()->execWithResult(BUILD_ROOT_PATH . '\bin\php.exe -n -r "echo \"hello\";"');
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') { if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
throw new RuntimeException('cli failed sanity check'); throw new RuntimeException('cli failed sanity check');
} }

View File

@@ -12,14 +12,41 @@ class curl extends WindowsLibraryBase
protected function build(): void protected function build(): void
{ {
FileSystem::createDir(BUILD_BIN_PATH); // reset cmake
cmd()->cd($this->source_dir . '\winbuild') FileSystem::resetDir($this->source_dir . '\cmakebuild');
// lib:zstd
$alt = $this->builder->getLib('zstd') ? '' : '-DCURL_ZSTD=OFF';
// lib:brotli
$alt .= $this->builder->getLib('brotli') ? '' : ' -DCURL_BROTLI=OFF';
// start build
cmd()->cd($this->source_dir)
->execWithWrapper( ->execWithWrapper(
$this->builder->makeSimpleWrapper('nmake'), $this->builder->makeSimpleWrapper('cmake'),
'/f Makefile.vc WITH_DEVEL=' . BUILD_ROOT_PATH . ' ' . '-B cmakebuild ' .
'WITH_PREFIX=' . BUILD_ROOT_PATH . ' ' . '-A x64 ' .
'mode=static RTLIBCFG=static WITH_SSL=static WITH_NGHTTP2=static WITH_SSH2=static ENABLE_IPV6=yes WITH_ZLIB=static MACHINE=x64 DEBUG=no' "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DBUILD_STATIC_LIBS=ON ' .
'-DCURL_STATICLIB=ON ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
'-DBUILD_CURL_EXE=OFF ' . // disable curl.exe
'-DBUILD_TESTING=OFF ' . // disable tests
'-DBUILD_EXAMPLES=OFF ' . // disable examples
'-DUSE_LIBIDN2=OFF ' . // disable libidn2
'-DCURL_USE_LIBPSL=OFF ' . // disable libpsl
'-DCURL_ENABLE_SSL=ON ' .
'-DUSE_NGHTTP2=ON ' . // enable nghttp2
'-DCURL_USE_LIBSSH2=ON ' . // enable libssh2
'-DENABLE_IPV6=ON ' . // enable ipv6
'-DNGHTTP2_CFLAGS="/DNGHTTP2_STATICLIB" ' .
$alt
)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
"--build cmakebuild --config Release --target install -j{$this->builder->concurrency}"
); );
FileSystem::copyDir($this->source_dir . '\include\curl', BUILD_INCLUDE_PATH . '\curl');
} }
} }

View File

@@ -32,7 +32,6 @@ class BuildCliCommand extends BuildCommand
$this->addOption('build-embed', null, null, 'Build embed SAPI'); $this->addOption('build-embed', null, null, 'Build embed SAPI');
$this->addOption('build-all', null, null, 'Build all SAPI'); $this->addOption('build-all', null, null, 'Build all SAPI');
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions'); $this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
$this->addOption('enable-zts', null, null, 'enable ZTS support');
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit'); $this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');
$this->addOption('with-config-file-path', null, InputOption::VALUE_REQUIRED, 'Set the path in which to look for php.ini', $isWindows ? null : '/usr/local/etc/php'); $this->addOption('with-config-file-path', null, InputOption::VALUE_REQUIRED, 'Set the path in which to look for php.ini', $isWindows ? null : '/usr/local/etc/php');
$this->addOption('with-config-file-scan-dir', null, InputOption::VALUE_REQUIRED, 'Set the directory to scan for .ini files after reading php.ini', $isWindows ? null : '/usr/local/etc/php/conf.d'); $this->addOption('with-config-file-scan-dir', null, InputOption::VALUE_REQUIRED, 'Set the directory to scan for .ini files after reading php.ini', $isWindows ? null : '/usr/local/etc/php/conf.d');

View File

@@ -31,5 +31,6 @@ abstract class BuildCommand extends BaseCommand
$this->addOption('with-clean', null, null, 'fresh build, remove `source` dir before `make`'); $this->addOption('with-clean', null, null, 'fresh build, remove `source` dir before `make`');
$this->addOption('bloat', null, null, 'add all libraries into binary'); $this->addOption('bloat', null, null, 'add all libraries into binary');
$this->addOption('rebuild', 'r', null, 'Delete old build and rebuild'); $this->addOption('rebuild', 'r', null, 'Delete old build and rebuild');
$this->addOption('enable-zts', null, null, 'enable ZTS support');
} }
} }

View File

@@ -0,0 +1,5 @@
<?php
declare(strict_types=1);
assert(function_exists('dio_open'));

View File

@@ -0,0 +1,5 @@
<?php
declare(strict_types=1);
assert(function_exists('OpenTelemetry\Instrumentation\hook'));

View File

@@ -13,19 +13,22 @@ declare(strict_types=1);
// test php version // test php version
$test_php_version = [ $test_php_version = [
'8.1',
'8.2',
'8.3', '8.3',
'8.4', '8.4',
]; ];
// 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-14', 'macos-14',
'macos-13',
'ubuntu-latest', 'ubuntu-latest',
// 'windows-latest',
]; ];
// whether enable thread safe // whether enable thread safe
$zts = false; $zts = true;
$no_strip = false; $no_strip = false;
@@ -37,8 +40,8 @@ $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' => 'imagick', 'Linux', 'Darwin' => 'gettext',
'Windows' => 'ast', 'Windows' => 'gettext',
}; };
// 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`).
@@ -51,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' => 'none',
'Windows' => 'none', 'Windows' => 'none',
}; };