@@ -157,7 +157,8 @@ private function buildClangRuntimeBits(string $zig_bin_dir): void
157157 $ profileLib = "{$ libDir }/libclang_rt.profile.a " ;
158158 $ crtBegin = "{$ libDir }/clang_rt.crtbegin.o " ;
159159 $ crtEnd = "{$ libDir }/clang_rt.crtend.o " ;
160- if (file_exists ($ profileLib ) && file_exists ($ crtBegin ) && file_exists ($ crtEnd )) {
160+ $ cpuModelLib = "{$ libDir }/libclang_rt.cpu_model.a " ;
161+ if (file_exists ($ profileLib ) && file_exists ($ crtBegin ) && file_exists ($ crtEnd ) && file_exists ($ cpuModelLib )) {
161162 return ;
162163 }
163164
@@ -182,9 +183,49 @@ private function buildClangRuntimeBits(string $zig_bin_dir): void
182183 if (!file_exists ($ crtBegin ) || !file_exists ($ crtEnd )) {
183184 $ this ->buildCrtObjects ($ zig , $ srcRoot , $ crtBegin , $ crtEnd );
184185 }
186+ if (!file_exists ($ cpuModelLib )) {
187+ $ this ->buildCpuModelBuiltins ($ zig , $ srcRoot , $ cpuModelLib );
188+ }
185189 FileSystem::removeDir ($ srcRoot );
186190 }
187191
192+ private function buildCpuModelBuiltins (string $ zig , string $ srcRoot , string $ libPath ): void
193+ {
194+ $ builtins = "{$ srcRoot }/lib/builtins " ;
195+ $ arch = php_uname ('m ' );
196+ $ cpuModelDir = "{$ builtins }/cpu_model " ;
197+ if (is_dir ($ cpuModelDir )) {
198+ $ src = match (true ) {
199+ in_array ($ arch , ['x86_64 ' , 'amd64 ' , 'i386 ' , 'i686 ' , 'x86 ' ], true ) => "{$ cpuModelDir }/x86.c " ,
200+ in_array ($ arch , ['aarch64 ' , 'arm64 ' ], true ) => "{$ cpuModelDir }/aarch64.c " ,
201+ str_starts_with ($ arch , 'riscv ' ) => "{$ cpuModelDir }/riscv.c " ,
202+ default => null ,
203+ };
204+ $ includes = '-I ' . escapeshellarg ($ builtins ) . ' -I ' . escapeshellarg ($ cpuModelDir );
205+ } else {
206+ $ src = "{$ builtins }/cpu_model.c " ;
207+ $ includes = '-I ' . escapeshellarg ($ builtins );
208+ }
209+ if ($ src === null || !is_file ($ src )) {
210+ logger ()->warning ("[zig] cpu_model source not found for arch {$ arch } under {$ builtins } — __builtin_cpu_supports/__cpu_model will be unresolved " );
211+ return ;
212+ }
213+
214+ $ objDir = "{$ srcRoot }/obj-cpu-model " ;
215+ f_mkdir ($ objDir , recursive: true );
216+ $ obj = "{$ objDir }/cpu_model.o " ;
217+ $ cflags = '-c -O2 -fPIC ' . $ includes ;
218+ $ cmd = escapeshellarg ($ zig ) . ' cc ' . $ cflags . ' -o ' . escapeshellarg ($ obj ) . ' ' . escapeshellarg ($ src ) . ' 2>&1 ' ;
219+ if (!$ this ->runZigCmd ($ cmd , $ obj , "failed to compile {$ src }" )) {
220+ return ;
221+ }
222+ $ arCmd = escapeshellarg ($ zig ) . ' ar rcs ' . escapeshellarg ($ libPath ) . ' ' . escapeshellarg ($ obj ) . ' 2>&1 ' ;
223+ if (!$ this ->runZigCmd ($ arCmd , $ libPath , 'zig ar failed for cpu_model ' )) {
224+ return ;
225+ }
226+ logger ()->info ('[zig] libclang_rt.cpu_model.a installed ( ' . filesize ($ libPath ) . ' bytes) ' );
227+ }
228+
188229 private function fetchCompilerRtSource (string $ llvmVersion ): ?string
189230 {
190231 $ pkgName = "compiler-rt- {$ llvmVersion }" ;
0 commit comments