From 8d75a85d6d36662d2a6f6f94cf3ba408be818256 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Thu, 26 Jun 2025 12:29:58 +0700 Subject: [PATCH] ziggy --- config/pkg.json | 15 +++ src/SPC/store/Downloader.php | 2 +- src/SPC/store/pkg/Zig.php | 148 ++++++++++++++++++++++++++++++ src/SPC/util/GlobalEnvManager.php | 4 + 4 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 src/SPC/store/pkg/Zig.php diff --git a/config/pkg.json b/config/pkg.json index e0762cac..080958b4 100644 --- a/config/pkg.json +++ b/config/pkg.json @@ -54,5 +54,20 @@ }, "go-xcaddy-aarch64-macos": { "type": "custom" + }, + "zig-x86_64-linux": { + "type": "custom" + }, + "zig-aarch64-linux": { + "type": "custom" + }, + "zig-x86_64-macos": { + "type": "custom" + }, + "zig-aarch64-macos": { + "type": "custom" + }, + "zig-x86_64-win": { + "type": "custom" } } diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index ba0cd124..41fcb25d 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -365,8 +365,8 @@ class Downloader $cls = new $class(); if (in_array($name, $cls->getSupportName())) { (new $class())->fetch($name, $force, $pkg); + break; } - break; } } break; diff --git a/src/SPC/store/pkg/Zig.php b/src/SPC/store/pkg/Zig.php new file mode 100644 index 00000000..38020579 --- /dev/null +++ b/src/SPC/store/pkg/Zig.php @@ -0,0 +1,148 @@ + "{$pkgroot}/{$name}/bin/zig.exe", + default => "{$pkgroot}/{$name}/bin/zig", + }; + + if (file_exists($zig_exec) && !$force) { + return; + } + + $parts = explode('-', $name); + $arch = $parts[1]; + $os = $parts[2]; + + $zig_arch = match ($arch) { + 'x86_64', 'aarch64' => $arch, + default => throw new \InvalidArgumentException('Unsupported architecture: ' . $arch), + }; + + $zig_os = match ($os) { + 'linux' => 'linux', + 'macos' => 'macos', + 'win' => 'windows', + default => throw new \InvalidArgumentException('Unsupported OS: ' . $os), + }; + + $index_json = json_decode(Downloader::curlExec('https://ziglang.org/download/index.json', hooks: [[CurlHook::class, 'setupGithubToken']]), true); + + $latest_version = null; + foreach ($index_json as $version => $data) { + $latest_version = $version; + break; + } + + if (!$latest_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}"); + } + + $download_info = $index_json[$latest_version][$platform_key]; + $url = $download_info['tarball']; + $filename = basename($url); + + $config = [ + 'type' => 'url', + 'url' => $url, + 'filename' => $filename, + ]; + + Downloader::downloadPackage($name, $config, $force); + } + + public function extract(string $name): void + { + $pkgroot = PKG_ROOT_PATH; + $zig_bin_dir = "{$pkgroot}/{$name}"; + $zig_exec = match (PHP_OS_FAMILY) { + 'Windows' => "{$zig_bin_dir}/zig.exe", + default => "{$zig_bin_dir}/zig", + }; + + if (file_exists($zig_exec)) { + if (!file_exists("{$zig_bin_dir}/zig-cc")) { + $this->createZigCcScript($zig_bin_dir); + return; + } + return; + } + + $lock = json_decode(FileSystem::readFile(LockFile::LOCK_FILE), true); + $source_type = $lock[$name]['source_type']; + $filename = DOWNLOAD_PATH . '/' . ($lock[$name]['filename'] ?? $lock[$name]['dirname']); + $extract = "{$pkgroot}/{$name}"; + + + FileSystem::extractPackage($name, $source_type, $filename, $extract); + + $this->createZigCcScript($zig_bin_dir); + } + + private function createZigCcScript(string $bin_dir): void + { + $zig_cc_path = "{$bin_dir}/zig-cc"; + + $script_content = <<<'EOF' +#!/usr/bin/env bash + +SPC_TARGET="${SPC_TARGET:-native-native}" +SPC_LIBC="${SPC_LIBC}" +SPC_LIBC_VERSION="${SPC_LIBC_VERSION}" + +if [ "$SPC_LIBC" = "glibc" ]; then + SPC_LIBC="gnu" +fi + +if [ "$SPC_TARGET" = "native-native" ] && [ -z "$SPC_LIBC" ] && [ -z "$SPC_LIBC_VERSION" ]; then + exec zig cc "$@" +elif [ -z "$SPC_LIBC" ] && [ -z "$SPC_LIBC_VERSION" ]; then + exec zig cc -target ${SPC_TARGET} "$@" +elif [ -z "$SPC_LIBC_VERSION" ]; then + exec zig cc -target ${SPC_TARGET}-${SPC_LIBC} -L/usr/lib64 -lstdc++ "$@" +else + error_output=$(zig cc -target ${SPC_TARGET}-${SPC_LIBC}.${SPC_LIBC_VERSION} "$@" 2>&1 >/dev/null) + if echo "$error_output" | grep -q "zig: error: version '.*' in target triple '${SPC_TARGET}-${SPC_LIBC}\..*' is invalid"; then + exec zig cc -target ${SPC_TARGET}-${SPC_LIBC} -L/usr/lib64 -lstdc++ "$@" + else + exec zig cc -target ${SPC_TARGET}-${SPC_LIBC}.${SPC_LIBC_VERSION} -L/usr/lib64 -lstdc++ "$@" + fi +fi + +EOF; + + file_put_contents($zig_cc_path, $script_content); + chmod($zig_cc_path, 0755); + } +} diff --git a/src/SPC/util/GlobalEnvManager.php b/src/SPC/util/GlobalEnvManager.php index 17785205..6f04b328 100644 --- a/src/SPC/util/GlobalEnvManager.php +++ b/src/SPC/util/GlobalEnvManager.php @@ -108,6 +108,10 @@ class GlobalEnvManager 'BSD' => self::applyConfig($ini['freebsd']), default => null, }; + + if (str_contains(getenv('CC'), 'zig')) { + // add to path + } } public static function putenv(string $val): void