From 5bc4504e37b08286d9efd08b56eb3f570f6034cf Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Tue, 1 Jul 2025 17:53:35 +0700 Subject: [PATCH 1/5] fix g++ not found error --- src/SPC/toolchain/ClangNativeToolchain.php | 19 ++++++++++++------- src/SPC/toolchain/GccNativeToolchain.php | 19 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/SPC/toolchain/ClangNativeToolchain.php b/src/SPC/toolchain/ClangNativeToolchain.php index c5186521..061bb517 100644 --- a/src/SPC/toolchain/ClangNativeToolchain.php +++ b/src/SPC/toolchain/ClangNativeToolchain.php @@ -22,12 +22,17 @@ class ClangNativeToolchain implements ToolchainInterface public function afterInit(): void { - // check clang exists - match (PHP_OS_FAMILY) { - 'Linux' => LinuxSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or manually set CC/CXX to a valid path.'), - 'Darwin' => MacOSSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or set CC/CXX to a valid path.'), - 'BSD' => FreeBSDSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or set CC/CXX to a valid path.'), - default => throw new WrongUsageException('Clang is not supported on ' . PHP_OS_FAMILY . '.'), - }; + foreach (['CC', 'CXX', 'AR', 'LD'] as $env) { + $command = getenv($env); + if (is_file($command)) { + continue; + } + match (PHP_OS_FAMILY) { + 'Linux' => LinuxSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."), + 'Darwin' => MacOSSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."), + 'BSD' => FreeBSDSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."), + default => throw new \RuntimeException(__CLASS__ . ' is not supported on ' . PHP_OS_FAMILY . '.'), + }; + } } } diff --git a/src/SPC/toolchain/GccNativeToolchain.php b/src/SPC/toolchain/GccNativeToolchain.php index bd8cc868..21d103ab 100644 --- a/src/SPC/toolchain/GccNativeToolchain.php +++ b/src/SPC/toolchain/GccNativeToolchain.php @@ -22,12 +22,17 @@ class GccNativeToolchain implements ToolchainInterface public function afterInit(): void { - // check gcc exists - match (PHP_OS_FAMILY) { - 'Linux' => LinuxSystemUtil::findCommand('g++') ?? throw new WrongUsageException('g++ not found, please install it or set CC/CXX to a valid path.'), - 'Darwin' => MacOSSystemUtil::findCommand('g++') ?? throw new WrongUsageException('g++ not found, please install it or set CC/CXX to a valid path.'), - 'BSD' => FreeBSDSystemUtil::findCommand('g++') ?? throw new WrongUsageException('g++ not found, please install it or set CC/CXX to a valid path.'), - default => throw new \RuntimeException('GCC is not supported on ' . PHP_OS_FAMILY . '.'), - }; + foreach (['CC', 'CXX', 'AR', 'LD'] as $env) { + $command = getenv($env); + if (is_file($command)) { + continue; + } + match (PHP_OS_FAMILY) { + 'Linux' => LinuxSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."), + 'Darwin' => MacOSSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."), + 'BSD' => FreeBSDSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."), + default => throw new \RuntimeException(__CLASS__ . ' is not supported on ' . PHP_OS_FAMILY . '.'), + }; + } } } From e5ea32e9c03bd3b764a889de71ee09681ed5e8d4 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Tue, 1 Jul 2025 17:57:36 +0700 Subject: [PATCH 2/5] fix in case it's not set --- src/SPC/toolchain/ClangNativeToolchain.php | 2 +- src/SPC/toolchain/GccNativeToolchain.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SPC/toolchain/ClangNativeToolchain.php b/src/SPC/toolchain/ClangNativeToolchain.php index 061bb517..fb0bea46 100644 --- a/src/SPC/toolchain/ClangNativeToolchain.php +++ b/src/SPC/toolchain/ClangNativeToolchain.php @@ -24,7 +24,7 @@ class ClangNativeToolchain implements ToolchainInterface { foreach (['CC', 'CXX', 'AR', 'LD'] as $env) { $command = getenv($env); - if (is_file($command)) { + if (!$command || is_file($command)) { continue; } match (PHP_OS_FAMILY) { diff --git a/src/SPC/toolchain/GccNativeToolchain.php b/src/SPC/toolchain/GccNativeToolchain.php index 21d103ab..1e97b50e 100644 --- a/src/SPC/toolchain/GccNativeToolchain.php +++ b/src/SPC/toolchain/GccNativeToolchain.php @@ -24,7 +24,7 @@ class GccNativeToolchain implements ToolchainInterface { foreach (['CC', 'CXX', 'AR', 'LD'] as $env) { $command = getenv($env); - if (is_file($command)) { + if (!$command || is_file($command)) { continue; } match (PHP_OS_FAMILY) { From dd72b32559600cc2aad2c3f311954a117a4b0944 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 10 Jul 2025 12:59:27 +0800 Subject: [PATCH 3/5] Merge --- src/SPC/builder/LibraryBase.php | 9 +++++++++ src/SPC/builder/extension/imap.php | 11 +++++++++++ src/SPC/builder/linux/library/imap.php | 16 +++++++++++++--- src/SPC/builder/unix/UnixBuilderBase.php | 5 +++++ src/SPC/store/SourceManager.php | 11 +++++++++-- src/SPC/util/SPCConfigUtil.php | 3 +++ 6 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index fc6adefc..b97b5929 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -332,6 +332,15 @@ abstract class LibraryBase return false; } + /** + * Patch php-config after embed was built + * Example: imap requires -lcrypt + */ + public function patchPhpConfig(): bool + { + return false; + } + /** * Build this library. * diff --git a/src/SPC/builder/extension/imap.php b/src/SPC/builder/extension/imap.php index 9cc9a87f..f36ffb1e 100644 --- a/src/SPC/builder/extension/imap.php +++ b/src/SPC/builder/extension/imap.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace SPC\builder\extension; use SPC\builder\Extension; +use SPC\builder\linux\SystemUtil; use SPC\exception\WrongUsageException; use SPC\store\FileSystem; use SPC\util\CustomExt; @@ -41,4 +42,14 @@ class imap extends Extension } return $arg; } + + public function patchBeforeMake(): bool + { + if (PHP_OS_FAMILY !== 'Linux' || SystemUtil::isMuslDist()) { + return false; + } + $extra_libs = trim(getenv('SPC_EXTRA_LIBS') . ' -lcrypt'); + f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); + return true; + } } diff --git a/src/SPC/builder/linux/library/imap.php b/src/SPC/builder/linux/library/imap.php index 781529c6..8203928d 100644 --- a/src/SPC/builder/linux/library/imap.php +++ b/src/SPC/builder/linux/library/imap.php @@ -7,6 +7,7 @@ namespace SPC\builder\linux\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\SPCTarget; class imap extends LinuxLibraryBase { @@ -34,6 +35,15 @@ class imap extends LinuxLibraryBase return true; } + public function patchPhpConfig(): bool + { + if (SPCTarget::getLibc() === 'glibc') { + FileSystem::replaceFileRegex(BUILD_BIN_PATH . '/php-config', '/^libs="(.*)"$/m', 'libs="$1 -lcrypt"'); + return true; + } + return false; + } + /** * @throws RuntimeException */ @@ -44,6 +54,8 @@ class imap extends LinuxLibraryBase } else { $ssl_options = 'SSLTYPE=none'; } + $libcVer = SPCTarget::getLibcVersion(); + $extraLibs = $libcVer && version_compare($libcVer, '2.17', '<=') ? 'EXTRALDFLAGS="-ldl -lrt -lpthread"' : ''; shell()->cd($this->source_dir) ->exec('make clean') ->exec('touch ip6') @@ -51,9 +63,7 @@ class imap extends LinuxLibraryBase ->exec('chmod +x tools/ua') ->exec('chmod +x src/osdep/unix/drivers') ->exec('chmod +x src/osdep/unix/mkauths') - ->exec( - "yes | make slx {$ssl_options} EXTRACFLAGS='-fPIC -fpermissive'" - ); + ->exec("yes | make slx {$ssl_options} EXTRACFLAGS='-fPIC -fpermissive' {$extraLibs}"); try { shell() ->exec("cp -rf {$this->source_dir}/c-client/c-client.a " . BUILD_LIB_PATH . '/libc-client.a') diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index 6f0d5045..f0e4e169 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -294,6 +294,11 @@ abstract class UnixBuilderBase extends BuilderBase $php_config_str = preg_replace('/(libs=")(.*?)\s*(-lstdc\+\+)\s*(.*?)"/', '$1$2 $4 $3"', $php_config_str); FileSystem::writeFile(BUILD_BIN_PATH . '/php-config', $php_config_str); } + foreach ($this->getLibs() as $lib) { + if ($lib->patchPhpConfig()) { + logger()->debug("Library {$lib->getName()} patched php-config"); + } + } } /** diff --git a/src/SPC/store/SourceManager.php b/src/SPC/store/SourceManager.php index 02d07263..251e2fa1 100644 --- a/src/SPC/store/SourceManager.php +++ b/src/SPC/store/SourceManager.php @@ -66,7 +66,7 @@ class SourceManager $check = LockFile::getExtractPath($lock_name, SOURCE_PATH . '/' . $source); // $check = $lock[$lock_name]['move_path'] === null ? (SOURCE_PATH . '/' . $source) : (SOURCE_PATH . '/' . $lock[$lock_name]['move_path']); if (!is_dir($check)) { - logger()->debug('Extracting source [' . $source . '] to ' . $check . ' ...'); + logger()->debug("Extracting source [{$source}] to {$check} ..."); $filename = LockFile::getLockFullPath($lock_content); FileSystem::extractSource($source, $lock_content['source_type'], $filename, $check); LockFile::putLockSourceHash($lock_content, $check); @@ -81,7 +81,14 @@ class SourceManager // when source already extracted, detect if the extracted source hash is the same as the lock file one if (file_exists("{$check}/.spc-hash") && FileSystem::readFile("{$check}/.spc-hash") === $hash) { - logger()->debug('Source [' . $source . '] already extracted in ' . $check . ', skip !'); + logger()->debug("Source [{$source}] already extracted in {$check}, skip !"); + continue; + } + + // ext imap was included in php < 8.4 which we should not extract, + // but since it's not simple to compare php version, for now we just skip it + if ($source === 'ext-imap') { + logger()->debug("Source [ext-imap] already extracted in {$check}, skip !"); continue; } diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index fec3c089..96c09b48 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -145,6 +145,9 @@ class SPCConfigUtil } } } + if (in_array('imap', $libraries) && SPCTarget::getLibc() === 'glibc') { + $short_name[] = '-lcrypt'; + } return implode(' ', $short_name); } From ec153fa6ff9425f21ca9a0f85377d7af8383e9b5 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 10 Jul 2025 20:10:54 +0800 Subject: [PATCH 4/5] Workaround for swoole with alpine 3.21 --- bin/spc-alpine-docker | 6 +++--- src/globals/test-extensions.php | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bin/spc-alpine-docker b/bin/spc-alpine-docker index 58c24ce7..3bedaf5f 100755 --- a/bin/spc-alpine-docker +++ b/bin/spc-alpine-docker @@ -53,9 +53,9 @@ aarch64|arm64) exit 1 ;; esac -# if ALPINE_FROM is not set, use alpine:edge +# if ALPINE_FROM is not set, use alpine:3.21 if [ -z "$ALPINE_FROM" ]; then - ALPINE_FROM=alpine:edge + ALPINE_FROM=alpine:3.21 fi if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then echo "* Using different arch needs to setup qemu-static for docker !" @@ -64,7 +64,7 @@ if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then $DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null fi else - ALPINE_FROM=alpine:edge + ALPINE_FROM=alpine:3.21 fi if [ "$SPC_USE_MIRROR" = "yes" ]; then diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 86b53b8d..e16ad76d 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -23,10 +23,10 @@ $test_php_version = [ $test_os = [ // '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-24.04', // bin/spc 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 // 'windows-latest', // .\bin\spc.ps1 @@ -44,17 +44,17 @@ $upx = false; $frankenphp = false; // prefer downloading pre-built packages to speed up the build process -$prefer_pre_built = true; +$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' => 'curl', + 'Linux', 'Darwin' => 'imap,swoole', 'Windows' => 'intl', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). $shared_extensions = match (PHP_OS_FAMILY) { - 'Linux' => 'uv', + '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' => 'common', + 'Linux', 'Darwin' => 'minimal', 'Windows' => 'none', }; From a5cd5fcb3100b1cea92a987f83905159c1ced1f5 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 10 Jul 2025 20:20:29 +0800 Subject: [PATCH 5/5] Fix test and bump docker image version --- bin/spc-alpine-docker | 2 +- src/globals/test-extensions.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/spc-alpine-docker b/bin/spc-alpine-docker index 3bedaf5f..18e981f8 100755 --- a/bin/spc-alpine-docker +++ b/bin/spc-alpine-docker @@ -3,7 +3,7 @@ set -e # This file is using docker to run commands -SPC_DOCKER_VERSION=v4 +SPC_DOCKER_VERSION=v5 # Detect docker can run if ! which docker >/dev/null; then diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index e16ad76d..ffb03701 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -33,7 +33,7 @@ $test_os = [ ]; // whether enable thread safe -$zts = true; +$zts = false; $no_strip = false;