From f69f8d1e4ab73bed9a26fe33055a08f7771c536d Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 22 Jul 2025 13:16:26 +0800 Subject: [PATCH] Move zig-toolchain-only things to zig toolchain class --- src/SPC/builder/Extension.php | 20 ++++--------- src/SPC/builder/linux/LinuxBuilder.php | 3 -- src/SPC/store/pkg/Zig.php | 15 ++++++---- src/SPC/toolchain/ZigToolchain.php | 41 ++++++++++++-------------- src/SPC/util/SPCConfigUtil.php | 6 +--- 5 files changed, 34 insertions(+), 51 deletions(-) diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index 6f6fe15b..6a702416 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -9,9 +9,8 @@ use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\Config; use SPC\store\FileSystem; -use SPC\toolchain\ToolchainManager; -use SPC\toolchain\ZigToolchain; use SPC\util\SPCConfigUtil; +use SPC\util\SPCTarget; class Extension { @@ -187,16 +186,11 @@ class Extension */ public function patchBeforeMake(): bool { - if ( - PHP_OS_FAMILY === 'Linux' && - $this->isBuildShared() && - ToolchainManager::getToolchainClass() === ZigToolchain::class && - ($extra = (new ZigToolchain())->getExtraRuntimeObjects()) - ) { + if (SPCTarget::getTargetOS() === 'Linux' && $this->isBuildShared() && ($objs = getenv('SPC_EXTRA_RUNTIME_OBJECTS'))) { FileSystem::replaceFileRegex( SOURCE_PATH . '/php-src/Makefile', "/^(shared_objects_{$this->getName()}\\s*=.*)$/m", - "$1 {$extra}", + "$1 {$objs}", ); return true; } @@ -230,15 +224,11 @@ class Extension */ public function patchBeforeSharedMake(): bool { - if ( - PHP_OS_FAMILY === 'Linux' && - ToolchainManager::getToolchainClass() === ZigToolchain::class && - ($extra = (new ZigToolchain())->getExtraRuntimeObjects()) - ) { + if (SPCTarget::getTargetOS() === 'Linux' && ($objs = getenv('SPC_EXTRA_RUNTIME_OBJECTS'))) { FileSystem::replaceFileRegex( $this->source_dir . '/Makefile', "/^(shared_objects_{$this->getName()}\\s*=.*)$/m", - "$1 {$extra}", + "$1 {$objs}", ); return true; } diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 9c4b6d42..8983cab7 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -10,8 +10,6 @@ use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\FileSystem; use SPC\store\SourcePatcher; -use SPC\toolchain\ToolchainManager; -use SPC\toolchain\ZigToolchain; use SPC\util\GlobalEnvManager; use SPC\util\SPCTarget; @@ -62,7 +60,6 @@ class LinuxBuilder extends UnixBuilderBase } // add libstdc++, some extensions or libraries need it $extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : ''); - $extra_libs .= (ToolchainManager::getToolchainClass() === ZigToolchain::class ? ' -lunwind' : ''); f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); $cflags = $this->arch_c_flags; f_putenv('CFLAGS=' . $cflags); diff --git a/src/SPC/store/pkg/Zig.php b/src/SPC/store/pkg/Zig.php index f819da7a..6f823405 100644 --- a/src/SPC/store/pkg/Zig.php +++ b/src/SPC/store/pkg/Zig.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace SPC\store\pkg; +use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; use SPC\store\CurlHook; use SPC\store\Downloader; use SPC\store\FileSystem; @@ -50,14 +52,14 @@ class Zig extends CustomPackage $zig_arch = match ($arch) { 'x86_64', 'aarch64' => $arch, - default => throw new \InvalidArgumentException('Unsupported architecture: ' . $arch), + default => throw new WrongUsageException('Unsupported architecture: ' . $arch), }; $zig_os = match ($os) { 'linux' => 'linux', 'macos' => 'macos', 'win' => 'windows', - default => throw new \InvalidArgumentException('Unsupported OS: ' . $os), + default => throw new WrongUsageException('Unsupported OS: ' . $os), }; $index_json = json_decode(Downloader::curlExec('https://ziglang.org/download/index.json', hooks: [[CurlHook::class, 'setupGithubToken']]), true); @@ -69,14 +71,14 @@ class Zig extends CustomPackage } if (!$latest_version) { - throw new \RuntimeException('Could not determine latest Zig version'); + throw new RuntimeException('Could not determine latest Zig version'); } logger()->info("Installing Zig version {$latest_version}"); $platform_key = "{$zig_arch}-{$zig_os}"; if (!isset($index_json[$latest_version][$platform_key])) { - throw new \RuntimeException("No download available for {$platform_key} in Zig version {$latest_version}"); + throw new RuntimeException("No download available for {$platform_key} in Zig version {$latest_version}"); } $download_info = $index_json[$latest_version][$platform_key]; @@ -119,7 +121,6 @@ class Zig extends CustomPackage { $arch = arch2gnu(php_uname('m')); $os = match (PHP_OS_FAMILY) { - 'Linux' => 'linux', 'Windows' => 'win', 'Darwin' => 'macos', 'BSD' => 'freebsd', @@ -134,11 +135,13 @@ class Zig extends CustomPackage ]; } + /** + * @throws WrongUsageException + */ private static function getPath(): string { $arch = arch2gnu(php_uname('m')); $os = match (PHP_OS_FAMILY) { - 'Linux' => 'linux', 'Windows' => 'win', 'Darwin' => 'macos', 'BSD' => 'freebsd', diff --git a/src/SPC/toolchain/ZigToolchain.php b/src/SPC/toolchain/ZigToolchain.php index 59e97469..1447956f 100644 --- a/src/SPC/toolchain/ZigToolchain.php +++ b/src/SPC/toolchain/ZigToolchain.php @@ -17,27 +17,8 @@ class ZigToolchain implements ToolchainInterface GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=zig-c++'); GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar'); GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld'); - } - - public function afterInit(): void - { - if (!is_dir(Zig::getEnvironment()['PATH'])) { - throw new WrongUsageException('You are building with zig, but zig is not installed, please install zig first. (You can use `doctor` command to install it)'); - } - GlobalEnvManager::addPathIfNotExists(Zig::getEnvironment()['PATH']); - } - - /** - * Get the extra runtime objects needed for zig toolchain. - * This method searches for `crtbeginS.o` and `crtendS.o` in common GCC library paths. - */ - public function getExtraRuntimeObjects(): string - { - static $cache = null; - if ($cache !== null) { - return $cache; - } + // Generate additional object needed for zig toolchain $paths = ['/usr/lib/gcc', '/usr/local/lib/gcc']; $objects = ['crtbeginS.o', 'crtendS.o']; $found = []; @@ -56,8 +37,24 @@ class ZigToolchain implements ToolchainInterface $found[] = $located; } } + GlobalEnvManager::putenv('SPC_EXTRA_RUNTIME_OBJECTS=' . implode(' ', $found)); - $cache = implode(' ', $found); - return $cache; + $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; + if (!str_contains($extra_libs, '-lunwind')) { + // Add unwind library if not already present + $extra_libs = trim($extra_libs . ' -lunwind'); + GlobalEnvManager::putenv("SPC_EXTRA_LIBS={$extra_libs}"); + } + } + + /** + * @throws WrongUsageException + */ + public function afterInit(): void + { + if (!is_dir(Zig::getEnvironment()['PATH'])) { + throw new WrongUsageException('You are building with zig, but zig is not installed, please install zig first. (You can use `doctor` command to install it)'); + } + GlobalEnvManager::addPathIfNotExists(Zig::getEnvironment()['PATH']); } } diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index 83b76b2c..d7ecd368 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -11,8 +11,6 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\Config; -use SPC\toolchain\ToolchainManager; -use SPC\toolchain\ZigToolchain; use Symfony\Component\Console\Input\ArgvInput; class SPCConfigUtil @@ -71,9 +69,7 @@ class SPCConfigUtil if ($this->builder->hasCpp()) { $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; } - if (ToolchainManager::getToolchainClass() === ZigToolchain::class) { - $libs .= ' -lunwind'; - } + $libs .= ' ' . (getenv('SPC_EXTRA_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);