From c8eb62e8f0fbee4bf188cb9e5427b55273135677 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 17:23:13 +0800 Subject: [PATCH 01/35] Add real pkg-config integration --- src/SPC/builder/LibraryBase.php | 40 ++++++---- src/SPC/util/ConfigValidator.php | 3 + src/SPC/util/PkgConfigUtil.php | 69 +++++++++++++++++ src/SPC/util/SPCConfigUtil.php | 112 ++++++++++++++++----------- tests/SPC/util/SPCConfigUtilTest.php | 2 +- 5 files changed, 165 insertions(+), 61 deletions(-) create mode 100644 src/SPC/util/PkgConfigUtil.php diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index b97b5929..8d07f2e5 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -182,20 +182,7 @@ abstract class LibraryBase return LIB_STATUS_INSTALL_FAILED; } } - foreach ($this->getStaticLibs() as $name) { - if (!file_exists(BUILD_LIB_PATH . "/{$name}")) { - $this->tryInstall($lock, true); - return LIB_STATUS_OK; - } - } - foreach ($this->getHeaders() as $name) { - if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) { - $this->tryInstall($lock, true); - return LIB_STATUS_OK; - } - } - // pkg-config is treated specially. If it is pkg-config, check if the pkg-config binary exists - if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) { + if (!$this->isLibraryInstalled()) { $this->tryInstall($lock, true); return LIB_STATUS_OK; } @@ -397,4 +384,29 @@ abstract class LibraryBase } } } + + protected function isLibraryInstalled(): bool + { + foreach (Config::getLib(static::NAME, 'static-libs', []) as $name) { + if (!file_exists(BUILD_LIB_PATH . "/{$name}")) { + return false; + } + } + foreach (Config::getLib(static::NAME, 'headers', []) as $name) { + if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) { + return false; + } + } + foreach (Config::getLib(static::NAME, 'pkg-configs', []) as $name) { + if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$name}.pc")) { + return false; + } + } + foreach (Config::getLib(static::NAME, 'bin', []) as $name) { + if (!file_exists(BUILD_BIN_PATH . "/{$name}")) { + return false; + } + } + return true; + } } diff --git a/src/SPC/util/ConfigValidator.php b/src/SPC/util/ConfigValidator.php index dbc8ce23..b908efce 100644 --- a/src/SPC/util/ConfigValidator.php +++ b/src/SPC/util/ConfigValidator.php @@ -90,6 +90,9 @@ class ConfigValidator if (isset($lib['static-libs' . $suffix]) && !is_list_array($lib['static-libs' . $suffix])) { throw new ValidationException("lib {$name} static-libs must be a list"); } + if (isset($lib['pkg-configs' . $suffix]) && !is_list_array($lib['pkg-configs' . $suffix])) { + throw new ValidationException("lib {$name} pkg-configs must be a list"); + } } // check if frameworks is a list array if (isset($lib['frameworks']) && !is_list_array($lib['frameworks'])) { diff --git a/src/SPC/util/PkgConfigUtil.php b/src/SPC/util/PkgConfigUtil.php new file mode 100644 index 00000000..84c2c3c6 --- /dev/null +++ b/src/SPC/util/PkgConfigUtil.php @@ -0,0 +1,69 @@ +builder = $builder; // BuilderProvider::makeBuilderByInput($input ?? new ArgvInput()); @@ -54,14 +54,17 @@ class SPCConfigUtil } ob_get_clean(); $ldflags = $this->getLdflagsString(); - $libs = $this->getLibsString($libraries, $with_dependencies); + $libs = $this->getLibsString($libraries); if (SPCTarget::getTargetOS() === 'Darwin') { $libs .= " {$this->getFrameworksString($extensions)}"; } - $cflags = $this->getIncludesString(); + $cflags = $this->getIncludesString($libraries); + $libs = trim("-lc {$libs}"); // embed - $libs = trim("-lphp -lc {$libs}"); + if ($this->link_php) { + $libs = "-lphp {$libs}"; + } $extra_env = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'); if (is_string($extra_env)) { $libs .= ' ' . trim($extra_env, '"'); @@ -81,18 +84,33 @@ class SPCConfigUtil ]; } - private function getIncludesString(): string + private function getIncludesString(array $libraries): string { $base = BUILD_INCLUDE_PATH; - $php_embed_includes = [ - "-I{$base}", - "-I{$base}/php", - "-I{$base}/php/main", - "-I{$base}/php/TSRM", - "-I{$base}/php/Zend", - "-I{$base}/php/ext", - ]; - return implode(' ', $php_embed_includes); + $includes = ["-I{$base}"]; + + // link with libphp + if ($this->link_php) { + $includes = [ + ...$includes, + "-I{$base}/php", + "-I{$base}/php/main", + "-I{$base}/php/TSRM", + "-I{$base}/php/Zend", + "-I{$base}/php/ext", + ]; + } + + // parse pkg-configs + foreach ($libraries as $library) { + $pc_cflags = implode(' ', Config::getLib($library, 'pkg-configs', [])); + if ($pc_cflags !== '') { + $pc_cflags = PkgConfigUtil::getCflags($pc_cflags); + $includes[] = $pc_cflags; + } + } + $includes = array_unique($includes); + return implode(' ', $includes); } private function getLdflagsString(): string @@ -100,51 +118,53 @@ class SPCConfigUtil return '-L' . BUILD_LIB_PATH; } - private function getLibsString(array $libraries, bool $withDependencies = false): string + private function getLibsString(array $libraries): string { $short_name = []; - foreach (array_reverse($libraries) as $library) { + $frameworks = []; + + foreach ($libraries as $library) { + // convert all static-libs to short names $libs = Config::getLib($library, 'static-libs', []); foreach ($libs as $lib) { - if ($withDependencies) { - $noExt = str_replace('.a', '', $lib); - $requiredLibs = []; - $pkgconfFile = BUILD_LIB_PATH . "/pkgconfig/{$noExt}.pc"; - if (file_exists($pkgconfFile)) { - $lines = file($pkgconfFile); - foreach ($lines as $value) { - if (str_starts_with($value, 'Libs')) { - $items = explode(' ', $value); - foreach ($items as $item) { - $item = trim($item); - if (str_starts_with($item, '-l')) { - $requiredLibs[] = $item; - } - } - } - } - } else { - $requiredLibs[] = $this->getShortLibName($lib); - } - foreach ($requiredLibs as $requiredLib) { - if (!in_array($requiredLib, $short_name)) { - $short_name[] = $requiredLib; - } - } - } else { - $short_name[] = $this->getShortLibName($lib); + // check file existence + if (!file_exists(BUILD_LIB_PATH . "/{$lib}")) { + throw new WrongUsageException("Library file '{$lib}' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "'. Please build it first."); + } + $short_name[] = $this->getShortLibName($lib); + } + // add frameworks for macOS + if (SPCTarget::getTargetOS() === 'Darwin') { + $frameworks = array_merge($frameworks, Config::getLib($library, 'frameworks', [])); + } + // add pkg-configs libs + $pkg_configs = Config::getLib($library, 'pkg-configs', []); + foreach ($pkg_configs as $pkg_config) { + if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$pkg_config}.pc")) { + throw new WrongUsageException("pkg-config file '{$pkg_config}.pc' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first."); } } - if (PHP_OS_FAMILY !== 'Darwin') { - continue; + $pkg_configs = implode(' ', $pkg_configs); + if ($pkg_configs !== '') { + $pc_libs = PkgConfigUtil::getLibsArray($pkg_configs); + $short_name = [...$short_name, ...$pc_libs]; } - foreach (Config::getLib($library, 'frameworks', []) as $fw) { + } + + // post-process + $short_name = array_unique(array_reverse($short_name)); + $frameworks = array_unique(array_reverse($frameworks)); + + // process frameworks to short_name + if (SPCTarget::getTargetOS() === 'Darwin') { + foreach ($frameworks as $fw) { $ks = '-framework ' . $fw; if (!in_array($ks, $short_name)) { $short_name[] = $ks; } } } + if (in_array('imap', $libraries) && SPCTarget::getLibc() === 'glibc') { $short_name[] = '-lcrypt'; } diff --git a/tests/SPC/util/SPCConfigUtilTest.php b/tests/SPC/util/SPCConfigUtilTest.php index ebd2f92a..c37f01f3 100644 --- a/tests/SPC/util/SPCConfigUtilTest.php +++ b/tests/SPC/util/SPCConfigUtilTest.php @@ -54,7 +54,7 @@ class SPCConfigUtilTest extends TestCase $this->assertStringContainsString('-lphp', $result['libs']); // has cpp - $result = (new SPCConfigUtil())->config(['swoole']); + $result = (new SPCConfigUtil())->config(['rar']); $this->assertStringContainsString(PHP_OS_FAMILY === 'Darwin' ? '-lc++' : '-lstdc++', $result['libs']); // has mimalloc.o in lib dir From 95a94da66fa0e651a506916a961eb99a145353ce Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 17:26:34 +0800 Subject: [PATCH 02/35] Add --no-php option to spc-config --- src/SPC/command/SPCConfigCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SPC/command/SPCConfigCommand.php b/src/SPC/command/SPCConfigCommand.php index a1886ed1..8a54a862 100644 --- a/src/SPC/command/SPCConfigCommand.php +++ b/src/SPC/command/SPCConfigCommand.php @@ -23,6 +23,7 @@ class SPCConfigCommand extends BaseCommand $this->addOption('with-suggested-exts', 'E', null, 'Build with suggested extensions for selected exts'); $this->addOption('includes', null, null, 'Add additional include path'); $this->addOption('libs', null, null, 'Add additional libs path'); + $this->addOption('no-php', null, null, 'Do not link to PHP library'); } /** @@ -37,7 +38,7 @@ class SPCConfigCommand extends BaseCommand $include_suggest_ext = $this->getOption('with-suggested-exts'); $include_suggest_lib = $this->getOption('with-suggested-libs'); - $util = new SPCConfigUtil(); + $util = new SPCConfigUtil(link_php: !$this->getOption('no-php')); $config = $util->config($extensions, $libraries, $include_suggest_ext, $include_suggest_lib); if ($this->getOption('includes')) { From 7e977414a77e075fdfac454ea13841cbb9313507 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 19:59:44 +0800 Subject: [PATCH 03/35] Use spc-config instead of SPC_EXTRA_LIBS, trigger extension test --- config/env.ini | 6 +- config/lib.json | 4 +- src/SPC/builder/freebsd/BSDBuilder.php | 12 ---- src/SPC/builder/linux/LinuxBuilder.php | 15 +---- src/SPC/builder/macos/MacOSBuilder.php | 19 +------ src/SPC/command/BuildCommand.php | 1 - src/SPC/command/SPCConfigCommand.php | 21 ++++--- src/SPC/util/PkgConfigUtil.php | 4 +- src/SPC/util/SPCConfigUtil.php | 78 +++++++++++++++++--------- src/globals/test-extensions.php | 14 ++--- 10 files changed, 85 insertions(+), 89 deletions(-) diff --git a/config/env.ini b/config/env.ini index afbce73c..375ee13c 100644 --- a/config/env.ini +++ b/config/env.ini @@ -89,7 +89,7 @@ LD=${SPC_LINUX_DEFAULT_LD} SPC_DEFAULT_C_FLAGS="-fPIC -Os" SPC_DEFAULT_CXX_FLAGS="-fPIC -Os" ; extra libs for building php executable, used in `make` command for building php (this value may changed by extension build process, space separated) -SPC_EXTRA_LIBS= +SPC_EXTRA_LIBS="" ; upx executable path UPX_EXEC=${PKG_ROOT_PATH}/bin/upx ; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches @@ -119,7 +119,7 @@ SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE ; EXTRA_LIBS for `make` php SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm" ; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so -SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS="" +SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS="-L${BUILD_LIB_PATH}" ; EXTRA_LDFLAGS_PROGRAM for `make` php SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -Wl,-O1 -pie" @@ -134,7 +134,7 @@ CXX=clang++ SPC_DEFAULT_C_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os" SPC_DEFAULT_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os" ; extra libs for building php executable, used in `make` command for building php (this value may changed by extension build process, space separated) -SPC_EXTRA_LIBS= +SPC_EXTRA_LIBS="" ; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches SPC_MICRO_PATCHES=cli_checks,macos_iconv diff --git a/config/lib.json b/config/lib.json index 28775535..26910ec0 100644 --- a/config/lib.json +++ b/config/lib.json @@ -737,8 +737,8 @@ "openssl": { "source": "openssl", "static-libs-unix": [ - "libssl.a", - "libcrypto.a" + "libcrypto.a", + "libssl.a" ], "static-libs-windows": [ "libssl.lib", diff --git a/src/SPC/builder/freebsd/BSDBuilder.php b/src/SPC/builder/freebsd/BSDBuilder.php index 65ebea57..3e9cc80b 100644 --- a/src/SPC/builder/freebsd/BSDBuilder.php +++ b/src/SPC/builder/freebsd/BSDBuilder.php @@ -63,18 +63,6 @@ class BSDBuilder extends UnixBuilderBase */ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void { - // ---------- Update extra-libs ---------- - $extra_libs = $this->getOption('extra-libs', ''); - // add libc++, some extensions or libraries need it (C++ cannot be linked statically) - $extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : ''); - if (!$this->getOption('bloat', false)) { - $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles()); - } else { - logger()->info('bloat linking'); - $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles()))); - } - $this->setOption('extra-libs', $extra_libs); - $this->emitPatchPoint('before-php-buildconf'); SourcePatcher::patchBeforeBuildconf($this); diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 94d8a41e..869f088f 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -11,6 +11,7 @@ use SPC\exception\WrongUsageException; use SPC\store\FileSystem; use SPC\store\SourcePatcher; use SPC\util\GlobalEnvManager; +use SPC\util\SPCConfigUtil; class LinuxBuilder extends UnixBuilderBase { @@ -56,17 +57,6 @@ class LinuxBuilder extends UnixBuilderBase */ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void { - // ---------- Update extra-libs ---------- - $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; - // bloat means force-load all static libraries, even if they are not used - if (!$this->getOption('bloat', false)) { - $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles()); - } else { - $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", array_filter($this->getAllStaticLibFiles()))); - } - // add libstdc++, some extensions or libraries need it - $extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : ''); - f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); $cflags = $this->arch_c_flags; f_putenv('CFLAGS=' . $cflags); @@ -308,9 +298,10 @@ class LinuxBuilder extends UnixBuilderBase private function getMakeExtraVars(): array { + $config = (new SPCConfigUtil($this, ['libs_only_deps' => true, 'absolute_libs' => true]))->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs')); return [ 'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'), - 'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'), + 'EXTRA_LIBS' => $config['libs'], 'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), 'EXTRA_LDFLAGS_PROGRAM' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM'), ]; diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index 362a68fe..50efa013 100644 --- a/src/SPC/builder/macos/MacOSBuilder.php +++ b/src/SPC/builder/macos/MacOSBuilder.php @@ -12,6 +12,7 @@ use SPC\exception\WrongUsageException; use SPC\store\FileSystem; use SPC\store\SourcePatcher; use SPC\util\GlobalEnvManager; +use SPC\util\SPCConfigUtil; class MacOSBuilder extends UnixBuilderBase { @@ -88,21 +89,6 @@ class MacOSBuilder extends UnixBuilderBase */ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void { - $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; - // ---------- Update extra-libs ---------- - // add macOS frameworks - $extra_libs .= (empty($extra_libs) ? '' : ' ') . $this->getFrameworks(true); - // add libc++, some extensions or libraries need it (C++ cannot be linked statically) - $extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : ''); - // bloat means force-load all static libraries, even if they are not used - if (!$this->getOption('bloat', false)) { - $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles()); - } else { - logger()->info('bloat linking'); - $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles()))); - } - f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); - $this->emitPatchPoint('before-php-buildconf'); SourcePatcher::patchBeforeBuildconf($this); @@ -291,9 +277,10 @@ class MacOSBuilder extends UnixBuilderBase private function getMakeExtraVars(): array { + $config = (new SPCConfigUtil($this, ['libs_only_deps' => true]))->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs')); return [ 'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'), - 'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'), + 'EXTRA_LIBS' => $config['libs'], ]; } } diff --git a/src/SPC/command/BuildCommand.php b/src/SPC/command/BuildCommand.php index 6020931f..0285c333 100644 --- a/src/SPC/command/BuildCommand.php +++ b/src/SPC/command/BuildCommand.php @@ -18,7 +18,6 @@ abstract class BuildCommand extends BaseCommand } $this->addOption('with-clean', null, null, 'fresh build, remove `source` and `buildroot` dir before build'); - $this->addOption('bloat', null, null, 'add all libraries into binary'); $this->addOption('rebuild', 'r', null, 'Delete old build and rebuild'); $this->addOption('enable-zts', null, null, 'enable ZTS support'); } diff --git a/src/SPC/command/SPCConfigCommand.php b/src/SPC/command/SPCConfigCommand.php index 8a54a862..4b6d1bc4 100644 --- a/src/SPC/command/SPCConfigCommand.php +++ b/src/SPC/command/SPCConfigCommand.php @@ -23,6 +23,8 @@ class SPCConfigCommand extends BaseCommand $this->addOption('with-suggested-exts', 'E', null, 'Build with suggested extensions for selected exts'); $this->addOption('includes', null, null, 'Add additional include path'); $this->addOption('libs', null, null, 'Add additional libs path'); + $this->addOption('libs-only-deps', null, null, 'Output dependent libraries with -l prefix'); + $this->addOption('absolute-libs', null, null, 'Output absolute paths for libraries'); $this->addOption('no-php', null, null, 'Do not link to PHP library'); } @@ -38,16 +40,19 @@ class SPCConfigCommand extends BaseCommand $include_suggest_ext = $this->getOption('with-suggested-exts'); $include_suggest_lib = $this->getOption('with-suggested-libs'); - $util = new SPCConfigUtil(link_php: !$this->getOption('no-php')); + $util = new SPCConfigUtil(options: [ + 'no_php' => $this->getOption('no-php'), + 'libs_only_deps' => $this->getOption('libs-only-deps'), + 'absolute_libs' => $this->getOption('absolute-libs'), + ]); $config = $util->config($extensions, $libraries, $include_suggest_ext, $include_suggest_lib); - if ($this->getOption('includes')) { - $this->output->writeln($config['cflags']); - } elseif ($this->getOption('libs')) { - $this->output->writeln("{$config['ldflags']} {$config['libs']}"); - } else { - $this->output->writeln("{$config['cflags']} {$config['ldflags']} {$config['libs']}"); - } + $this->output->writeln(match (true) { + $this->getOption('includes') => $config['cflags'], + $this->getOption('libs-only-deps') => $config['libs'], + $this->getOption('libs') => "{$config['ldflags']} {$config['libs']}", + default => "{$config['cflags']} {$config['ldflags']} {$config['libs']}", + }); return 0; } diff --git a/src/SPC/util/PkgConfigUtil.php b/src/SPC/util/PkgConfigUtil.php index 84c2c3c6..d4a4ebed 100644 --- a/src/SPC/util/PkgConfigUtil.php +++ b/src/SPC/util/PkgConfigUtil.php @@ -32,7 +32,7 @@ class PkgConfigUtil * @return array Unique libs array, e.g. [-lz, -lxml, ...] * @throws RuntimeException */ - public static function getLibsArray(string $pkg_config_str): array + public static function getLibsArray(string $pkg_config_str, bool $force_short_name = true): array { // Use this instead of shell() to avoid unnecessary outputs $result = self::execWithResult("pkg-config --static --libs-only-l {$pkg_config_str}"); @@ -44,7 +44,7 @@ class PkgConfigUtil $exp = explode(' ', trim($result)); foreach ($exp as $item) { // if item ends with .a, convert it to -lxxx - if (str_ends_with($item, '.a') && str_starts_with($item, 'lib')) { + if (str_ends_with($item, '.a') && str_starts_with($item, 'lib') && $force_short_name) { $name = pathinfo($item, PATHINFO_BASENAME); $name = substr($name, 3, -2); // remove 'lib' prefix and '.a' suffix $libs[] = "-l{$name}"; diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index d967543f..bb808a7c 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -6,7 +6,6 @@ namespace SPC\util; use SPC\builder\BuilderBase; use SPC\builder\BuilderProvider; -use SPC\builder\macos\MacOSBuilder; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -17,11 +16,27 @@ class SPCConfigUtil { private ?BuilderBase $builder = null; - public function __construct(?BuilderBase $builder = null, private bool $link_php = true) + private bool $no_php; + + private bool $libs_only_deps; + + private bool $absolute_libs; + + /** + * @param array{ + * no_php?: bool, + * libs_only_deps?: bool, + * absolute_libs?: bool + * } $options Options pass to spc-config + */ + public function __construct(?BuilderBase $builder = null, array $options = []) { if ($builder !== null) { $this->builder = $builder; // BuilderProvider::makeBuilderByInput($input ?? new ArgvInput()); } + $this->no_php = $options['no_php'] ?? false; + $this->libs_only_deps = $options['libs_only_deps'] ?? false; + $this->absolute_libs = $options['absolute_libs'] ?? false; } /** @@ -54,24 +69,35 @@ class SPCConfigUtil } ob_get_clean(); $ldflags = $this->getLdflagsString(); - $libs = $this->getLibsString($libraries); - if (SPCTarget::getTargetOS() === 'Darwin') { - $libs .= " {$this->getFrameworksString($extensions)}"; - } $cflags = $this->getIncludesString($libraries); + $libs = $this->getLibsString($libraries, !$this->absolute_libs); - $libs = trim("-lc {$libs}"); - // embed - if ($this->link_php) { - $libs = "-lphp {$libs}"; - } + // additional OS-specific libraries (e.g. macOS -lresolv) $extra_env = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'); if (is_string($extra_env)) { $libs .= ' ' . trim($extra_env, '"'); } - // c++ - if ($this->builder->hasCpp()) { - $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; + $extra_env = getenv('SPC_EXTRA_LIBS'); + if (is_string($extra_env)) { + $libs .= " {$extra_env}"; + } + // extension frameworks + if (SPCTarget::getTargetOS() === 'Darwin') { + $libs .= " {$this->getFrameworksString($extensions)}"; + } + + if ($this->libs_only_deps) { + return [ + 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), + 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), + 'libs' => trim(getenv('LIBS') . ' ' . $libs), + ]; + } + + $libs = trim("-lc {$libs}"); + // embed + if (!$this->no_php) { + $libs = "-lphp {$libs}"; } // mimalloc must come first if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) { @@ -90,7 +116,7 @@ class SPCConfigUtil $includes = ["-I{$base}"]; // link with libphp - if ($this->link_php) { + if (!$this->no_php) { $includes = [ ...$includes, "-I{$base}/php", @@ -118,9 +144,9 @@ class SPCConfigUtil return '-L' . BUILD_LIB_PATH; } - private function getLibsString(array $libraries): string + private function getLibsString(array $libraries, bool $use_short_libs = true): string { - $short_name = []; + $lib_names = []; $frameworks = []; foreach ($libraries as $library) { @@ -131,7 +157,7 @@ class SPCConfigUtil if (!file_exists(BUILD_LIB_PATH . "/{$lib}")) { throw new WrongUsageException("Library file '{$lib}' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "'. Please build it first."); } - $short_name[] = $this->getShortLibName($lib); + $lib_names[] = $use_short_libs ? $this->getShortLibName($lib) : (BUILD_LIB_PATH . "/{$lib}"); } // add frameworks for macOS if (SPCTarget::getTargetOS() === 'Darwin') { @@ -146,29 +172,29 @@ class SPCConfigUtil } $pkg_configs = implode(' ', $pkg_configs); if ($pkg_configs !== '') { - $pc_libs = PkgConfigUtil::getLibsArray($pkg_configs); - $short_name = [...$short_name, ...$pc_libs]; + $pc_libs = array_reverse(PkgConfigUtil::getLibsArray($pkg_configs, $use_short_libs)); + $lib_names = [...$lib_names, ...$pc_libs]; } } // post-process - $short_name = array_unique(array_reverse($short_name)); - $frameworks = array_unique(array_reverse($frameworks)); + $lib_names = array_unique(array_reverse($lib_names)); + $frameworks = array_unique($frameworks); // process frameworks to short_name if (SPCTarget::getTargetOS() === 'Darwin') { foreach ($frameworks as $fw) { $ks = '-framework ' . $fw; - if (!in_array($ks, $short_name)) { - $short_name[] = $ks; + if (!in_array($ks, $lib_names)) { + $lib_names[] = $ks; } } } if (in_array('imap', $libraries) && SPCTarget::getLibc() === 'glibc') { - $short_name[] = '-lcrypt'; + $lib_names[] = '-lcrypt'; } - return implode(' ', $short_name); + return implode(' ', $lib_names); } private function getShortLibName(string $lib): string diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 0358f870..94953bf4 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -13,7 +13,7 @@ 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', @@ -24,16 +24,16 @@ $test_os = [ 'macos-13', // bin/spc for x86_64 // 'macos-14', // bin/spc for arm64 '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', // 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 ]; // whether enable thread safe -$zts = true; +$zts = false; $no_strip = false; @@ -54,7 +54,7 @@ $extensions = match (PHP_OS_FAMILY) { // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). $shared_extensions = match (PHP_OS_FAMILY) { - 'Linux' => 'imagick', + 'Linux' => '', 'Darwin' => '', 'Windows' => '', }; @@ -72,7 +72,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', }; From 6634ade6b4e45e0cff6a814caebf26f02f8c48cb Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 20:41:35 +0800 Subject: [PATCH 04/35] Fix library build failure not interrupt bug --- src/SPC/builder/BuilderBase.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index 184d88dc..3c3acdda 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -66,13 +66,17 @@ abstract class BuilderBase // build all libs foreach ($this->libs as $lib) { $starttime = microtime(true); - match ($lib->setup($this->getOption('rebuild', false))) { + $status = $lib->setup($this->getOption('rebuild', false)); + match ($status) { LIB_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] setup success, took ' . round(microtime(true) - $starttime, 2) . ' s'), LIB_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'), LIB_STATUS_BUILD_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'), LIB_STATUS_INSTALL_FAILED => logger()->error('lib [' . $lib::NAME . '] install failed'), default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'), }; + if (in_array($status, [LIB_STATUS_BUILD_FAILED, LIB_STATUS_INSTALL_FAILED])) { + throw new RuntimeException('Library [' . $lib::NAME . '] setup failed.'); + } } } From 1888b735d1c85bf7258f09329e4be156212dd5fa Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 21:13:35 +0800 Subject: [PATCH 05/35] Fix all extension builds --- config/lib.json | 13 ++-- src/SPC/builder/LibraryBase.php | 3 +- src/SPC/builder/freebsd/library/curl.php | 9 --- src/SPC/builder/linux/library/curl.php | 9 --- src/SPC/builder/linux/library/icu.php | 2 +- src/SPC/builder/linux/library/openssl.php | 9 --- src/SPC/builder/macos/library/icu.php | 2 +- src/SPC/builder/traits/UnixLibraryTrait.php | 49 +++--------- src/SPC/builder/unix/UnixBuilderBase.php | 82 --------------------- src/SPC/builder/unix/library/libxslt.php | 4 +- src/SPC/builder/unix/library/ngtcp2.php | 8 +- src/SPC/builder/unix/library/xz.php | 1 + src/SPC/util/SPCConfigUtil.php | 7 +- 13 files changed, 28 insertions(+), 170 deletions(-) diff --git a/config/lib.json b/config/lib.json index 26910ec0..34104af1 100644 --- a/config/lib.json +++ b/config/lib.json @@ -36,9 +36,9 @@ "brotli": { "source": "brotli", "static-libs-unix": [ + "libbrotlicommon.a", "libbrotlidec.a", - "libbrotlienc.a", - "libbrotlicommon.a" + "libbrotlienc.a" ], "static-libs-windows": [ "brotlicommon.lib", @@ -200,11 +200,10 @@ "icu": { "source": "icu", "cpp-library": true, - "static-libs-unix": [ - "libicui18n.a", - "libicuio.a", - "libicuuc.a", - "libicudata.a" + "pkg-configs": [ + "icu-uc", + "icu-i18n", + "icu-io" ] }, "icu-static-win": { diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 8d07f2e5..13fb9b5a 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -183,8 +183,7 @@ abstract class LibraryBase } } if (!$this->isLibraryInstalled()) { - $this->tryInstall($lock, true); - return LIB_STATUS_OK; + return $this->tryInstall($lock, true); } return LIB_STATUS_ALREADY; } diff --git a/src/SPC/builder/freebsd/library/curl.php b/src/SPC/builder/freebsd/library/curl.php index 4eeab20d..2cad3ee7 100644 --- a/src/SPC/builder/freebsd/library/curl.php +++ b/src/SPC/builder/freebsd/library/curl.php @@ -9,13 +9,4 @@ class curl extends BSDLibraryBase use \SPC\builder\unix\library\curl; public const NAME = 'curl'; - - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string - { - $libs = parent::getStaticLibFiles($style, $recursive, $include_self); - if ($this->builder->getLib('openssl')) { - $this->builder->setOption('extra-libs', $this->builder->getOption('extra-libs') . ' /usr/lib/libpthread.a /usr/lib/libdl.a'); - } - return $libs; - } } diff --git a/src/SPC/builder/linux/library/curl.php b/src/SPC/builder/linux/library/curl.php index f382773f..20ed10f2 100644 --- a/src/SPC/builder/linux/library/curl.php +++ b/src/SPC/builder/linux/library/curl.php @@ -9,13 +9,4 @@ class curl extends LinuxLibraryBase use \SPC\builder\unix\library\curl; public const NAME = 'curl'; - - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string - { - $libs = parent::getStaticLibFiles($style, $recursive, $include_self); - if ($this->builder->getLib('openssl')) { - $libs .= ' -ldl -lpthread'; - } - return $libs; - } } diff --git a/src/SPC/builder/linux/library/icu.php b/src/SPC/builder/linux/library/icu.php index c911a2fe..7b8bcf8e 100644 --- a/src/SPC/builder/linux/library/icu.php +++ b/src/SPC/builder/linux/library/icu.php @@ -38,7 +38,7 @@ class icu extends LinuxLibraryBase ->exec("make -j{$this->builder->concurrency}") ->exec('make install'); - $this->patchPkgconfPrefix(['icu-i18n.pc', 'icu-io.pc', 'icu-uc.pc'], PKGCONF_PATCH_PREFIX); + $this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX); FileSystem::removeDir(BUILD_LIB_PATH . '/icu'); } } diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index 252eb47f..1030cfb8 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -91,13 +91,4 @@ class openssl extends LinuxLibraryBase FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Libs.private: ${libdir}/libz.a'); FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")'); } - - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string - { - $libFiles = parent::getStaticLibFiles($style, $recursive, $include_self); - if (!str_contains('-ldl -lpthread', $libFiles)) { - $libFiles .= ' -ldl -lpthread'; - } - return $libFiles; - } } diff --git a/src/SPC/builder/macos/library/icu.php b/src/SPC/builder/macos/library/icu.php index d49f43f8..ebe1946f 100644 --- a/src/SPC/builder/macos/library/icu.php +++ b/src/SPC/builder/macos/library/icu.php @@ -21,7 +21,7 @@ class icu extends MacOSLibraryBase ->exec("make -j{$this->builder->concurrency}") ->exec('make install'); - $this->patchPkgconfPrefix(['icu-i18n.pc', 'icu-io.pc', 'icu-uc.pc'], PKGCONF_PATCH_PREFIX); + $this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX); FileSystem::removeDir(BUILD_LIB_PATH . '/icu'); } } diff --git a/src/SPC/builder/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index e98a6f3a..21ed4a6d 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -4,11 +4,12 @@ declare(strict_types=1); namespace SPC\builder\traits; -use SPC\builder\LibraryBase; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\store\Config; use SPC\store\FileSystem; +use SPC\util\SPCConfigUtil; trait UnixLibraryTrait { @@ -17,44 +18,13 @@ trait UnixLibraryTrait * @throws FileSystemException * @throws WrongUsageException */ - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string + public function getStaticLibFiles(bool $include_self = true): string { $libs = $include_self ? [$this] : []; - if ($recursive) { - array_unshift($libs, ...array_values($this->getDependencies(recursive: true))); - } - - $sep = match ($style) { - 'autoconf' => ' ', - 'cmake' => ';', - default => throw new RuntimeException('style only support autoconf and cmake'), - }; - $ret = []; - /** @var LibraryBase $lib */ - foreach ($libs as $lib) { - $libFiles = []; - foreach ($lib->getStaticLibs() as $name) { - $name = str_replace(' ', '\ ', FileSystem::convertPath(BUILD_LIB_PATH . "/{$name}")); - $name = str_replace('"', '\"', $name); - $libFiles[] = $name; - } - array_unshift($ret, implode($sep, $libFiles)); - } - return implode($sep, $ret); - } - - /** - * @throws FileSystemException - * @throws RuntimeException - * @throws WrongUsageException - */ - public function makeAutoconfEnv(?string $prefix = null): string - { - if ($prefix === null) { - $prefix = str_replace('-', '_', strtoupper(static::NAME)); - } - return $prefix . '_CFLAGS="-I' . BUILD_INCLUDE_PATH . '" ' . - $prefix . '_LIBS="' . $this->getStaticLibFiles() . '"'; + array_unshift($libs, ...array_values($this->getDependencies(recursive: true))); + $config = new SPCConfigUtil($this->builder, options: ['libs_only_deps' => true, 'absolute_libs' => true]); + $res = $config->config(libraries: array_map(fn ($x) => $x->getName(), $libs)); + return $res['libs']; } /** @@ -64,9 +34,12 @@ trait UnixLibraryTrait * @throws FileSystemException * @throws RuntimeException */ - public function patchPkgconfPrefix(array $files, int $patch_option = PKGCONF_PATCH_ALL, ?array $custom_replace = null): void + public function patchPkgconfPrefix(array $files = [], int $patch_option = PKGCONF_PATCH_ALL, ?array $custom_replace = null): void { logger()->info('Patching library [' . static::NAME . '] pkgconfig'); + if ($files === [] && ($conf_pc = Config::getLib(static::NAME, 'pkg-configs', [])) !== []) { + $files = array_map(fn ($x) => "{$x}.pc", $conf_pc); + } foreach ($files as $name) { $realpath = realpath(BUILD_ROOT_PATH . '/lib/pkgconfig/' . $name); if ($realpath === false) { diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index f0e4e169..9ba6f2fd 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -5,9 +5,6 @@ declare(strict_types=1); namespace SPC\builder\unix; use SPC\builder\BuilderBase; -use SPC\builder\freebsd\library\BSDLibraryBase; -use SPC\builder\linux\library\LinuxLibraryBase; -use SPC\builder\macos\library\MacOSLibraryBase; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -27,85 +24,6 @@ abstract class UnixBuilderBase extends BuilderBase /** @var string C++ flags */ public string $arch_cxx_flags; - /** - * @throws WrongUsageException - * @throws FileSystemException - */ - public function getAllStaticLibFiles(): array - { - $libs = []; - - // reorder libs - foreach ($this->libs as $lib) { - foreach ($lib->getDependencies() as $dep) { - $libs[] = $dep; - } - $libs[] = $lib; - } - - $libFiles = []; - $libNames = []; - // merge libs - foreach ($libs as $lib) { - if (!in_array($lib::NAME, $libNames, true)) { - $libNames[] = $lib::NAME; - array_unshift($libFiles, ...$lib->getStaticLibs()); - } - } - return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles); - } - - /** - * Generate configure flags - */ - public function makeAutoconfFlags(int $flag = AUTOCONF_ALL): string - { - $extra = ''; - // TODO: add auto pkg-config support - if (($flag & AUTOCONF_LIBS) === AUTOCONF_LIBS) { - $extra .= 'LIBS="' . BUILD_LIB_PATH . '" '; - } - if (($flag & AUTOCONF_CFLAGS) === AUTOCONF_CFLAGS) { - $extra .= 'CFLAGS="-I' . BUILD_INCLUDE_PATH . '" '; - } - if (($flag & AUTOCONF_CPPFLAGS) === AUTOCONF_CPPFLAGS) { - $extra .= 'CPPFLAGS="-I' . BUILD_INCLUDE_PATH . '" '; - } - if (($flag & AUTOCONF_LDFLAGS) === AUTOCONF_LDFLAGS) { - $extra .= 'LDFLAGS="-L' . BUILD_LIB_PATH . '" '; - } - return $extra; - } - - /** - * @throws FileSystemException - * @throws RuntimeException - * @throws WrongUsageException - */ - public function makeAutoconfArgs(string $name, array $libSpecs): string - { - $ret = ''; - foreach ($libSpecs as $libName => $arr) { - $lib = $this->getLib($libName); - if ($lib === null && str_starts_with($libName, 'lib')) { - $lib = $this->getLib(substr($libName, 3)); - } - - $arr = $arr ?? []; - - $disableArgs = $arr[0] ?? null; - $prefix = $arr[1] ?? null; - if ($lib instanceof LinuxLibraryBase || $lib instanceof MacOSLibraryBase || $lib instanceof BSDLibraryBase) { - logger()->info("{$name} \033[32;1mwith\033[0;1m {$libName} support"); - $ret .= "--with-{$libName}=yes " . $lib->makeAutoconfEnv($prefix) . ' '; - } else { - logger()->info("{$name} \033[31;1mwithout\033[0;1m {$libName} support"); - $ret .= ($disableArgs ?? "--with-{$libName}=no") . ' '; - } - } - return rtrim($ret); - } - public function proveLibs(array $sorted_libraries): void { // search all supported libs diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index aabc277d..63500566 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -24,7 +24,7 @@ trait libxslt ->appendEnv([ 'CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}", - 'LIBS' => "{$static_libs} -lstdc++", + 'LIBS' => "{$static_libs}", ]) ->addConfigureArgs( '--without-python', @@ -41,7 +41,7 @@ trait libxslt } $ac->configure()->make(); - $this->patchPkgconfPrefix(['libexslt.pc']); + $this->patchPkgconfPrefix(['libxslt.pc']); $this->patchLaDependencyPrefix(); shell()->cd(BUILD_LIB_PATH) ->exec("ar -t libxslt.a | grep '\\.a$' | xargs -n1 ar d libxslt.a") diff --git a/src/SPC/builder/unix/library/ngtcp2.php b/src/SPC/builder/unix/library/ngtcp2.php index df29fba3..644bab4e 100644 --- a/src/SPC/builder/unix/library/ngtcp2.php +++ b/src/SPC/builder/unix/library/ngtcp2.php @@ -21,8 +21,6 @@ trait ngtcp2 UnixAutoconfExecutor::create($this) ->optionalLib('openssl', fn ($lib) => implode(' ', [ '--with-openssl=yes', - "OPENSSL_LIBS=\"{$lib->getStaticLibFiles()}\"", - "OPENSSL_CFLAGS=\"-I{$lib->getIncludeDir()}\"", ]), '--with-openssl=no') ->optionalLib('libev', ...ac_with_args('libev', true)) ->optionalLib('nghttp3', ...ac_with_args('libnghttp3', true)) @@ -30,12 +28,8 @@ trait ngtcp2 ->optionalLib( 'brotli', fn ($lib) => implode(' ', [ - '--with-brotlidec=yes', - "LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", - "LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"", + '--with-libbrotlidec=yes', '--with-libbrotlienc=yes', - "LIBBROTLIENC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", - "LIBBROTLIENC_LIBS=\"{$lib->getStaticLibFiles()}\"", ]) ) ->appendEnv(['PKG_CONFIG' => '$PKG_CONFIG --static']) diff --git a/src/SPC/builder/unix/library/xz.php b/src/SPC/builder/unix/library/xz.php index f127e59a..98f33bea 100644 --- a/src/SPC/builder/unix/library/xz.php +++ b/src/SPC/builder/unix/library/xz.php @@ -21,6 +21,7 @@ trait xz '--disable-scripts', '--disable-doc', '--with-libiconv', + '--bindir=/tmp/xz', // xz binary will corrupt `tar` command, that's really strange. ) ->make(); $this->patchPkgconfPrefix(['liblzma.pc']); diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index bb808a7c..0d165231 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -6,6 +6,7 @@ namespace SPC\util; use SPC\builder\BuilderBase; use SPC\builder\BuilderProvider; +use SPC\builder\macos\MacOSBuilder; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -78,13 +79,14 @@ class SPCConfigUtil $libs .= ' ' . trim($extra_env, '"'); } $extra_env = getenv('SPC_EXTRA_LIBS'); - if (is_string($extra_env)) { + if (is_string($extra_env) && !empty($extra_env)) { $libs .= " {$extra_env}"; } // extension frameworks if (SPCTarget::getTargetOS() === 'Darwin') { $libs .= " {$this->getFrameworksString($extensions)}"; } + $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; if ($this->libs_only_deps) { return [ @@ -94,10 +96,9 @@ class SPCConfigUtil ]; } - $libs = trim("-lc {$libs}"); // embed if (!$this->no_php) { - $libs = "-lphp {$libs}"; + $libs = "-lphp -lc {$libs}"; } // mimalloc must come first if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) { From dfbc9a7fffe7fdd67e60fb281cdd1d651d8252ad Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 21:14:25 +0800 Subject: [PATCH 06/35] Trigger common extension test --- src/globals/test-extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 94953bf4..320e6404 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -72,7 +72,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' => 'bulk', + 'Linux', 'Darwin' => 'common', 'Windows' => 'none', }; From 062cc84d5186525cee4799aa83a66487888ef3cb Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 21:15:22 +0800 Subject: [PATCH 07/35] Fix phpunit --- tests/SPC/builder/ExtensionTest.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/SPC/builder/ExtensionTest.php b/tests/SPC/builder/ExtensionTest.php index 499a800f..c387dc99 100644 --- a/tests/SPC/builder/ExtensionTest.php +++ b/tests/SPC/builder/ExtensionTest.php @@ -78,11 +78,6 @@ class ExtensionTest extends TestCase } } - public function testGetLibFilesString() - { - $this->assertStringEndsWith('libonig.a', $this->extension->getLibFilesString()); - } - public function testGetName() { $this->assertEquals('mbregex', $this->extension->getName()); From 6dd4406782964aea71fdbde42d74f609119a9f00 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 21:19:11 +0800 Subject: [PATCH 08/35] Disable extension test's UPX --- .github/workflows/ext-matrix-tests.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/ext-matrix-tests.yml b/.github/workflows/ext-matrix-tests.yml index 1c04f5c9..e38ed2ed 100644 --- a/.github/workflows/ext-matrix-tests.yml +++ b/.github/workflows/ext-matrix-tests.yml @@ -136,11 +136,4 @@ jobs: - name: "Build library: ${{ matrix.library }}" run: | SPC_USE_SUDO=yes ./bin/spc doctor --auto-fix - if [ "${{ env.OS }}" = "linux-x86_64" ]; then - ./bin/spc install-pkg upx - UPX=--with-upx-pack - elif [ "${{ env.OS }}" = "linux-aarch64" ]; then - ./bin/spc install-pkg upx - UPX=--with-upx-pack - fi - ./bin/spc build --build-cli --build-micro --build-fpm ${{ matrix.extension }} --debug $UPX --with-suggested-libs --with-suggested-exts + ./bin/spc build --build-cli --build-micro --build-fpm ${{ matrix.extension }} --debug --with-suggested-libs --with-suggested-exts From f2ccabf0628c4fa52f66563541cf7a7c1bd6ee99 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 21:54:27 +0800 Subject: [PATCH 09/35] Fix library base, fix brotli and curl libs, trigger extension test --- config/lib.json | 8 ++++---- src/SPC/builder/LibraryBase.php | 24 ++---------------------- src/SPC/builder/unix/library/curl.php | 8 ++++---- 3 files changed, 10 insertions(+), 30 deletions(-) diff --git a/config/lib.json b/config/lib.json index 34104af1..cffda176 100644 --- a/config/lib.json +++ b/config/lib.json @@ -35,10 +35,10 @@ }, "brotli": { "source": "brotli", - "static-libs-unix": [ - "libbrotlicommon.a", - "libbrotlidec.a", - "libbrotlienc.a" + "pkg-configs": [ + "libbrotlicommon", + "libbrotlidec", + "libbrotlienc" ], "static-libs-windows": [ "brotlicommon.lib", diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 13fb9b5a..c211b97d 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -226,28 +226,8 @@ abstract class LibraryBase return LIB_STATUS_OK; } - // check if these libraries exist, if not, invoke compilation and return the result status - foreach ($this->getStaticLibs() as $name) { - if (!file_exists(BUILD_LIB_PATH . "/{$name}")) { - $this->tryBuild(true); - return LIB_STATUS_OK; - } - } - // header files the same - foreach ($this->getHeaders() as $name) { - if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) { - $this->tryBuild(true); - return LIB_STATUS_OK; - } - } - // current library is package and binary file is not exists - if (Config::getLib(static::NAME, 'type', 'lib') === 'package') { - foreach ($this->getBinaryFiles() as $name) { - if (!file_exists(BUILD_BIN_PATH . "/{$name}")) { - $this->tryBuild(true); - return LIB_STATUS_OK; - } - } + if (!$this->isLibraryInstalled()) { + return $this->tryBuild(true); } // if all the files exist at this point, skip the compilation process return LIB_STATUS_ALREADY; diff --git a/src/SPC/builder/unix/library/curl.php b/src/SPC/builder/unix/library/curl.php index c38201e5..6e304d60 100644 --- a/src/SPC/builder/unix/library/curl.php +++ b/src/SPC/builder/unix/library/curl.php @@ -21,10 +21,10 @@ trait curl UnixCMakeExecutor::create($this) ->optionalLib('openssl', '-DCURL_USE_OPENSSL=ON -DCURL_CA_BUNDLE=OFF -DCURL_CA_PATH=OFF -DCURL_CA_FALLBACK=ON', '-DCURL_USE_OPENSSL=OFF -DCURL_ENABLE_SSL=OFF') ->optionalLib('brotli', ...cmake_boolean_args('CURL_BROTLI')) - ->optionalLib('libssh2', fn ($lib) => "-DLIBSSH2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DLIBSSH2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DCURL_USE_LIBSSH2=OFF') - ->optionalLib('nghttp2', fn ($lib) => "-DUSE_NGHTTP2=ON -DNGHTTP2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP2=OFF') - ->optionalLib('nghttp3', fn ($lib) => "-DUSE_NGHTTP3=ON -DNGHTTP3_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP3_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP3=OFF') - ->optionalLib('ngtcp2', fn ($lib) => "-DUSE_NGTCP2=ON -DNGNGTCP2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGNGTCP2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGTCP2=OFF') + ->optionalLib('libssh2', ...cmake_boolean_args('CURL_USE_LIBSSH2')) + ->optionalLib('nghttp2', ...cmake_boolean_args('USE_NGHTTP2')) + ->optionalLib('nghttp3', ...cmake_boolean_args('USE_NGHTTP3')) + ->optionalLib('ngtcp2', ...cmake_boolean_args('USE_NGTCP2')) ->optionalLib('ldap', ...cmake_boolean_args('CURL_DISABLE_LDAP', true)) ->optionalLib('zstd', ...cmake_boolean_args('CURL_ZSTD')) ->optionalLib('idn2', ...cmake_boolean_args('USE_LIBIDN2')) From 2c81ca2bf838a3647d8188a12e2954a5b18fbe41 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 22:00:39 +0800 Subject: [PATCH 10/35] Replace example.com --- src/globals/ext-tests/curl.php | 2 +- src/globals/ext-tests/openssl.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/globals/ext-tests/curl.php b/src/globals/ext-tests/curl.php index a890a8cf..7c3eecf7 100644 --- a/src/globals/ext-tests/curl.php +++ b/src/globals/ext-tests/curl.php @@ -9,7 +9,7 @@ assert(function_exists('curl_close')); $curl_version = curl_version(); if (stripos($curl_version['ssl_version'], 'schannel') !== false) { $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, 'https://example.com/'); + curl_setopt($curl, CURLOPT_URL, 'https://captive.apple.com/'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER, 0); $data = curl_exec($curl); diff --git a/src/globals/ext-tests/openssl.php b/src/globals/ext-tests/openssl.php index 3b3452b3..0453101a 100644 --- a/src/globals/ext-tests/openssl.php +++ b/src/globals/ext-tests/openssl.php @@ -5,5 +5,5 @@ declare(strict_types=1); assert(function_exists('openssl_digest')); assert(openssl_digest('123456', 'md5') === 'e10adc3949ba59abbe56e057f20f883e'); if (file_exists('/etc/ssl/openssl.cnf')) { - assert(file_get_contents('https://example.com/') !== false); + assert(file_get_contents('https://captive.apple.com/') !== false); } From a095d489f35e6d2551ae45aed537708a9d5b36bc Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 22:09:45 +0800 Subject: [PATCH 11/35] Fix libwebp static libs order --- config/lib.json | 12 ++++++------ src/SPC/builder/unix/library/libwebp.php | 3 +-- src/SPC/util/SPCConfigUtil.php | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/config/lib.json b/config/lib.json index cffda176..27825387 100644 --- a/config/lib.json +++ b/config/lib.json @@ -555,12 +555,12 @@ }, "libwebp": { "source": "libwebp", - "static-libs-unix": [ - "libwebp.a", - "libwebpdecoder.a", - "libwebpdemux.a", - "libwebpmux.a", - "libsharpyuv.a" + "pkg-configs": [ + "libwebp", + "libwebpdecoder", + "libwebpdemux", + "libwebpmux", + "libsharpyuv" ], "static-libs-windows": [ "libwebp.lib", diff --git a/src/SPC/builder/unix/library/libwebp.php b/src/SPC/builder/unix/library/libwebp.php index 32331ea2..a7651dd5 100644 --- a/src/SPC/builder/unix/library/libwebp.php +++ b/src/SPC/builder/unix/library/libwebp.php @@ -22,8 +22,7 @@ trait libwebp ->addConfigureArgs('-DWEBP_BUILD_EXTRAS=ON') ->build(); // patch pkgconfig - $this->patchPkgconfPrefix(['libsharpyuv.pc', 'libwebp.pc', 'libwebpdecoder.pc', 'libwebpdemux.pc', 'libwebpmux.pc'], PKGCONF_PATCH_PREFIX | PKGCONF_PATCH_LIBDIR); + $this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX | PKGCONF_PATCH_LIBDIR); $this->patchPkgconfPrefix(['libsharpyuv.pc'], PKGCONF_PATCH_CUSTOM, ['/^includedir=.*$/m', 'includedir=${prefix}/include/webp']); - $this->patchPkgconfPrefix(['libwebp.pc'], PKGCONF_PATCH_CUSTOM, ['/-lwebp$/m', '-lwebp -lsharpyuv']); } } diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 0d165231..595e330f 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -86,7 +86,7 @@ class SPCConfigUtil if (SPCTarget::getTargetOS() === 'Darwin') { $libs .= " {$this->getFrameworksString($extensions)}"; } - $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; + $libs .= $this->builder->hasCpp() && $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; if ($this->libs_only_deps) { return [ From a88f9933d2297db678f4579ccaf4076f5db2a739 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 22:25:16 +0800 Subject: [PATCH 12/35] Fix unique and reverse order --- src/SPC/util/SPCConfigUtil.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 595e330f..770f8762 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -179,7 +179,7 @@ class SPCConfigUtil } // post-process - $lib_names = array_unique(array_reverse($lib_names)); + $lib_names = array_reverse(array_unique($lib_names)); $frameworks = array_unique($frameworks); // process frameworks to short_name From 4cdafe2497d88bc3bbf73ef1ae7dff2a723101d8 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 22:25:21 +0800 Subject: [PATCH 13/35] Fix unique and reverse order --- src/SPC/util/PkgConfigUtil.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SPC/util/PkgConfigUtil.php b/src/SPC/util/PkgConfigUtil.php index d4a4ebed..b6423630 100644 --- a/src/SPC/util/PkgConfigUtil.php +++ b/src/SPC/util/PkgConfigUtil.php @@ -55,7 +55,8 @@ class PkgConfigUtil } } - return array_unique($libs); + // enhancement for linker + return array_reverse(array_unique(array_reverse($libs))); } private static function execWithResult(string $cmd): string From dea3c4afeb8f2e68ac26e531912873144e82a327 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 22:25:46 +0800 Subject: [PATCH 14/35] Looks like ngtcp2 does not happy with pkg-config --- src/SPC/builder/unix/library/ngtcp2.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/SPC/builder/unix/library/ngtcp2.php b/src/SPC/builder/unix/library/ngtcp2.php index 644bab4e..9c9919d8 100644 --- a/src/SPC/builder/unix/library/ngtcp2.php +++ b/src/SPC/builder/unix/library/ngtcp2.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace SPC\builder\unix\library; +use SPC\builder\linux\library\LinuxLibraryBase; +use SPC\builder\macos\library\MacOSLibraryBase; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -19,17 +21,23 @@ trait ngtcp2 protected function build(): void { UnixAutoconfExecutor::create($this) - ->optionalLib('openssl', fn ($lib) => implode(' ', [ + ->optionalLib('openssl', fn (LinuxLibraryBase|MacOSLibraryBase $lib) => implode(' ', [ '--with-openssl=yes', + "OPENSSL_LIBS=\"{$lib->getStaticLibFiles()}\"", + "OPENSSL_CFLAGS=\"-I{$lib->getIncludeDir()}\"", ]), '--with-openssl=no') ->optionalLib('libev', ...ac_with_args('libev', true)) ->optionalLib('nghttp3', ...ac_with_args('libnghttp3', true)) ->optionalLib('jemalloc', ...ac_with_args('jemalloc', true)) ->optionalLib( 'brotli', - fn ($lib) => implode(' ', [ - '--with-libbrotlidec=yes', + fn (LinuxLibraryBase|MacOSLibraryBase $lib) => implode(' ', [ + '--with-brotlidec=yes', + "LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", + "LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"", '--with-libbrotlienc=yes', + "LIBBROTLIENC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", + "LIBBROTLIENC_LIBS=\"{$lib->getStaticLibFiles()}\"", ]) ) ->appendEnv(['PKG_CONFIG' => '$PKG_CONFIG --static']) From 099425abc8c62dd579e458c5de5315ba64ebec26 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 22:46:13 +0800 Subject: [PATCH 15/35] Fix c++, check pkg-config exists before calling PkgConfigUtil --- src/SPC/util/SPCConfigUtil.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 770f8762..bcac8287 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -86,8 +86,9 @@ class SPCConfigUtil if (SPCTarget::getTargetOS() === 'Darwin') { $libs .= " {$this->getFrameworksString($extensions)}"; } - $libs .= $this->builder->hasCpp() && $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; - + if ($this->builder->hasCpp()) { + $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; + } if ($this->libs_only_deps) { return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), @@ -130,7 +131,13 @@ class SPCConfigUtil // parse pkg-configs foreach ($libraries as $library) { - $pc_cflags = implode(' ', Config::getLib($library, 'pkg-configs', [])); + $pc = Config::getLib($library, 'pkg-configs', []); + foreach ($pc as $file) { + if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$file}.pc")) { + throw new WrongUsageException("pkg-config file '{$file}.pc' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first."); + } + } + $pc_cflags = implode(' ', $pc); if ($pc_cflags !== '') { $pc_cflags = PkgConfigUtil::getCflags($pc_cflags); $includes[] = $pc_cflags; From ffa5219d23c70e349890ecae2fa0354c93eeaab1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 23:18:19 +0800 Subject: [PATCH 16/35] trigger extension test --- src/globals/test-extensions.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 320e6404..50e0fc9e 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -21,11 +21,11 @@ $test_php_version = [ // test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available) $test_os = [ - 'macos-13', // bin/spc for x86_64 + // 'macos-13', // bin/spc for x86_64 // 'macos-14', // bin/spc for arm64 - 'macos-15', // bin/spc for arm64 - 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 - 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 + // 'macos-15', // bin/spc for arm64 + // '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 @@ -72,7 +72,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' => 'common', + 'Linux', 'Darwin' => 'none', 'Windows' => 'none', }; From b5ceda5955b30b4f0d075b0160a08ca3f21545a4 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 00:38:25 +0800 Subject: [PATCH 17/35] Fix libxslt build again --- src/SPC/builder/unix/library/libxslt.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index 63500566..6df9374f 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -4,7 +4,8 @@ declare(strict_types=1); namespace SPC\builder\unix\library; -use SPC\builder\linux\library\LinuxLibraryBase; +use SPC\builder\linux\LinuxBuilder; +use SPC\builder\macos\MacOSBuilder; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -19,12 +20,13 @@ trait libxslt */ protected function build(): void { - $static_libs = $this instanceof LinuxLibraryBase ? $this->getStaticLibFiles(include_self: false) : ''; + $static_libs = $this->builder instanceof LinuxBuilder ? $this->getStaticLibFiles(include_self: false) : ''; + $cpp = $this->builder instanceof MacOSBuilder ? '-lc++' : '-lstdc++'; $ac = UnixAutoconfExecutor::create($this) ->appendEnv([ 'CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}", - 'LIBS' => "{$static_libs}", + 'LIBS' => "{$static_libs} {$cpp}", ]) ->addConfigureArgs( '--without-python', From 0d408e0df1d964218054bff207de1e43489c0b39 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 00:38:36 +0800 Subject: [PATCH 18/35] Allow empty target --- src/SPC/util/SPCTarget.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/util/SPCTarget.php b/src/SPC/util/SPCTarget.php index 071f2620..b674379e 100644 --- a/src/SPC/util/SPCTarget.php +++ b/src/SPC/util/SPCTarget.php @@ -73,7 +73,7 @@ class SPCTarget public static function getTargetOS(): string { $target = getenv('SPC_TARGET'); - if ($target === false) { + if ($target === false || $target === '') { return PHP_OS_FAMILY; } // TODO: zig target parser like below? From a2e0efaed31fbd4bbdb49c69c645086a9e728e88 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 00:45:06 +0800 Subject: [PATCH 19/35] extension test --- config/lib.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/config/lib.json b/config/lib.json index 27825387..b46b2735 100644 --- a/config/lib.json +++ b/config/lib.json @@ -220,10 +220,10 @@ }, "imagemagick": { "source": "imagemagick", - "static-libs-unix": [ - "libMagick++-7.Q16HDRI.a", - "libMagickWand-7.Q16HDRI.a", - "libMagickCore-7.Q16HDRI.a" + "pkg-configs": [ + "Magick++-7.Q16HDRI", + "MagickCore-7.Q16HDRI", + "MagickWand-7.Q16HDRI" ], "lib-depends": [ "zlib", @@ -266,9 +266,9 @@ }, "ldap": { "source": "ldap", - "static-libs-unix": [ - "libldap.a", - "liblber.a" + "pkg-configs": [ + "ldap", + "lber" ], "lib-depends": [ "openssl", @@ -421,11 +421,11 @@ }, "libjxl": { "source": "libjxl", - "static-libs-unix": [ - "libjxl.a", - "libjxl_cms.a", - "libjxl_threads.a", - "libhwy.a" + "pkg-configs": [ + "libjxl", + "libjxl_cms", + "libjxl_threads", + "libhwy" ], "lib-depends": [ "brotli", From 154a21fbaf5a6795ce8afcbf31d47ddb674c86e5 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 00:48:37 +0800 Subject: [PATCH 20/35] phpstan, extension test --- src/SPC/builder/unix/library/libxslt.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index 6df9374f..582d22ec 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -4,8 +4,8 @@ declare(strict_types=1); namespace SPC\builder\unix\library; -use SPC\builder\linux\LinuxBuilder; -use SPC\builder\macos\MacOSBuilder; +use SPC\builder\linux\library\LinuxLibraryBase; +use SPC\builder\macos\library\MacOSLibraryBase; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -20,8 +20,8 @@ trait libxslt */ protected function build(): void { - $static_libs = $this->builder instanceof LinuxBuilder ? $this->getStaticLibFiles(include_self: false) : ''; - $cpp = $this->builder instanceof MacOSBuilder ? '-lc++' : '-lstdc++'; + $static_libs = $this instanceof LinuxLibraryBase ? $this->getStaticLibFiles(include_self: false) : ''; + $cpp = $this instanceof MacOSLibraryBase ? '-lc++' : '-lstdc++'; $ac = UnixAutoconfExecutor::create($this) ->appendEnv([ 'CFLAGS' => "-I{$this->getIncludeDir()}", From 779c7cec30ba5767da17b578809523f6be8c0355 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 01:32:42 +0800 Subject: [PATCH 21/35] test pgsql --- config/lib.json | 6 ++---- src/globals/test-extensions.php | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/config/lib.json b/config/lib.json index b46b2735..4bb73100 100644 --- a/config/lib.json +++ b/config/lib.json @@ -752,10 +752,8 @@ }, "postgresql": { "source": "postgresql", - "static-libs-unix": [ - "libpq.a", - "libpgport.a", - "libpgcommon.a" + "pkg-configs": [ + "libpq" ], "lib-depends": [ "libiconv", diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 50e0fc9e..e7fcbb51 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -24,7 +24,7 @@ $test_os = [ // 'macos-13', // bin/spc for x86_64 // 'macos-14', // bin/spc for arm64 // '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 @@ -48,7 +48,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' => 'bcmath', + 'Linux', 'Darwin' => 'pgsql,pdo_pgsql', 'Windows' => 'intl', }; From 9c4a6b46b629f743ea868b2393cb810668334ee8 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 09:57:09 +0800 Subject: [PATCH 22/35] Fix pkg-config missing option --- src/SPC/util/PkgConfigUtil.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/util/PkgConfigUtil.php b/src/SPC/util/PkgConfigUtil.php index b6423630..3f61582d 100644 --- a/src/SPC/util/PkgConfigUtil.php +++ b/src/SPC/util/PkgConfigUtil.php @@ -39,7 +39,7 @@ class PkgConfigUtil $libs = explode(' ', trim($result)); // get other things - $result = self::execWithResult("pkg-config --libs --libs-only-other {$pkg_config_str}"); + $result = self::execWithResult("pkg-config --static --libs --libs-only-other {$pkg_config_str}"); // convert libxxx.a to -L{path} -lxxx $exp = explode(' ', trim($result)); foreach ($exp as $item) { From b6be20727d95b23ee2d4efb566893b876eac3fe4 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 23 Jul 2025 09:46:32 +0700 Subject: [PATCH 23/35] fix a few accidental array_reverse calls, pkg-config --static instead of pkg-config --libs --- src/SPC/util/PkgConfigUtil.php | 17 +++++++++++------ src/SPC/util/SPCConfigUtil.php | 13 +++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/SPC/util/PkgConfigUtil.php b/src/SPC/util/PkgConfigUtil.php index 3f61582d..db2f4431 100644 --- a/src/SPC/util/PkgConfigUtil.php +++ b/src/SPC/util/PkgConfigUtil.php @@ -39,18 +39,23 @@ class PkgConfigUtil $libs = explode(' ', trim($result)); // get other things - $result = self::execWithResult("pkg-config --static --libs --libs-only-other {$pkg_config_str}"); + $result = self::execWithResult("pkg-config --static --libs-only-other {$pkg_config_str}"); // convert libxxx.a to -L{path} -lxxx $exp = explode(' ', trim($result)); foreach ($exp as $item) { + if (str_starts_with($item, '-L')) { + $libs[] = $item; + continue; + } // if item ends with .a, convert it to -lxxx - if (str_ends_with($item, '.a') && str_starts_with($item, 'lib') && $force_short_name) { + if (str_ends_with($item, '.a') && (str_starts_with($item, 'lib') || str_starts_with($item, BUILD_LIB_PATH))) { $name = pathinfo($item, PATHINFO_BASENAME); $name = substr($name, 3, -2); // remove 'lib' prefix and '.a' suffix - $libs[] = "-l{$name}"; - } else { - // if item starts with -L, keep it as is - // if item starts with -l, keep it as is + $shortlib = "-l{$name}"; + if (!in_array($shortlib, $libs)) { + $libs[] = $shortlib; + } + } elseif (!in_array($item, $libs)) { $libs[] = $item; } } diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index bcac8287..4ce5253c 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -87,9 +87,10 @@ class SPCConfigUtil $libs .= " {$this->getFrameworksString($extensions)}"; } if ($this->builder->hasCpp()) { - $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; + $libs .= SPCTarget::getTargetOS() === 'Darwin' ? ' -lc++' : ' -lstdc++'; } if ($this->libs_only_deps) { + $libs = '-L' . BUILD_LIB_PATH . ' ' . $libs; return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), @@ -105,6 +106,7 @@ class SPCConfigUtil if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) { $libs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $libs); } + $libs = '-L' . BUILD_LIB_PATH . ' ' . $libs; return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), @@ -138,8 +140,7 @@ class SPCConfigUtil } } $pc_cflags = implode(' ', $pc); - if ($pc_cflags !== '') { - $pc_cflags = PkgConfigUtil::getCflags($pc_cflags); + if ($pc_cflags !== '' && ($pc_cflags = PkgConfigUtil::getCflags($pc_cflags)) !== '') { $includes[] = $pc_cflags; } } @@ -165,7 +166,7 @@ class SPCConfigUtil if (!file_exists(BUILD_LIB_PATH . "/{$lib}")) { throw new WrongUsageException("Library file '{$lib}' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "'. Please build it first."); } - $lib_names[] = $use_short_libs ? $this->getShortLibName($lib) : (BUILD_LIB_PATH . "/{$lib}"); + $lib_names[] = $this->getShortLibName($lib); } // add frameworks for macOS if (SPCTarget::getTargetOS() === 'Darwin') { @@ -180,13 +181,13 @@ class SPCConfigUtil } $pkg_configs = implode(' ', $pkg_configs); if ($pkg_configs !== '') { - $pc_libs = array_reverse(PkgConfigUtil::getLibsArray($pkg_configs, $use_short_libs)); + $pc_libs = PkgConfigUtil::getLibsArray($pkg_configs); $lib_names = [...$lib_names, ...$pc_libs]; } } // post-process - $lib_names = array_reverse(array_unique($lib_names)); + $lib_names = array_reverse(array_unique(array_reverse($lib_names))); $frameworks = array_unique($frameworks); // process frameworks to short_name From f8970a21beb80ea4bbdfec7e9f5bc02c6e15f6d9 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 23 Jul 2025 09:53:31 +0700 Subject: [PATCH 24/35] fix cs --- src/SPC/util/PkgConfigUtil.php | 2 +- src/SPC/util/SPCConfigUtil.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SPC/util/PkgConfigUtil.php b/src/SPC/util/PkgConfigUtil.php index db2f4431..87075b49 100644 --- a/src/SPC/util/PkgConfigUtil.php +++ b/src/SPC/util/PkgConfigUtil.php @@ -32,7 +32,7 @@ class PkgConfigUtil * @return array Unique libs array, e.g. [-lz, -lxml, ...] * @throws RuntimeException */ - public static function getLibsArray(string $pkg_config_str, bool $force_short_name = true): array + public static function getLibsArray(string $pkg_config_str): array { // Use this instead of shell() to avoid unnecessary outputs $result = self::execWithResult("pkg-config --static --libs-only-l {$pkg_config_str}"); diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 4ce5253c..a3f2af6e 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -6,7 +6,6 @@ namespace SPC\util; use SPC\builder\BuilderBase; use SPC\builder\BuilderProvider; -use SPC\builder\macos\MacOSBuilder; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; From f75c58b7d243b66e6cd0bc098fd212ec63d042a1 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 23 Jul 2025 10:21:36 +0700 Subject: [PATCH 25/35] revert to double array_reverse, because static libs with dependencies are backwards --- src/SPC/util/SPCConfigUtil.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index a3f2af6e..ae66a183 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -93,7 +93,7 @@ class SPCConfigUtil return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), - 'libs' => trim(getenv('LIBS') . ' ' . $libs), + 'libs' => trim(getenv('LIBS') . ' ' . $libs), ]; } @@ -101,11 +101,11 @@ class SPCConfigUtil if (!$this->no_php) { $libs = "-lphp -lc {$libs}"; } + $libs = '-L' . BUILD_LIB_PATH . ' ' . $libs; // mimalloc must come first if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) { $libs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $libs); } - $libs = '-L' . BUILD_LIB_PATH . ' ' . $libs; return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), @@ -180,13 +180,13 @@ class SPCConfigUtil } $pkg_configs = implode(' ', $pkg_configs); if ($pkg_configs !== '') { - $pc_libs = PkgConfigUtil::getLibsArray($pkg_configs); + $pc_libs = array_reverse(PkgConfigUtil::getLibsArray($pkg_configs)); $lib_names = [...$lib_names, ...$pc_libs]; } } // post-process - $lib_names = array_reverse(array_unique(array_reverse($lib_names))); + $lib_names = array_unique(array_reverse(array_filter($lib_names, fn ($x) => $x !== ''))); $frameworks = array_unique($frameworks); // process frameworks to short_name From 51ec8199e4c37e26e184f25689f479753dfed402 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 23 Jul 2025 10:46:30 +0700 Subject: [PATCH 26/35] bring back static lib logic --- src/SPC/util/SPCConfigUtil.php | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index ae66a183..5dd86490 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -88,24 +88,25 @@ class SPCConfigUtil if ($this->builder->hasCpp()) { $libs .= SPCTarget::getTargetOS() === 'Darwin' ? ' -lc++' : ' -lstdc++'; } + if ($this->libs_only_deps) { - $libs = '-L' . BUILD_LIB_PATH . ' ' . $libs; return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), - 'libs' => trim(getenv('LIBS') . ' ' . $libs), + 'libs' => trim(getenv('LIBS') . ' ' . $libs), ]; } // embed if (!$this->no_php) { - $libs = "-lphp -lc {$libs}"; + $libs = "-lphp {$libs} -lc"; } - $libs = '-L' . BUILD_LIB_PATH . ' ' . $libs; + // mimalloc must come first if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) { $libs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $libs); } + return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), @@ -202,6 +203,9 @@ class SPCConfigUtil if (in_array('imap', $libraries) && SPCTarget::getLibc() === 'glibc') { $lib_names[] = '-lcrypt'; } + if (!$use_short_libs) { + $lib_names = array_map(fn ($l) => $this->getFullLibName($l), $lib_names); + } return implode(' ', $lib_names); } @@ -214,6 +218,19 @@ class SPCConfigUtil return '-l' . substr($lib, 3, -2); } + private function getFullLibName(string $lib) + { + if (!str_starts_with($lib, '-l')) { + return $lib; + } + $libname = substr($lib, 2); + $staticLib = BUILD_LIB_PATH . '/' . "lib{$libname}.a"; + if (file_exists($staticLib)) { + return $staticLib; + } + return $lib; + } + private function getFrameworksString(array $extensions): string { $list = []; From 31e7cd31c144fdfa84f072257436213bc67d1b17 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 23 Jul 2025 10:49:23 +0700 Subject: [PATCH 27/35] make sure that mimalloc.o is *always* first, no matter if $_ENV['LIBS'] is set --- src/SPC/util/SPCConfigUtil.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 5dd86490..1a8547e6 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -102,15 +102,17 @@ class SPCConfigUtil $libs = "-lphp {$libs} -lc"; } + $allLibs = getenv('LIBS') . ' ' . $libs; + // mimalloc must come first if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) { - $libs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $libs); + $allLibs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $allLibs); } return [ 'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags), 'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags), - 'libs' => trim(getenv('LIBS') . ' ' . $libs), + 'libs' => trim($allLibs), ]; } From 952ecb2eec4b9acf928817e7329b842d3b40df6d Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 23 Jul 2025 10:50:29 +0700 Subject: [PATCH 28/35] test all affected operating systems! --- src/globals/test-extensions.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index e7fcbb51..7576bcef 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -21,11 +21,11 @@ $test_php_version = [ // test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available) $test_os = [ - // 'macos-13', // bin/spc for x86_64 + 'macos-13', // bin/spc for x86_64 // 'macos-14', // bin/spc for arm64 - // 'macos-15', // bin/spc for arm64 + 'macos-15', // bin/spc for arm64 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 - // 'ubuntu-22.04', // bin/spc-gnu-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 From 293a95da6dcad879135751de404eb670c6f42dd1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 11:51:28 +0800 Subject: [PATCH 29/35] Use absolute path for pc files --- src/SPC/builder/traits/UnixLibraryTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/builder/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index e98a6f3a..baadf226 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -75,7 +75,7 @@ trait UnixLibraryTrait logger()->debug('Patching ' . $realpath); // replace prefix $file = FileSystem::readFile($realpath); - $file = ($patch_option & PKGCONF_PATCH_PREFIX) === PKGCONF_PATCH_PREFIX ? preg_replace('/^prefix\s*=.*$/m', 'prefix=${pcfiledir}/../..', $file) : $file; + $file = ($patch_option & PKGCONF_PATCH_PREFIX) === PKGCONF_PATCH_PREFIX ? preg_replace('/^prefix\s*=.*$/m', 'prefix=' . BUILD_ROOT_PATH, $file) : $file; $file = ($patch_option & PKGCONF_PATCH_EXEC_PREFIX) === PKGCONF_PATCH_EXEC_PREFIX ? preg_replace('/^exec_prefix\s*=.*$/m', 'exec_prefix=${prefix}', $file) : $file; $file = ($patch_option & PKGCONF_PATCH_LIBDIR) === PKGCONF_PATCH_LIBDIR ? preg_replace('/^libdir\s*=.*$/m', 'libdir=${prefix}/lib', $file) : $file; $file = ($patch_option & PKGCONF_PATCH_INCLUDEDIR) === PKGCONF_PATCH_INCLUDEDIR ? preg_replace('/^includedir\s*=.*$/m', 'includedir=${prefix}/include', $file) : $file; From 147fd396cfc3241db24bb00d941c5d2006d1920f Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 11:52:05 +0800 Subject: [PATCH 30/35] Fix openssl pc file --- src/SPC/builder/linux/library/openssl.php | 11 +++++------ src/SPC/builder/macos/library/openssl.php | 14 ++++++-------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index 252eb47f..9cb107d9 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -67,8 +67,7 @@ class openssl extends LinuxLibraryBase shell()->cd($this->source_dir)->initializeEnv($this) ->exec( "{$env} ./Configure no-shared {$extra} " . - '--prefix=/ ' . - '--libdir=lib ' . + '--prefix=' . BUILD_ROOT_PATH . ' ' . '--openssldir=/etc/ssl ' . "{$zlib_extra}" . 'no-legacy ' . @@ -76,17 +75,17 @@ class openssl extends LinuxLibraryBase ) ->exec('make clean') ->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") - ->exec("make install_sw DESTDIR={$destdir}"); + ->exec('make install_sw'); $this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']); // patch for openssl 3.3.0+ if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc'), 'prefix=')) { - FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc', 'prefix=${pcfiledir}/../..' . "\n" . $file); + FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file); } if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc'), 'prefix=')) { - FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc', 'prefix=${pcfiledir}/../..' . "\n" . $file); + FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file); } if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc'), 'prefix=')) { - FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=${pcfiledir}/../..' . "\n" . $file); + 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 . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")'); diff --git a/src/SPC/builder/macos/library/openssl.php b/src/SPC/builder/macos/library/openssl.php index d641fc1d..c1826b5c 100644 --- a/src/SPC/builder/macos/library/openssl.php +++ b/src/SPC/builder/macos/library/openssl.php @@ -37,8 +37,6 @@ class openssl extends MacOSLibraryBase */ protected function build(): void { - [$lib,,$destdir] = SEPARATED_PATH; - // lib:zlib $extra = ''; $ex_lib = ''; @@ -52,24 +50,24 @@ class openssl extends MacOSLibraryBase shell()->cd($this->source_dir)->initializeEnv($this) ->exec( "./Configure no-shared {$extra} " . - '--prefix=/ ' . // use prefix=/ - "--libdir={$lib} " . + '--prefix=' . BUILD_ROOT_PATH . ' ' . // use prefix=/ + '--libdir=lib ' . '--openssldir=/etc/ssl ' . "darwin64-{$arch}-cc" ) ->exec('make clean') ->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") - ->exec("make install_sw DESTDIR={$destdir}"); + ->exec('make install_sw'); $this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']); // patch for openssl 3.3.0+ if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc'), 'prefix=')) { - FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc', 'prefix=${pcfiledir}/../..' . "\n" . $file); + FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file); } if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc'), 'prefix=')) { - FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc', 'prefix=${pcfiledir}/../..' . "\n" . $file); + FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file); } if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc'), 'prefix=')) { - FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=${pcfiledir}/../..' . "\n" . $file); + 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 . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")'); From 9f7a7a5703c41f32af8608239e138ed27005d023 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 11:52:25 +0800 Subject: [PATCH 31/35] Add packing placeholder --- src/SPC/builder/LibraryBase.php | 22 +++++++++++++- src/SPC/builder/unix/library/icu.php | 1 + src/SPC/builder/unix/library/libevent.php | 1 + src/SPC/command/dev/PackLibCommand.php | 35 +++++++++++++++++++++++ src/globals/functions.php | 10 +++++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index b97b5929..441a389c 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -350,7 +350,27 @@ abstract class LibraryBase protected function install(): void { - // do something after extracting pre-built files, default do nothing. overwrite this method to do something + // replace placeholders if BUILD_ROOT_PATH/.spc-extract-placeholder.json exists + $placeholder_file = BUILD_ROOT_PATH . '/.spc-extract-placeholder.json'; + if (!file_exists($placeholder_file)) { + return; + } + $placeholder = json_decode(file_get_contents($placeholder_file), true); + if (!is_array($placeholder)) { + throw new RuntimeException('Invalid placeholder file: ' . $placeholder_file); + } + $placeholder = get_pack_placehoder(); + // replace placeholders in BUILD_ROOT_PATH + foreach ($placeholder as $item) { + $filepath = BUILD_ROOT_PATH . "/{$item}"; + FileSystem::replaceFileStr( + $filepath, + array_values($placeholder), + array_keys($placeholder), + ); + } + // remove placeholder file + unlink($placeholder_file); } /** diff --git a/src/SPC/builder/unix/library/icu.php b/src/SPC/builder/unix/library/icu.php index d1aa8dc1..6f2e8611 100644 --- a/src/SPC/builder/unix/library/icu.php +++ b/src/SPC/builder/unix/library/icu.php @@ -17,6 +17,7 @@ trait icu protected function install(): void { + parent::install(); $icu_config = BUILD_ROOT_PATH . '/bin/icu-config'; FileSystem::replaceFileStr($icu_config, '{BUILD_ROOT_PATH}', BUILD_ROOT_PATH); } diff --git a/src/SPC/builder/unix/library/libevent.php b/src/SPC/builder/unix/library/libevent.php index 55889d1d..ab4838e3 100644 --- a/src/SPC/builder/unix/library/libevent.php +++ b/src/SPC/builder/unix/library/libevent.php @@ -68,6 +68,7 @@ trait libevent protected function install(): void { + parent::install(); FileSystem::replaceFileStr( BUILD_LIB_PATH . '/cmake/libevent/LibeventTargets-static.cmake', '{BUILD_ROOT_PATH}', diff --git a/src/SPC/command/dev/PackLibCommand.php b/src/SPC/command/dev/PackLibCommand.php index 6440588c..7b6aec07 100644 --- a/src/SPC/command/dev/PackLibCommand.php +++ b/src/SPC/command/dev/PackLibCommand.php @@ -51,6 +51,10 @@ class PackLibCommand extends BuildCommand } } + $origin_files = []; + // get pack placehoder defines + $placehoder = get_pack_placehoder(); + foreach ($builder->getLibs() as $lib) { if ($lib->getName() !== $lib_name) { // other dependencies: install or build, both ok @@ -73,6 +77,27 @@ class PackLibCommand extends BuildCommand // After build: load buildroot/ directory, and calculate increase files $after_buildroot = FileSystem::scanDirFiles(BUILD_ROOT_PATH, relative: true); $increase_files = array_diff($after_buildroot, $before_buildroot); + + // patch pkg-config and la files with absolute path + foreach ($increase_files as $file) { + if (str_ends_with($file, '.pc') || str_ends_with($file, '.la')) { + $content = FileSystem::readFile(BUILD_ROOT_PATH . '/' . $file); + $origin_files[$file] = $content; + // replace relative paths with absolute paths + $content = str_replace( + array_keys($placehoder), + array_values($placehoder), + $content + ); + FileSystem::writeFile(BUILD_ROOT_PATH . '/' . $file, $content); + } + } + + // add .spc-extract-placeholder.json in BUILD_ROOT_PATH + $placeholder_file = BUILD_ROOT_PATH . '/.spc-extract-placeholder.json'; + file_put_contents($placeholder_file, json_encode(array_keys($origin_files), JSON_PRETTY_PRINT)); + $increase_files[] = '.spc-extract-placeholder.json'; + // every file mapped with BUILD_ROOT_PATH // get BUILD_ROOT_PATH last dir part $buildroot_part = basename(BUILD_ROOT_PATH); @@ -94,6 +119,16 @@ class PackLibCommand extends BuildCommand $filename = WORKING_DIR . '/dist/' . $filename; f_passthru("tar {$tar_option} {$filename} -T " . WORKING_DIR . '/packlib_files.txt'); logger()->info('Pack library ' . $lib->getName() . ' to ' . $filename . ' complete.'); + + // remove temp files + unlink($placeholder_file); + } + } + + foreach ($origin_files as $file => $content) { + // restore original files + if (file_exists(BUILD_ROOT_PATH . '/' . $file)) { + FileSystem::writeFile(BUILD_ROOT_PATH . '/' . $file, $content); } } diff --git a/src/globals/functions.php b/src/globals/functions.php index 998b2d1c..28f059ac 100644 --- a/src/globals/functions.php +++ b/src/globals/functions.php @@ -232,3 +232,13 @@ function ac_with_args(string $arg_name, bool $use_value = false): array { return $use_value ? ["--with-{$arg_name}=yes", "--with-{$arg_name}=no"] : ["--with-{$arg_name}", "--without-{$arg_name}"]; } + +function get_pack_placehoder(): array +{ + return [ + BUILD_LIB_PATH => '@build_lib_path@', + BUILD_BIN_PATH => '@build_bin_path@', + BUILD_INCLUDE_PATH => '@build_include_path@', + BUILD_ROOT_PATH => '@build_root_path@', + ]; +} From e02ce4c1510224c351aeeda90a392090f9078f14 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 12:15:18 +0800 Subject: [PATCH 32/35] Fix gnu docker openssl build --- src/SPC/builder/linux/library/openssl.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index 9cb107d9..08cffe62 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -68,6 +68,7 @@ class openssl extends LinuxLibraryBase ->exec( "{$env} ./Configure no-shared {$extra} " . '--prefix=' . BUILD_ROOT_PATH . ' ' . + '--libdir=' . BUILD_LIB_PATH . ' ' . '--openssldir=/etc/ssl ' . "{$zlib_extra}" . 'no-legacy ' . From 42e2f6a89de18a65e66c3720fea03ba31e6a077e Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 12:49:13 +0800 Subject: [PATCH 33/35] Update composer deps, trigger extension test --- composer.lock | 365 ++++++++++++++++++++++++++------------------------ 1 file changed, 188 insertions(+), 177 deletions(-) diff --git a/composer.lock b/composer.lock index 3004785e..a05a1e0d 100644 --- a/composer.lock +++ b/composer.lock @@ -8,7 +8,7 @@ "packages": [ { "name": "illuminate/collections", - "version": "v11.44.4", + "version": "v11.45.1", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -64,7 +64,7 @@ }, { "name": "illuminate/conditionable", - "version": "v11.44.4", + "version": "v11.45.1", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -110,7 +110,7 @@ }, { "name": "illuminate/contracts", - "version": "v11.44.4", + "version": "v11.45.1", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -158,7 +158,7 @@ }, { "name": "illuminate/macroable", - "version": "v11.44.4", + "version": "v11.45.1", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -416,16 +416,16 @@ }, { "name": "symfony/console", - "version": "v6.4.20", + "version": "v6.4.23", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2e4af9c952617cc3f9559ff706aee420a8464c36" + "reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2e4af9c952617cc3f9559ff706aee420a8464c36", - "reference": "2e4af9c952617cc3f9559ff706aee420a8464c36", + "url": "https://api.github.com/repos/symfony/console/zipball/9056771b8eca08d026cd3280deeec3cfd99c4d93", + "reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93", "shasum": "" }, "require": { @@ -490,7 +490,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.20" + "source": "https://github.com/symfony/console/tree/v6.4.23" }, "funding": [ { @@ -506,20 +506,20 @@ "type": "tidelift" } ], - "time": "2025-03-03T17:16:38+00:00" + "time": "2025-06-27T19:37:22+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { @@ -532,7 +532,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -557,7 +557,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -573,11 +573,11 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -636,7 +636,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" }, "funding": [ { @@ -656,7 +656,7 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", @@ -714,7 +714,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" }, "funding": [ { @@ -734,7 +734,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -795,7 +795,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" }, "funding": [ { @@ -815,19 +815,20 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { + "ext-iconv": "*", "php": ">=7.2" }, "provide": { @@ -875,7 +876,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" }, "funding": [ { @@ -891,20 +892,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/process", - "version": "v7.2.5", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "87b7c93e57df9d8e39a093d32587702380ff045d" + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d", - "reference": "87b7c93e57df9d8e39a093d32587702380ff045d", + "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", "shasum": "" }, "require": { @@ -936,7 +937,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.2.5" + "source": "https://github.com/symfony/process/tree/v7.3.0" }, "funding": [ { @@ -952,20 +953,20 @@ "type": "tidelift" } ], - "time": "2025-03-13T12:21:46+00:00" + "time": "2025-04-17T09:11:12+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", "shasum": "" }, "require": { @@ -983,7 +984,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -1019,7 +1020,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" }, "funding": [ { @@ -1035,20 +1036,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2025-04-25T09:37:31+00:00" }, { "name": "symfony/string", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125", + "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125", "shasum": "" }, "require": { @@ -1106,7 +1107,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "source": "https://github.com/symfony/string/tree/v7.3.0" }, "funding": [ { @@ -1122,20 +1123,20 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:26+00:00" + "time": "2025-04-20T20:19:01+00:00" }, { "name": "symfony/yaml", - "version": "v7.2.5", + "version": "v7.3.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912" + "reference": "0c3555045a46ab3cd4cc5a69d161225195230edb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912", - "reference": "4c4b6f4cfcd7e52053f0c8bfad0f7f30fb924912", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0c3555045a46ab3cd4cc5a69d161225195230edb", + "reference": "0c3555045a46ab3cd4cc5a69d161225195230edb", "shasum": "" }, "require": { @@ -1178,7 +1179,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.2.5" + "source": "https://github.com/symfony/yaml/tree/v7.3.1" }, "funding": [ { @@ -1194,7 +1195,7 @@ "type": "tidelift" } ], - "time": "2025-03-03T07:12:39+00:00" + "time": "2025-06-03T06:57:57+00:00" }, { "name": "zhamao/logger", @@ -2077,16 +2078,16 @@ }, { "name": "captainhook/captainhook-phar", - "version": "5.25.2", + "version": "5.25.6", "source": { "type": "git", "url": "https://github.com/captainhook-git/captainhook-phar.git", - "reference": "ab47b0561ec7997bf9b88181d090857874f2cf8c" + "reference": "a5dbcd8d20b3dcdb1cbd6948d0d3a058453b3d6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/captainhook-git/captainhook-phar/zipball/ab47b0561ec7997bf9b88181d090857874f2cf8c", - "reference": "ab47b0561ec7997bf9b88181d090857874f2cf8c", + "url": "https://api.github.com/repos/captainhook-git/captainhook-phar/zipball/a5dbcd8d20b3dcdb1cbd6948d0d3a058453b3d6a", + "reference": "a5dbcd8d20b3dcdb1cbd6948d0d3a058453b3d6a", "shasum": "" }, "require": { @@ -2119,7 +2120,7 @@ } ], "description": "PHP git hook manager", - "homepage": "https://github.com/captainhookphp/captainhook", + "homepage": "https://github.com/captainhook-git/captainhook", "keywords": [ "commit-msg", "git", @@ -2130,8 +2131,8 @@ "prepare-commit-msg" ], "support": { - "issues": "https://github.com/captainhookphp/captainhook/issues", - "source": "https://github.com/captainhook-git/captainhook-phar/tree/5.25.2" + "issues": "https://github.com/captainhook-git/captainhook/issues", + "source": "https://github.com/captainhook-git/captainhook-phar/tree/5.25.6" }, "funding": [ { @@ -2139,7 +2140,7 @@ "type": "github" } ], - "time": "2025-03-30T17:19:44+00:00" + "time": "2025-04-08T07:07:48+00:00" }, { "name": "captainhook/hook-installer", @@ -2832,16 +2833,16 @@ }, { "name": "filp/whoops", - "version": "2.18.0", + "version": "2.18.3", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e" + "reference": "59a123a3d459c5a23055802237cb317f609867e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", - "reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", + "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5", + "reference": "59a123a3d459c5a23055802237cb317f609867e5", "shasum": "" }, "require": { @@ -2891,7 +2892,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.18.0" + "source": "https://github.com/filp/whoops/tree/2.18.3" }, "funding": [ { @@ -2899,62 +2900,63 @@ "type": "github" } ], - "time": "2025-03-15T12:00:00+00:00" + "time": "2025-06-16T00:02:10+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.75.0", + "version": "v3.84.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c" + "reference": "38dad0767bf2a9b516b976852200ae722fe984ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c", - "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/38dad0767bf2a9b516b976852200ae722fe984ca", + "reference": "38dad0767bf2a9b516b976852200ae722fe984ca", "shasum": "" }, "require": { "clue/ndjson-react": "^1.0", "composer/semver": "^3.4", - "composer/xdebug-handler": "^3.0.3", + "composer/xdebug-handler": "^3.0.5", "ext-filter": "*", "ext-hash": "*", "ext-json": "*", "ext-tokenizer": "*", "fidry/cpu-core-counter": "^1.2", "php": "^7.4 || ^8.0", - "react/child-process": "^0.6.5", + "react/child-process": "^0.6.6", "react/event-loop": "^1.0", - "react/promise": "^2.0 || ^3.0", + "react/promise": "^2.11 || ^3.0", "react/socket": "^1.0", "react/stream": "^1.0", - "sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0", - "symfony/console": "^5.4 || ^6.4 || ^7.0", - "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", - "symfony/finder": "^5.4 || ^6.4 || ^7.0", - "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", - "symfony/polyfill-mbstring": "^1.31", - "symfony/polyfill-php80": "^1.31", - "symfony/polyfill-php81": "^1.31", - "symfony/process": "^5.4 || ^6.4 || ^7.2", - "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", + "symfony/console": "^5.4.45 || ^6.4.13 || ^7.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0", + "symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0", + "symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0", + "symfony/polyfill-mbstring": "^1.32", + "symfony/polyfill-php80": "^1.32", + "symfony/polyfill-php81": "^1.32", + "symfony/process": "^5.4.47 || ^6.4.20 || ^7.2", + "symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0" }, "require-dev": { "facile-it/paraunit": "^1.3.1 || ^2.6", "infection/infection": "^0.29.14", - "justinrainbow/json-schema": "^5.3 || ^6.2", - "keradus/cli-executor": "^2.1", + "justinrainbow/json-schema": "^5.3 || ^6.4", + "keradus/cli-executor": "^2.2", "mikey179/vfsstream": "^1.6.12", - "php-coveralls/php-coveralls": "^2.7", + "php-coveralls/php-coveralls": "^2.8", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", - "phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.12", - "symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.3", - "symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.3" + "phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25", + "symfony/polyfill-php84": "^1.32", + "symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1", + "symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -2995,7 +2997,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.84.0" }, "funding": [ { @@ -3003,7 +3005,7 @@ "type": "github" } ], - "time": "2025-03-31T18:40:42+00:00" + "time": "2025-07-15T18:21:57+00:00" }, { "name": "humbug/box", @@ -3546,16 +3548,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.13.0", + "version": "1.13.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414" + "reference": "faed855a7b5f4d4637717c2b3863e277116beb36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36", + "reference": "faed855a7b5f4d4637717c2b3863e277116beb36", "shasum": "" }, "require": { @@ -3594,7 +3596,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.3" }, "funding": [ { @@ -3602,7 +3604,7 @@ "type": "tidelift" } ], - "time": "2025-02-12T12:17:51+00:00" + "time": "2025-07-05T12:25:42+00:00" }, { "name": "nikic/iter", @@ -3658,16 +3660,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.4.0", + "version": "v5.5.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9", + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9", "shasum": "" }, "require": { @@ -3710,9 +3712,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0" }, - "time": "2024-12-30T11:07:19+00:00" + "time": "2025-05-31T08:24:38+00:00" }, { "name": "nunomaduro/collision", @@ -4404,16 +4406,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.1.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68" + "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9b30d6fd026b2c132b3985ce6b23bec09ab3aa68", - "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b9e61a61e39e02dd90944e9115241c7f7e76bfd8", + "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8", "shasum": "" }, "require": { @@ -4445,22 +4447,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.1.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.2.0" }, - "time": "2025-02-19T13:28:12+00:00" + "time": "2025-07-13T07:04:09+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.24", + "version": "1.12.28", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "338b92068f58d9f8035b76aed6cf2b9e5624c025" + "reference": "fcf8b71aeab4e1a1131d1783cef97b23a51b87a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/338b92068f58d9f8035b76aed6cf2b9e5624c025", - "reference": "338b92068f58d9f8035b76aed6cf2b9e5624c025", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/fcf8b71aeab4e1a1131d1783cef97b23a51b87a9", + "reference": "fcf8b71aeab4e1a1131d1783cef97b23a51b87a9", "shasum": "" }, "require": { @@ -4505,7 +4507,7 @@ "type": "github" } ], - "time": "2025-04-16T13:01:53+00:00" + "time": "2025-07-17T17:15:39+00:00" }, { "name": "phpunit/php-code-coverage", @@ -4830,16 +4832,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.45", + "version": "10.5.48", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" + "reference": "6e0a2bc39f6fae7617989d690d76c48e6d2eb541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e0a2bc39f6fae7617989d690d76c48e6d2eb541", + "reference": "6e0a2bc39f6fae7617989d690d76c48e6d2eb541", "shasum": "" }, "require": { @@ -4849,7 +4851,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.1", + "myclabs/deep-copy": "^1.13.3", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.1", @@ -4911,7 +4913,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.48" }, "funding": [ { @@ -4922,12 +4924,20 @@ "url": "https://github.com/sebastianbergmann", "type": "github" }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2025-02-06T16:08:12+00:00" + "time": "2025-07-11T04:07:17+00:00" }, { "name": "psr/event-dispatcher", @@ -6715,16 +6725,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", "shasum": "" }, "require": { @@ -6775,7 +6785,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0" }, "funding": [ { @@ -6791,20 +6801,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2025-04-22T09:11:45+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", "shasum": "" }, "require": { @@ -6818,7 +6828,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -6851,7 +6861,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" }, "funding": [ { @@ -6867,11 +6877,11 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/filesystem", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -6917,7 +6927,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + "source": "https://github.com/symfony/filesystem/tree/v7.3.0" }, "funding": [ { @@ -6937,16 +6947,16 @@ }, { "name": "symfony/finder", - "version": "v7.2.2", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb" + "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb", + "url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d", + "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d", "shasum": "" }, "require": { @@ -6981,7 +6991,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.2.2" + "source": "https://github.com/symfony/finder/tree/v7.3.0" }, "funding": [ { @@ -6997,20 +7007,20 @@ "type": "tidelift" } ], - "time": "2024-12-30T19:00:17+00:00" + "time": "2024-12-30T19:00:26+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" + "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", - "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca", + "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca", "shasum": "" }, "require": { @@ -7048,7 +7058,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.3.0" }, "funding": [ { @@ -7064,20 +7074,20 @@ "type": "tidelift" } ], - "time": "2024-11-20T11:17:29+00:00" + "time": "2025-04-04T13:12:05+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956" + "reference": "5f3b930437ae03ae5dff61269024d8ea1b3774aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/48becf00c920479ca2e910c22a5a39e5d47ca956", - "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/5f3b930437ae03ae5dff61269024d8ea1b3774aa", + "reference": "5f3b930437ae03ae5dff61269024d8ea1b3774aa", "shasum": "" }, "require": { @@ -7128,7 +7138,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.32.0" }, "funding": [ { @@ -7144,20 +7154,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-09-17T14:58:18+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd" + "reference": "000df7860439609837bbe28670b0be15783b7fbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/e5493eb51311ab0b1cc2243416613f06ed8f18bd", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/000df7860439609837bbe28670b0be15783b7fbf", + "reference": "000df7860439609837bbe28670b0be15783b7fbf", "shasum": "" }, "require": { @@ -7204,7 +7214,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.32.0" }, "funding": [ { @@ -7220,11 +7230,11 @@ "type": "tidelift" } ], - "time": "2024-09-09T12:04:04+00:00" + "time": "2025-02-20T12:04:08+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.2.4", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -7266,7 +7276,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.2.4" + "source": "https://github.com/symfony/stopwatch/tree/v7.3.0" }, "funding": [ { @@ -7286,20 +7296,21 @@ }, { "name": "symfony/var-dumper", - "version": "v7.2.3", + "version": "v7.3.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "82b478c69745d8878eb60f9a049a4d584996f73a" + "reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/82b478c69745d8878eb60f9a049a4d584996f73a", - "reference": "82b478c69745d8878eb60f9a049a4d584996f73a", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6e209fbe5f5a7b6043baba46fe5735a4b85d0d42", + "reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -7349,7 +7360,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.2.3" + "source": "https://github.com/symfony/var-dumper/tree/v7.3.1" }, "funding": [ { @@ -7365,20 +7376,20 @@ "type": "tidelift" } ], - "time": "2025-01-17T11:39:41+00:00" + "time": "2025-06-27T19:55:54+00:00" }, { "name": "thecodingmachine/safe", - "version": "v3.1.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/thecodingmachine/safe.git", - "reference": "e14ac96126e6c19ea9d1f4029abb51487f4cf2cf" + "reference": "2cdd579eeaa2e78e51c7509b50cc9fb89a956236" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/e14ac96126e6c19ea9d1f4029abb51487f4cf2cf", - "reference": "e14ac96126e6c19ea9d1f4029abb51487f4cf2cf", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/2cdd579eeaa2e78e51c7509b50cc9fb89a956236", + "reference": "2cdd579eeaa2e78e51c7509b50cc9fb89a956236", "shasum": "" }, "require": { @@ -7488,7 +7499,7 @@ "description": "PHP core functions that throw exceptions instead of returning FALSE on error", "support": { "issues": "https://github.com/thecodingmachine/safe/issues", - "source": "https://github.com/thecodingmachine/safe/tree/v3.1.0" + "source": "https://github.com/thecodingmachine/safe/tree/v3.3.0" }, "funding": [ { @@ -7504,7 +7515,7 @@ "type": "github" } ], - "time": "2025-04-12T06:41:26+00:00" + "time": "2025-05-14T06:15:44+00:00" }, { "name": "theseer/tokenizer", From 4c56c9632698c7dd8f9bf25ed9cf237249080733 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 23 Jul 2025 13:16:23 +0700 Subject: [PATCH 34/35] lib-suggests: ldap was missing for curl --- config/lib.json | 3 ++- src/SPC/util/SPCConfigUtil.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/lib.json b/config/lib.json index 4bb73100..c712e088 100644 --- a/config/lib.json +++ b/config/lib.json @@ -89,7 +89,8 @@ "nghttp3", "ngtcp2", "zstd", - "libcares" + "libcares", + "ldap" ], "lib-suggests-windows": [ "brotli", diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 1a8547e6..7a21a311 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -183,13 +183,14 @@ class SPCConfigUtil } $pkg_configs = implode(' ', $pkg_configs); if ($pkg_configs !== '') { + // static libs with dependencies come in reverse order, so reverse this too $pc_libs = array_reverse(PkgConfigUtil::getLibsArray($pkg_configs)); $lib_names = [...$lib_names, ...$pc_libs]; } } // post-process - $lib_names = array_unique(array_reverse(array_filter($lib_names, fn ($x) => $x !== ''))); + $lib_names = array_reverse(array_unique(array_filter($lib_names, fn ($x) => $x !== ''))); $frameworks = array_unique($frameworks); // process frameworks to short_name From 3d19299d308f4c18d93be0509df2350ee987bcc3 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 23 Jul 2025 14:35:34 +0800 Subject: [PATCH 35/35] Patch both --- src/SPC/builder/unix/library/libxslt.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index 582d22ec..98ceba8d 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -43,7 +43,7 @@ trait libxslt } $ac->configure()->make(); - $this->patchPkgconfPrefix(['libxslt.pc']); + $this->patchPkgconfPrefix(['libexslt.pc', 'libxslt.pc']); $this->patchLaDependencyPrefix(); shell()->cd(BUILD_LIB_PATH) ->exec("ar -t libxslt.a | grep '\\.a$' | xargs -n1 ar d libxslt.a")