mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-04 15:25:41 +08:00
Merge branch 'main' into frankenphp/mbed
This commit is contained in:
@@ -34,7 +34,7 @@ use Symfony\Component\Console\Application;
|
||||
*/
|
||||
final class ConsoleApplication extends Application
|
||||
{
|
||||
public const string VERSION = '2.7.5';
|
||||
public const string VERSION = '2.7.6';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
@@ -220,7 +220,7 @@ class Extension
|
||||
*/
|
||||
public function patchBeforeSharedMake(): bool
|
||||
{
|
||||
$config = (new SPCConfigUtil($this->builder))->config([$this->getName()], array_map(fn ($l) => $l->getName(), $this->builder->getLibs()));
|
||||
$config = (new SPCConfigUtil($this->builder))->getExtensionConfig($this);
|
||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||
$lstdcpp = str_contains($sharedLibs, '-l:libstdc++.a') ? '-l:libstdc++.a' : null;
|
||||
$lstdcpp ??= str_contains($sharedLibs, '-lstdc++') ? '-lstdc++' : '';
|
||||
@@ -486,18 +486,46 @@ class Extension
|
||||
return $this->build_static;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the library dependencies that current extension depends on.
|
||||
*
|
||||
* @param bool $recursive Whether it includes dependencies recursively
|
||||
*/
|
||||
public function getLibraryDependencies(bool $recursive = false): array
|
||||
{
|
||||
$ret = array_filter($this->dependencies, fn ($x) => $x instanceof LibraryBase);
|
||||
if (!$recursive) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$deps = [];
|
||||
|
||||
$added = 1;
|
||||
while ($added !== 0) {
|
||||
$added = 0;
|
||||
foreach ($ret as $depName => $dep) {
|
||||
foreach ($dep->getDependencies(true) as $depdepName => $depdep) {
|
||||
if (!array_key_exists($depdepName, $deps)) {
|
||||
$deps[$depdepName] = $depdep;
|
||||
++$added;
|
||||
}
|
||||
}
|
||||
if (!array_key_exists($depName, $deps)) {
|
||||
$deps[$depName] = $dep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $deps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment variables a shared extension needs to be built.
|
||||
* CFLAGS, CXXFLAGS, LDFLAGS and so on.
|
||||
*/
|
||||
protected function getSharedExtensionEnv(): array
|
||||
{
|
||||
$config = (new SPCConfigUtil($this->builder))->config(
|
||||
[$this->getName()],
|
||||
array_map(fn ($l) => $l->getName(), $this->getLibraryDependencies(recursive: true)),
|
||||
$this->builder->getOption('with-suggested-exts'),
|
||||
$this->builder->getOption('with-suggested-libs'),
|
||||
);
|
||||
$config = (new SPCConfigUtil($this->builder))->getExtensionConfig($this);
|
||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||
$preStatic = PHP_OS_FAMILY === 'Darwin' ? '' : '-Wl,--start-group ';
|
||||
$postStatic = PHP_OS_FAMILY === 'Darwin' ? '' : ' -Wl,--end-group ';
|
||||
@@ -519,7 +547,7 @@ class Extension
|
||||
}
|
||||
logger()->info("enabling {$this->name} without library {$name}");
|
||||
} else {
|
||||
$this->dependencies[] = $depLib;
|
||||
$this->dependencies[$name] = $depLib;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,7 +560,7 @@ class Extension
|
||||
}
|
||||
logger()->info("enabling {$this->name} without extension {$name}");
|
||||
} else {
|
||||
$this->dependencies[] = $depExt;
|
||||
$this->dependencies[$name] = $depExt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,37 +595,4 @@ class Extension
|
||||
}
|
||||
return [trim($staticLibString), trim($sharedLibString)];
|
||||
}
|
||||
|
||||
private function getLibraryDependencies(bool $recursive = false): array
|
||||
{
|
||||
$ret = array_filter($this->dependencies, fn ($x) => $x instanceof LibraryBase);
|
||||
if (!$recursive) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$deps = [];
|
||||
|
||||
$added = 1;
|
||||
while ($added !== 0) {
|
||||
$added = 0;
|
||||
foreach ($ret as $depName => $dep) {
|
||||
foreach ($dep->getDependencies(true) as $depdepName => $depdep) {
|
||||
if (!array_key_exists($depdepName, $deps)) {
|
||||
$deps[$depdepName] = $depdep;
|
||||
++$added;
|
||||
}
|
||||
}
|
||||
if (!array_key_exists($depName, $deps)) {
|
||||
$deps[$depName] = $dep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists(0, $deps)) {
|
||||
$zero = [0 => $deps[0]];
|
||||
unset($deps[0]);
|
||||
return $zero + $deps;
|
||||
}
|
||||
return $deps;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class grpc extends Extension
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
$util = new SPCConfigUtil($this->builder, ['libs_only_deps' => true]);
|
||||
$config = $util->config(['grpc']);
|
||||
$config = $util->getExtensionConfig($this);
|
||||
$libs = $config['libs'];
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lgrpc', $libs);
|
||||
return true;
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace SPC\builder\extension;
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
|
||||
#[CustomExt('rdkafka')]
|
||||
class rdkafka extends Extension
|
||||
@@ -15,6 +16,7 @@ class rdkafka extends Extension
|
||||
{
|
||||
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\n", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm \$RDKAFKA_LIBS\n");
|
||||
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\"\n", '-L$RDKAFKA_DIR/$PHP_LIBDIR -lm $RDKAFKA_LIBS"');
|
||||
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", 'PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,', 'AC_CHECK_LIB([$LIBNAME], [$LIBSYMBOL],');
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,8 +39,7 @@ class rdkafka extends Extension
|
||||
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
{
|
||||
$pkgconf_libs = shell()->execWithResult('pkg-config --libs --static rdkafka')[1];
|
||||
$pkgconf_libs = trim(implode('', $pkgconf_libs));
|
||||
return '--with-rdkafka=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . ' RDKAFKA_LIBS="' . $pkgconf_libs . '"';
|
||||
$pkgconf_libs = (new SPCConfigUtil($this->builder, ['no_php' => true, 'libs_only_deps' => true]))->getExtensionConfig($this);
|
||||
return '--with-rdkafka=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . " RDKAFKA_LIBS=\"{$pkgconf_libs['libs']}\"";
|
||||
}
|
||||
}
|
||||
|
||||
29
src/SPC/builder/extension/snmp.php
Normal file
29
src/SPC/builder/extension/snmp.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
use SPC\util\PkgConfigUtil;
|
||||
|
||||
#[CustomExt('snmp')]
|
||||
class snmp extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
// Overwrite m4 config using newer PHP version
|
||||
if ($this->builder->getPHPVersionID() < 80400) {
|
||||
FileSystem::copy(ROOT_DIR . '/src/globals/extra/snmp-ext-config-old.m4', "{$this->source_dir}/config.m4");
|
||||
}
|
||||
$libs = implode(' ', PkgConfigUtil::getLibsArray('netsnmp'));
|
||||
FileSystem::replaceFileStr(
|
||||
"{$this->source_dir}/config.m4",
|
||||
'PHP_EVAL_LIBLINE([$SNMP_LIBS], [SNMP_SHARED_LIBADD])',
|
||||
"SNMP_LIBS=\"{$libs}\"\nPHP_EVAL_LIBLINE([\$SNMP_LIBS], [SNMP_SHARED_LIBADD])"
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class swoole extends Extension
|
||||
$arg .= $this->builder->getExt('swoole-hook-mysql') ? ' --enable-mysqlnd' : ' --disable-mysqlnd';
|
||||
$arg .= $this->builder->getExt('swoole-hook-sqlite') ? ' --enable-swoole-sqlite' : ' --disable-swoole-sqlite';
|
||||
if ($this->builder->getExt('swoole-hook-odbc')) {
|
||||
$config = (new SPCConfigUtil($this->builder, ['libs_only_deps' => true]))->config([], ['unixodbc']);
|
||||
$config = (new SPCConfigUtil($this->builder))->getLibraryConfig($this->builder->getLib('unixodbc'));
|
||||
$arg .= ' --with-swoole-odbc=unixODBC,' . BUILD_ROOT_PATH . ' SWOOLE_ODBC_LIBS="' . $config['libs'] . '"';
|
||||
}
|
||||
|
||||
|
||||
12
src/SPC/builder/linux/library/net_snmp.php
Normal file
12
src/SPC/builder/linux/library/net_snmp.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class net_snmp extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\net_snmp;
|
||||
|
||||
public const NAME = 'net-snmp';
|
||||
}
|
||||
@@ -78,7 +78,7 @@ class openssl extends LinuxLibraryBase
|
||||
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc'), 'prefix=')) {
|
||||
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
|
||||
}
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Libs.private: ${libdir}/libz.a');
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Requires.private: zlib');
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")');
|
||||
}
|
||||
}
|
||||
|
||||
12
src/SPC/builder/macos/library/net_snmp.php
Normal file
12
src/SPC/builder/macos/library/net_snmp.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
class net_snmp extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\net_snmp;
|
||||
|
||||
public const NAME = 'net-snmp';
|
||||
}
|
||||
@@ -63,7 +63,7 @@ class openssl extends MacOSLibraryBase
|
||||
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc'), 'prefix=')) {
|
||||
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
|
||||
}
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Libs.private: ${libdir}/libz.a');
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Requires.private: zlib');
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
use SPC\util\executor\UnixCMakeExecutor;
|
||||
|
||||
trait librdkafka
|
||||
{
|
||||
@@ -26,34 +26,18 @@ trait librdkafka
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->appendEnv(['CFLAGS' => '-Wno-int-conversion -Wno-unused-but-set-variable -Wno-unused-variable'])
|
||||
->optionalLib(
|
||||
'zstd',
|
||||
function ($lib) {
|
||||
putenv("STATIC_LIB_libzstd={$lib->getLibDir()}/libzstd.a");
|
||||
return '';
|
||||
},
|
||||
'--disable-zstd'
|
||||
UnixCMakeExecutor::create($this)
|
||||
->optionalLib('zstd', ...cmake_boolean_args('WITH_ZSTD'))
|
||||
->optionalLib('curl', ...cmake_boolean_args('WITH_CURL'))
|
||||
->optionalLib('openssl', ...cmake_boolean_args('WITH_SSL'))
|
||||
->optionalLib('zlib', ...cmake_boolean_args('WITH_ZLIB'))
|
||||
->optionalLib('liblz4', ...cmake_boolean_args('ENABLE_LZ4_EXT'))
|
||||
->addConfigureArgs(
|
||||
'-DWITH_SASL=OFF',
|
||||
'-DRDKAFKA_BUILD_STATIC=ON',
|
||||
'-DRDKAFKA_BUILD_EXAMPLES=OFF',
|
||||
'-DRDKAFKA_BUILD_TESTS=OFF',
|
||||
)
|
||||
->removeConfigureArgs(
|
||||
'--with-pic',
|
||||
'--enable-pic',
|
||||
)
|
||||
->configure(
|
||||
'--disable-curl',
|
||||
'--disable-sasl',
|
||||
'--disable-valgrind',
|
||||
'--disable-zlib',
|
||||
'--disable-ssl',
|
||||
)
|
||||
->make();
|
||||
|
||||
$this->patchPkgconfPrefix(['rdkafka.pc', 'rdkafka-static.pc', 'rdkafka++.pc', 'rdkafka++-static.pc']);
|
||||
// remove dynamic libs
|
||||
shell()
|
||||
->exec("rm -rf {$this->getLibDir()}/*.so.*")
|
||||
->exec("rm -rf {$this->getLibDir()}/*.so")
|
||||
->exec("rm -rf {$this->getLibDir()}/*.dylib");
|
||||
->build();
|
||||
}
|
||||
}
|
||||
|
||||
49
src/SPC/builder/unix/library/net_snmp.php
Normal file
49
src/SPC/builder/unix/library/net_snmp.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
|
||||
trait net_snmp
|
||||
{
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Linux') {
|
||||
FileSystem::replaceFileStr("{$this->source_dir}/configure", 'LIBS="-lssl ${OPENSSL_LIBS}"', 'LIBS="-lssl ${OPENSSL_LIBS} -lpthread -ldl"');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
// use --static for PKG_CONFIG
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->setEnv(['PKG_CONFIG' => getenv('PKG_CONFIG') . ' --static'])
|
||||
->configure(
|
||||
'--disable-mibs',
|
||||
'--without-nl',
|
||||
'--disable-agent',
|
||||
'--disable-applications',
|
||||
'--disable-manuals',
|
||||
'--disable-scripts',
|
||||
'--disable-embedded-perl',
|
||||
'--without-perl-modules',
|
||||
'--with-out-mib-modules="if-mib host disman/event-mib ucd-snmp/diskio mibII"',
|
||||
'--with-out-transports="Unix"',
|
||||
'--with-mib-modules=""',
|
||||
'--enable-mini-agent',
|
||||
'--with-default-snmp-version="3"',
|
||||
'--with-sys-contact="@@no.where"',
|
||||
'--with-sys-location="Unknown"',
|
||||
'--with-logfile="/var/log/snmpd.log"',
|
||||
'--with-persistent-directory="/var/lib/net-snmp"',
|
||||
'--with-openssl=' . BUILD_ROOT_PATH,
|
||||
'--with-zlib=' . BUILD_ROOT_PATH,
|
||||
)->make(with_install: 'installheaders installlibs install_pkgconfig');
|
||||
$this->patchPkgconfPrefix();
|
||||
}
|
||||
}
|
||||
@@ -45,9 +45,9 @@ trait postgresql
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
$libs = array_map(fn ($x) => $x->getName(), $this->getDependencies());
|
||||
$spc = new SPCConfigUtil($this->getBuilder(), ['no_php' => true, 'libs_only_deps' => true]);
|
||||
$config = $spc->config(libraries: $libs, include_suggest_lib: $this->builder->getOption('with-suggested-libs'));
|
||||
$libs = array_map(fn ($x) => $x->getName(), $this->getDependencies(true));
|
||||
$spc = new SPCConfigUtil($this->builder, ['no_php' => true, 'libs_only_deps' => true]);
|
||||
$config = $spc->config(libraries: $libs, include_suggest_lib: $this->builder->getOption('with-suggested-libs', false));
|
||||
|
||||
$env_vars = [
|
||||
'CFLAGS' => $config['cflags'],
|
||||
|
||||
@@ -57,6 +57,7 @@ class WindowsBuilder extends BuilderBase
|
||||
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
|
||||
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
|
||||
$enableCgi = ($build_target & BUILD_TARGET_CGI) === BUILD_TARGET_CGI;
|
||||
|
||||
SourcePatcher::patchBeforeBuildconf($this);
|
||||
|
||||
@@ -102,13 +103,13 @@ class WindowsBuilder extends BuilderBase
|
||||
->exec(
|
||||
"{$this->sdk_prefix} configure.bat --task-args \"" .
|
||||
'--disable-all ' .
|
||||
'--disable-cgi ' .
|
||||
'--with-php-build=' . BUILD_ROOT_PATH . ' ' .
|
||||
'--with-extra-includes=' . BUILD_INCLUDE_PATH . ' ' .
|
||||
'--with-extra-libs=' . BUILD_LIB_PATH . ' ' .
|
||||
($enableCli ? '--enable-cli=yes ' : '--enable-cli=no ') .
|
||||
($enableMicro ? ('--enable-micro=yes ' . $micro_logo . $micro_w32) : '--enable-micro=no ') .
|
||||
($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
|
||||
($enableCli ? '--enable-cli ' : '--disable-cli ') .
|
||||
($enableMicro ? ('--enable-micro ' . $micro_logo . $micro_w32) : '--disable-micro ') .
|
||||
($enableEmbed ? '--enable-embed ' : '--disable-embed ') .
|
||||
($enableCgi ? '--enable-cgi ' : '--disable-cgi ') .
|
||||
$config_file_scan_dir .
|
||||
$opcache_jit_arg .
|
||||
"{$this->makeStaticExtensionArgs()} " .
|
||||
@@ -127,6 +128,10 @@ class WindowsBuilder extends BuilderBase
|
||||
if ($enableFpm) {
|
||||
logger()->warning('Windows does not support fpm SAPI, I will skip it.');
|
||||
}
|
||||
if ($enableCgi) {
|
||||
logger()->info('building cgi');
|
||||
$this->buildCgi();
|
||||
}
|
||||
if ($enableMicro) {
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro();
|
||||
@@ -159,6 +164,20 @@ class WindowsBuilder extends BuilderBase
|
||||
$this->deployBinary(BUILD_TARGET_CLI);
|
||||
}
|
||||
|
||||
public function buildCgi(): void
|
||||
{
|
||||
SourcePatcher::patchWindowsCGITarget();
|
||||
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||
|
||||
// add nmake wrapper
|
||||
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo LIBS_CGI=\"ws2_32.lib kernel32.lib advapi32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*");
|
||||
|
||||
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe");
|
||||
|
||||
$this->deployBinary(BUILD_TARGET_CGI);
|
||||
}
|
||||
|
||||
public function buildEmbed(): void
|
||||
{
|
||||
// TODO: add embed support for windows
|
||||
@@ -265,7 +284,7 @@ class WindowsBuilder extends BuilderBase
|
||||
// sanity check for php-cli
|
||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||
logger()->info('running cli sanity check');
|
||||
[$ret, $output] = cmd()->execWithResult(BUILD_ROOT_PATH . '\bin\php.exe -n -r "echo \"hello\";"');
|
||||
[$ret, $output] = cmd()->execWithResult(BUILD_BIN_PATH . '\php.exe -n -r "echo \"hello\";"');
|
||||
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
|
||||
throw new ValidationException('cli failed sanity check', validation_module: 'php-cli function check');
|
||||
}
|
||||
@@ -284,7 +303,7 @@ class WindowsBuilder extends BuilderBase
|
||||
if (file_exists($test_file)) {
|
||||
@unlink($test_file);
|
||||
}
|
||||
file_put_contents($test_file, file_get_contents(BUILD_ROOT_PATH . '\bin\micro.sfx') . $task['content']);
|
||||
file_put_contents($test_file, file_get_contents(BUILD_BIN_PATH . '\micro.sfx') . $task['content']);
|
||||
chmod($test_file, 0755);
|
||||
[$ret, $out] = cmd()->execWithResult($test_file);
|
||||
foreach ($task['conditions'] as $condition => $closure) {
|
||||
@@ -298,6 +317,17 @@ class WindowsBuilder extends BuilderBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sanity check for php-cgi
|
||||
if (($build_target & BUILD_TARGET_CGI) === BUILD_TARGET_CGI) {
|
||||
logger()->info('running cgi sanity check');
|
||||
FileSystem::writeFile(SOURCE_PATH . '\php-cgi-test.php', '<?php echo "<h1>Hello, World!</h1>"; ?>');
|
||||
[$ret, $output] = cmd()->execWithResult(BUILD_BIN_PATH . '\php-cgi.exe -n -f ' . SOURCE_PATH . '\php-cgi-test.php');
|
||||
$raw_output = implode("\n", $output);
|
||||
if ($ret !== 0 || !str_contains($raw_output, 'Hello, World!')) {
|
||||
throw new ValidationException("cgi failed sanity check. code: {$ret}, output: {$raw_output}", validation_module: 'php-cgi sanity check');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,20 +341,21 @@ class WindowsBuilder extends BuilderBase
|
||||
$src = match ($type) {
|
||||
BUILD_TARGET_CLI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php.exe",
|
||||
BUILD_TARGET_MICRO => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\micro.sfx",
|
||||
BUILD_TARGET_CGI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php-cgi.exe",
|
||||
default => throw new SPCInternalException("Deployment does not accept type {$type}"),
|
||||
};
|
||||
|
||||
// with-upx-pack for cli and micro
|
||||
if ($this->getOption('with-upx-pack', false)) {
|
||||
if ($type === BUILD_TARGET_CLI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) {
|
||||
if ($type === BUILD_TARGET_CLI || $type === BUILD_TARGET_CGI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) {
|
||||
cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src));
|
||||
}
|
||||
}
|
||||
|
||||
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
||||
FileSystem::createDir(BUILD_ROOT_PATH . '\bin');
|
||||
FileSystem::createDir(BUILD_BIN_PATH);
|
||||
|
||||
cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\\'));
|
||||
cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_BIN_PATH . '\\'));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class BuildPHPCommand extends BuildCommand
|
||||
$this->addOption('build-fpm', null, null, 'Build fpm SAPI (not available on Windows)');
|
||||
$this->addOption('build-embed', null, null, 'Build embed SAPI (not available on Windows)');
|
||||
$this->addOption('build-frankenphp', null, null, 'Build FrankenPHP SAPI (not available on Windows)');
|
||||
$this->addOption('build-cgi', null, null, 'Build cgi SAPI (not available on Windows)');
|
||||
$this->addOption('build-cgi', null, null, 'Build cgi SAPI');
|
||||
$this->addOption('build-all', null, null, 'Build all SAPI');
|
||||
$this->addOption('no-strip', null, null, 'build without strip, keep symbols to debug');
|
||||
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');
|
||||
|
||||
@@ -40,7 +40,7 @@ class LinuxToolCheckList
|
||||
'tar', 'unzip', 'gzip', 'gcc', 'g++',
|
||||
'bzip2', 'cmake', 'patch', 'which',
|
||||
'xz', 'libtool', 'gettext-devel',
|
||||
'patchelf',
|
||||
'patchelf', 'file',
|
||||
];
|
||||
|
||||
public const TOOLS_ARCH = [
|
||||
|
||||
@@ -159,7 +159,9 @@ class ExceptionHandler
|
||||
public static function handleDefaultException(\Throwable $e): void
|
||||
{
|
||||
$class = get_class($e);
|
||||
self::logError("✗ Unhandled exception {$class}:\n\t{$e->getMessage()}\n");
|
||||
$file = $e->getFile();
|
||||
$line = $e->getLine();
|
||||
self::logError("✗ Unhandled exception {$class} on {$file} line {$line}:\n\t{$e->getMessage()}\n");
|
||||
self::logError('Stack trace:');
|
||||
self::logError(ConsoleColor::gray($e->getTraceAsString()) . PHP_EOL, 4);
|
||||
self::logError('⚠ Please report this exception to: https://github.com/crazywhalecc/static-php-cli/issues');
|
||||
|
||||
@@ -549,6 +549,39 @@ class SourcePatcher
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines));
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch cgi SAPI Makefile for Windows.
|
||||
*/
|
||||
public static function patchWindowsCGITarget(): void
|
||||
{
|
||||
// search Makefile code line contains "$(BUILD_DIR)\php-cgi.exe:"
|
||||
$content = FileSystem::readFile(SOURCE_PATH . '/php-src/Makefile');
|
||||
$lines = explode("\r\n", $content);
|
||||
$line_num = 0;
|
||||
$found = false;
|
||||
foreach ($lines as $v) {
|
||||
if (str_contains($v, '$(BUILD_DIR)\php-cgi.exe:')) {
|
||||
$found = $line_num;
|
||||
break;
|
||||
}
|
||||
++$line_num;
|
||||
}
|
||||
if ($found === false) {
|
||||
throw new PatchException('Windows Makefile patching for php-cgi.exe target', 'Cannot patch windows CGI Makefile, Makefile does not contain "$(BUILD_DIR)\php-cgi.exe:" line');
|
||||
}
|
||||
// cli: $(BUILD_DIR)\php.exe: $(DEPS_CLI) $(CLI_GLOBAL_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php.exe.res $(BUILD_DIR)\php.exe.manifest
|
||||
// $lines[$line_num] = '$(BUILD_DIR)\php.exe: generated_files $(DEPS_CLI) $(CLI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\php.exe.res $(BUILD_DIR)\php.exe.manifest';
|
||||
// cgi: $(BUILD_DIR)\php-cgi.exe: $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest
|
||||
$lines[$line_num] = '$(BUILD_DIR)\php-cgi.exe: $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest';
|
||||
|
||||
// cli: @"$(LINK)" /nologo $(CGI_GLOBAL_OBJS_RESP) $(BUILD_DIR)\$(PHPLIB) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI)
|
||||
$lines[$line_num + 1] = "\t" . '@"$(LINK)" /nologo $(PHP_GLOBAL_OBJS_RESP) $(CGI_GLOBAL_OBJS_RESP) $(STATIC_EXT_OBJS_RESP) $(STATIC_EXT_LIBS) $(ASM_OBJS) $(LIBS) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) /ltcg /nodefaultlib:msvcrt /nodefaultlib:msvcrtd /ignore:4286';
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines));
|
||||
|
||||
// Patch cgi-static, comment ZEND_TSRMLS_CACHE_DEFINE()
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '\php-src\sapi\cgi\cgi_main.c', '/^ZEND_TSRMLS_CACHE_DEFINE\(\)/m', '// ZEND_TSRMLS_CACHE_DEFINE()');
|
||||
}
|
||||
|
||||
public static function patchPhpLibxml212(): bool
|
||||
{
|
||||
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace SPC\util;
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\LibraryBase;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
@@ -53,6 +54,9 @@ class SPCConfigUtil
|
||||
*/
|
||||
public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false): array
|
||||
{
|
||||
logger()->debug('config extensions: ' . implode(',', $extensions));
|
||||
logger()->debug('config libs: ' . implode(',', $libraries));
|
||||
logger()->debug('config suggest for [ext, lib]: ' . ($include_suggest_ext ? 'true' : 'false') . ',' . ($include_suggest_lib ? 'true' : 'false'));
|
||||
$extra_exts = [];
|
||||
foreach ($extensions as $ext) {
|
||||
$extra_exts = array_merge($extra_exts, Config::getExt($ext, 'ext-suggests', []));
|
||||
@@ -124,6 +128,63 @@ class SPCConfigUtil
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* [Helper function]
|
||||
* Get configuration for a specific extension(s) dependencies.
|
||||
*
|
||||
* @param Extension|Extension[] $extension Extension instance or list
|
||||
* @param bool $include_suggest_ext Whether to include suggested extensions
|
||||
* @param bool $include_suggest_lib Whether to include suggested libraries
|
||||
* @return array{
|
||||
* cflags: string,
|
||||
* ldflags: string,
|
||||
* libs: string
|
||||
* }
|
||||
*/
|
||||
public function getExtensionConfig(array|Extension $extension, bool $include_suggest_ext = false, bool $include_suggest_lib = false): array
|
||||
{
|
||||
if (!is_array($extension)) {
|
||||
$extension = [$extension];
|
||||
}
|
||||
$libs = array_map(fn ($y) => $y->getName(), array_merge(...array_map(fn ($x) => $x->getLibraryDependencies(true), $extension)));
|
||||
return $this->config(
|
||||
extensions: array_map(fn ($x) => $x->getName(), $extension),
|
||||
libraries: $libs,
|
||||
include_suggest_ext: $include_suggest_ext ?: $this->builder?->getOption('with-suggested-exts') ?? false,
|
||||
include_suggest_lib: $include_suggest_lib ?: $this->builder?->getOption('with-suggested-libs') ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* [Helper function]
|
||||
* Get configuration for a specific library(s) dependencies.
|
||||
*
|
||||
* @param LibraryBase|LibraryBase[] $lib Library instance or list
|
||||
* @param bool $include_suggest_lib Whether to include suggested libraries
|
||||
* @return array{
|
||||
* cflags: string,
|
||||
* ldflags: string,
|
||||
* libs: string
|
||||
* }
|
||||
*/
|
||||
public function getLibraryConfig(array|LibraryBase $lib, bool $include_suggest_lib = false): array
|
||||
{
|
||||
if (!is_array($lib)) {
|
||||
$lib = [$lib];
|
||||
}
|
||||
$save_no_php = $this->no_php;
|
||||
$this->no_php = true;
|
||||
$save_libs_only_deps = $this->libs_only_deps;
|
||||
$this->libs_only_deps = true;
|
||||
$ret = $this->config(
|
||||
libraries: array_map(fn ($x) => $x->getName(), $lib),
|
||||
include_suggest_lib: $include_suggest_lib ?: $this->builder?->getOption('with-suggested-libs') ?? false,
|
||||
);
|
||||
$this->no_php = $save_no_php;
|
||||
$this->libs_only_deps = $save_libs_only_deps;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function hasCpp(array $extensions, array $libraries): bool
|
||||
{
|
||||
// judge cpp-extension
|
||||
|
||||
@@ -115,6 +115,12 @@ class UnixAutoconfExecutor extends Executor
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEnv(array $env): static
|
||||
{
|
||||
$this->shell->setEnv($env);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function appendEnv(array $env): static
|
||||
{
|
||||
$this->shell->appendEnv($env);
|
||||
|
||||
92
src/globals/extra/snmp-ext-config-old.m4
Normal file
92
src/globals/extra/snmp-ext-config-old.m4
Normal file
@@ -0,0 +1,92 @@
|
||||
PHP_ARG_WITH([snmp],
|
||||
[for SNMP support],
|
||||
[AS_HELP_STRING([[--with-snmp[=DIR]]],
|
||||
[Include SNMP support. Use PKG_CONFIG_PATH (or SNMP_CFLAGS and SNMP_LIBS)
|
||||
environment variables, or alternatively the optional DIR argument to
|
||||
customize where to look for the net-snmp-config utility of the NET-SNMP
|
||||
library.])])
|
||||
|
||||
if test "$PHP_SNMP" != "no"; then
|
||||
snmp_found=no
|
||||
AS_VAR_IF([PHP_SNMP], [yes],
|
||||
[PKG_CHECK_MODULES([SNMP], [netsnmp >= 5.3], [snmp_found=yes], [:])])
|
||||
|
||||
AS_VAR_IF([snmp_found], [no], [
|
||||
AS_VAR_IF([PHP_SNMP], [yes],
|
||||
[AC_PATH_PROG([SNMP_CONFIG], [net-snmp-config],, [/usr/local/bin:$PATH])],
|
||||
[SNMP_CONFIG="$PHP_SNMP/bin/net-snmp-config"])
|
||||
|
||||
AS_IF([test ! -x "$SNMP_CONFIG"],
|
||||
[AC_MSG_ERROR(m4_text_wrap([
|
||||
Could not find net-snmp-config binary. Please check your net-snmp
|
||||
installation.
|
||||
]))])
|
||||
|
||||
snmp_version=$($SNMP_CONFIG --version)
|
||||
AS_VERSION_COMPARE([$snmp_version], [5.3],
|
||||
[AC_MSG_ERROR(m4_text_wrap([
|
||||
Net-SNMP version 5.3 or greater required (detected $snmp_version).
|
||||
]))])
|
||||
|
||||
SNMP_PREFIX=$($SNMP_CONFIG --prefix)
|
||||
SNMP_CFLAGS="-I${SNMP_PREFIX}/include"
|
||||
SNMP_LIBS=$($SNMP_CONFIG --netsnmp-libs)
|
||||
SNMP_LIBS="$SNMP_LIBS $($SNMP_CONFIG --external-libs)"
|
||||
|
||||
AS_IF([test -z "$SNMP_LIBS" || test -z "$SNMP_PREFIX"],
|
||||
[AC_MSG_ERROR(m4_text_wrap([
|
||||
Could not find the required paths. Please check your net-snmp
|
||||
installation.
|
||||
]))])
|
||||
])
|
||||
|
||||
PHP_EVAL_INCLINE([$SNMP_CFLAGS])
|
||||
PHP_EVAL_LIBLINE([$SNMP_LIBS], [SNMP_SHARED_LIBADD])
|
||||
SNMP_LIBNAME=netsnmp
|
||||
|
||||
dnl Test build.
|
||||
PHP_CHECK_LIBRARY([$SNMP_LIBNAME], [init_snmp],
|
||||
[AC_DEFINE([HAVE_SNMP], [1],
|
||||
[Define to 1 if the PHP extension 'snmp' is available.])],
|
||||
[AC_MSG_FAILURE([SNMP sanity check failed.])],
|
||||
[$SNMP_SHARED_LIBADD])
|
||||
|
||||
dnl Check whether shutdown_snmp_logging() exists.
|
||||
PHP_CHECK_LIBRARY([$SNMP_LIBNAME], [shutdown_snmp_logging],
|
||||
[AC_DEFINE([HAVE_SHUTDOWN_SNMP_LOGGING], [1],
|
||||
[Define to 1 if SNMP library has the 'shutdown_snmp_logging' function.])],
|
||||
[],
|
||||
[$SNMP_SHARED_LIBADD])
|
||||
|
||||
CFLAGS_SAVE=$CFLAGS
|
||||
LIBS_SAVE=$LIBS
|
||||
CFLAGS="$CFLAGS $SNMP_CFLAGS"
|
||||
LIBS="$LIBS $SNMP_LIBS"
|
||||
|
||||
AC_CHECK_DECL([usmHMAC192SHA256AuthProtocol],
|
||||
[AC_DEFINE([HAVE_SNMP_SHA256], [1],
|
||||
[Define to 1 if SNMP library has the 'usmHMAC192SHA256AuthProtocol'
|
||||
array.])],
|
||||
[],
|
||||
[
|
||||
#include <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
])
|
||||
|
||||
AC_CHECK_DECL([usmHMAC384SHA512AuthProtocol],
|
||||
[AC_DEFINE([HAVE_SNMP_SHA512], [1],
|
||||
[Define to 1 if SNMP library has the 'usmHMAC384SHA512AuthProtocol'
|
||||
array.])],
|
||||
[],
|
||||
[
|
||||
#include <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
])
|
||||
|
||||
CFLAGS=$CFLAGS_SAVE
|
||||
LIBS=$LIBS_SAVE
|
||||
|
||||
PHP_NEW_EXTENSION([snmp], [snmp.c], [$ext_shared])
|
||||
PHP_ADD_EXTENSION_DEP(snmp, spl)
|
||||
PHP_SUBST([SNMP_SHARED_LIBADD])
|
||||
fi
|
||||
@@ -13,11 +13,11 @@ declare(strict_types=1);
|
||||
|
||||
// test php version (8.1 ~ 8.4 available, multiple for matrix)
|
||||
$test_php_version = [
|
||||
'8.1',
|
||||
// '8.1',
|
||||
// '8.2',
|
||||
// '8.3',
|
||||
// '8.4',
|
||||
'8.5',
|
||||
'8.4',
|
||||
// '8.5',
|
||||
// 'git',
|
||||
];
|
||||
|
||||
@@ -30,11 +30,12 @@ $test_os = [
|
||||
'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
|
||||
// 'windows-latest', // .\bin\spc.ps1
|
||||
// 'windows-2022', // .\bin\spc.ps1
|
||||
// 'windows-2025',
|
||||
];
|
||||
|
||||
// whether enable thread safe
|
||||
$zts = false;
|
||||
$zts = true;
|
||||
|
||||
$no_strip = false;
|
||||
|
||||
@@ -49,7 +50,7 @@ $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' => 'gettext',
|
||||
'Linux', 'Darwin' => 'rdkafka',
|
||||
'Windows' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pdo,pdo_mysql,pdo_sqlite,phar,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip',
|
||||
};
|
||||
|
||||
@@ -208,7 +209,7 @@ switch ($argv[1] ?? null) {
|
||||
passthru($prefix . $down_cmd, $retcode);
|
||||
break;
|
||||
case 'build_cmd':
|
||||
passthru($prefix . $build_cmd . ' --build-cli --build-micro', $retcode);
|
||||
passthru($prefix . $build_cmd . ' --build-cli --build-micro --build-cgi', $retcode);
|
||||
break;
|
||||
case 'build_embed_cmd':
|
||||
if ($frankenphp) {
|
||||
|
||||
Reference in New Issue
Block a user