From 5f8cd972cd0365cb55cd6adf1889ee248747df88 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 5 Jul 2025 10:48:56 +0800 Subject: [PATCH] Move extra runtime object to zig toolchain --- src/SPC/builder/Extension.php | 20 ++++---- src/SPC/builder/linux/SystemUtil.php | 71 ---------------------------- src/SPC/toolchain/ZigToolchain.php | 34 +++++++++++++ 3 files changed, 44 insertions(+), 81 deletions(-) diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index ba4ddefe..dc1b2d34 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -4,12 +4,13 @@ declare(strict_types=1); namespace SPC\builder; -use SPC\builder\linux\SystemUtil; use SPC\exception\FileSystemException; 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; class Extension @@ -216,16 +217,15 @@ class Extension */ public function patchBeforeSharedMake(): bool { - $extra = SystemUtil::getExtraRuntimeObjects(); - if (!$extra) { - return false; + if (ToolchainManager::getToolchainClass() === ZigToolchain::class && ($extra = (new ZigToolchain())->getExtraRuntimeObjects())) { + FileSystem::replaceFileRegex( + $this->source_dir . '/Makefile', + "/^(shared_objects_{$this->getName()}\\s*=.*)$/m", + "$1 {$extra}", + ); + return true; } - FileSystem::replaceFileRegex( - $this->source_dir . '/Makefile', - "/^(shared_objects_{$this->getName()}\\s*=.*)$/m", - "$1 {$extra}", - ); - return true; + return false; } /** diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index 443f3ce7..c9e54255 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -5,9 +5,6 @@ declare(strict_types=1); namespace SPC\builder\linux; use SPC\builder\traits\UnixSystemUtilTrait; -use SPC\exception\RuntimeException; -use SPC\toolchain\ToolchainManager; -use SPC\toolchain\ZigToolchain; use SPC\util\SPCTarget; class SystemUtil @@ -16,8 +13,6 @@ class SystemUtil public static ?string $libc_version = null; - private static ?string $extra_runtime_objects = null; - /** @noinspection PhpMissingBreakStatementInspection */ public static function getOSRelease(): array { @@ -80,39 +75,6 @@ class SystemUtil return $ncpu; } - /** - * @throws RuntimeException - */ - public static function getCCType(?string $cc = null): string - { - $cc ??= getenv('CC'); - return match (true) { - str_contains($cc, 'zig') => 'clang', - str_ends_with($cc, 'c++'), str_ends_with($cc, 'cc'), str_ends_with($cc, 'g++'), str_ends_with($cc, 'gcc') => 'gcc', - $cc === 'clang++', $cc === 'clang', str_starts_with($cc, 'musl-clang') => 'clang', - default => throw new RuntimeException("unknown cc type: {$cc}"), - }; - } - - /** - * @throws RuntimeException - * @noinspection PhpUnused - */ - public static function getCrossCompilePrefix(string $cc, string $arch): string - { - return match (static::getCCType($cc)) { - // guessing clang toolchains - 'clang' => match ($arch) { - 'x86_64' => 'x86_64-linux-gnu-', - 'arm64', 'aarch64' => 'aarch64-linux-gnu-', - default => throw new RuntimeException('unsupported arch: ' . $arch), - }, - // remove gcc postfix - 'gcc' => str_replace('-cc', '', str_replace('-gcc', '', $cc)) . '-', - default => throw new RuntimeException('unsupported cc'), - }; - } - public static function findStaticLib(string $name): ?array { $paths = getenv('LIBPATH'); @@ -233,37 +195,4 @@ class SystemUtil } return null; } - - public static function getExtraRuntimeObjects(): string - { - if (ToolchainManager::getToolchainClass() !== ZigToolchain::class) { - return ''; - } - - if (self::$extra_runtime_objects !== null) { - return self::$extra_runtime_objects; - } - - $paths = ['/usr/lib/gcc', '/usr/local/lib/gcc']; - $objects = ['crtbeginS.o', 'crtendS.o']; - $found = []; - - foreach ($objects as $obj) { - $located = null; - foreach ($paths as $base) { - $output = shell_exec("find {$base} -name {$obj} 2>/dev/null | grep -v '/32/' | head -n 1"); - $line = trim((string) $output); - if ($line !== '') { - $located = $line; - break; - } - } - if ($located) { - $found[] = $located; - } - } - - self::$extra_runtime_objects = implode(' ', $found); - return implode(' ', $found); - } } diff --git a/src/SPC/toolchain/ZigToolchain.php b/src/SPC/toolchain/ZigToolchain.php index 779401a0..59e97469 100644 --- a/src/SPC/toolchain/ZigToolchain.php +++ b/src/SPC/toolchain/ZigToolchain.php @@ -26,4 +26,38 @@ class ZigToolchain implements ToolchainInterface } 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; + } + + $paths = ['/usr/lib/gcc', '/usr/local/lib/gcc']; + $objects = ['crtbeginS.o', 'crtendS.o']; + $found = []; + + foreach ($objects as $obj) { + $located = null; + foreach ($paths as $base) { + $output = shell_exec("find {$base} -name {$obj} 2>/dev/null | grep -v '/32/' | head -n 1"); + $line = trim((string) $output); + if ($line !== '') { + $located = $line; + break; + } + } + if ($located) { + $found[] = $located; + } + } + + $cache = implode(' ', $found); + return $cache; + } }