"{$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); } }