diff --git a/src/SPC/store/pkg/Zig.php b/src/SPC/store/pkg/Zig.php index ffe46657..018d456c 100644 --- a/src/SPC/store/pkg/Zig.php +++ b/src/SPC/store/pkg/Zig.php @@ -157,7 +157,8 @@ class Zig extends CustomPackage $profileLib = "{$libDir}/libclang_rt.profile.a"; $crtBegin = "{$libDir}/clang_rt.crtbegin.o"; $crtEnd = "{$libDir}/clang_rt.crtend.o"; - if (file_exists($profileLib) && file_exists($crtBegin) && file_exists($crtEnd)) { + $cpuModelLib = "{$libDir}/libclang_rt.cpu_model.a"; + if (file_exists($profileLib) && file_exists($crtBegin) && file_exists($crtEnd) && file_exists($cpuModelLib)) { return; } @@ -182,9 +183,49 @@ class Zig extends CustomPackage if (!file_exists($crtBegin) || !file_exists($crtEnd)) { $this->buildCrtObjects($zig, $srcRoot, $crtBegin, $crtEnd); } + if (!file_exists($cpuModelLib)) { + $this->buildCpuModelBuiltins($zig, $srcRoot, $cpuModelLib); + } FileSystem::removeDir($srcRoot); } + private function buildCpuModelBuiltins(string $zig, string $srcRoot, string $libPath): void + { + $builtins = "{$srcRoot}/lib/builtins"; + $arch = php_uname('m'); + $cpuModelDir = "{$builtins}/cpu_model"; + if (is_dir($cpuModelDir)) { + $src = match (true) { + in_array($arch, ['x86_64', 'amd64', 'i386', 'i686', 'x86'], true) => "{$cpuModelDir}/x86.c", + in_array($arch, ['aarch64', 'arm64'], true) => "{$cpuModelDir}/aarch64.c", + str_starts_with($arch, 'riscv') => "{$cpuModelDir}/riscv.c", + default => null, + }; + $includes = '-I' . escapeshellarg($builtins) . ' -I' . escapeshellarg($cpuModelDir); + } else { + $src = "{$builtins}/cpu_model.c"; + $includes = '-I' . escapeshellarg($builtins); + } + if ($src === null || !is_file($src)) { + logger()->warning("[zig] cpu_model source not found for arch {$arch} under {$builtins} — __builtin_cpu_supports/__cpu_model will be unresolved"); + return; + } + + $objDir = "{$srcRoot}/obj-cpu-model"; + f_mkdir($objDir, recursive: true); + $obj = "{$objDir}/cpu_model.o"; + $cflags = '-c -O2 -fPIC ' . $includes; + $cmd = escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($obj) . ' ' . escapeshellarg($src) . ' 2>&1'; + if (!$this->runZigCmd($cmd, $obj, "failed to compile {$src}")) { + return; + } + $arCmd = escapeshellarg($zig) . ' ar rcs ' . escapeshellarg($libPath) . ' ' . escapeshellarg($obj) . ' 2>&1'; + if (!$this->runZigCmd($arCmd, $libPath, 'zig ar failed for cpu_model')) { + return; + } + logger()->info('[zig] libclang_rt.cpu_model.a installed (' . filesize($libPath) . ' bytes)'); + } + private function fetchCompilerRtSource(string $llvmVersion): ?string { $pkgName = "compiler-rt-{$llvmVersion}"; diff --git a/src/SPC/store/scripts/zig-cc.sh b/src/SPC/store/scripts/zig-cc.sh index b698842b..ecb889ce 100644 --- a/src/SPC/store/scripts/zig-cc.sh +++ b/src/SPC/store/scripts/zig-cc.sh @@ -67,6 +67,9 @@ fi if [[ $IS_LINK -eq 1 && $NEED_CRT -eq 1 && -f "$SCRIPT_DIR/lib/clang_rt.crtbegin.o" && -f "$SCRIPT_DIR/lib/clang_rt.crtend.o" ]]; then PARSED_ARGS+=("$SCRIPT_DIR/lib/clang_rt.crtbegin.o" "$SCRIPT_DIR/lib/clang_rt.crtend.o") fi +if [[ $IS_LINK -eq 1 && -f "$SCRIPT_DIR/lib/libclang_rt.cpu_model.a" ]]; then + PARSED_ARGS+=("$SCRIPT_DIR/lib/libclang_rt.cpu_model.a") +fi [[ -n "$SPC_TARGET" ]] && TARGET="-target $SPC_TARGET" || TARGET=""