1414use StaticPHP \Exception \DownloaderException ;
1515use StaticPHP \Runtime \SystemTarget ;
1616
17+ /**
18+ * Builds the compiler-rt bits zig ships without — libclang_rt.profile.a (PGO instrumentation)
19+ * and clang_rt.crtbegin.o/crtend.o (__dso_handle for shared libs). Target-arch specific:
20+ * libs land in PKG_ROOT_PATH/zig/lib/{triple}.
21+ */
1722class llvm_compiler_rt
1823{
1924 #[CustomBinary('llvm-compiler-rt ' , [
2025 'linux-x86_64 ' ,
2126 'linux-aarch64 ' ,
27+ 'macos-x86_64 ' ,
28+ 'macos-aarch64 ' ,
2229 ])]
2330 public function downBinary (ArtifactDownloader $ downloader ): DownloadResult
2431 {
2532 $ llvmVersion = $ this ->detectZigLlvmVersion ()
26- ?? throw new DownloaderException ('Could not detect bundled clang version from zig cc --version; ensure zig is installed ' );
33+ ?? throw new DownloaderException ('llvm-compiler-rt: could not detect bundled clang version from zig cc --version ' );
2734 $ tarball = "compiler-rt- {$ llvmVersion }.src.tar.xz " ;
2835 $ url = "https://github.com/llvm/llvm-project/releases/download/llvmorg- {$ llvmVersion }/ {$ tarball }" ;
2936 $ tarballPath = DOWNLOAD_PATH . '/ ' . $ tarball ;
@@ -34,11 +41,13 @@ public function downBinary(ArtifactDownloader $downloader): DownloadResult
3441 #[CustomBinaryCheckUpdate('llvm-compiler-rt ' , [
3542 'linux-x86_64 ' ,
3643 'linux-aarch64 ' ,
44+ 'macos-x86_64 ' ,
45+ 'macos-aarch64 ' ,
3746 ])]
3847 public function checkUpdateBinary (?string $ old_version , ArtifactDownloader $ downloader ): CheckUpdateResult
3948 {
4049 $ llvmVersion = $ this ->detectZigLlvmVersion ()
41- ?? throw new DownloaderException ('Could not detect bundled clang version from zig cc --version; ensure zig is installed ' );
50+ ?? throw new DownloaderException ('llvm-compiler-rt: could not detect bundled clang version from zig cc --version ' );
4251 return new CheckUpdateResult (
4352 old: $ old_version ,
4453 new : $ llvmVersion ,
@@ -49,33 +58,34 @@ public function checkUpdateBinary(?string $old_version, ArtifactDownloader $down
4958 #[AfterBinaryExtract('llvm-compiler-rt ' , [
5059 'linux-x86_64 ' ,
5160 'linux-aarch64 ' ,
61+ 'macos-x86_64 ' ,
62+ 'macos-aarch64 ' ,
5263 ])]
5364 public function postExtract (string $ target_path ): void
5465 {
55- $ this ->buildForCurrentTarget ($ target_path );
66+ $ this ->buildForTriple ($ target_path );
5667 }
5768
58- public function buildForCurrentTarget (?string $ sourceDir = null ): void
69+ public function buildForTriple (?string $ sourceDir = null , ? string $ triple = null ): void
5970 {
6071 $ sourceDir ??= SOURCE_PATH . '/llvm-compiler-rt ' ;
61- $ triple = SystemTarget::getCanonicalTriple ();
72+ $ triple ?? = SystemTarget::getCanonicalTriple ();
6273 $ libDir = PKG_ROOT_PATH . '/zig/lib/ ' . $ triple ;
6374 if ($ this ->isBuilt ($ libDir )) {
6475 return ;
6576 }
66- if (!is_dir ($ sourceDir )) {
67- throw new BuildFailureException ("llvm-compiler-rt: missing source at {$ sourceDir }" );
77+ if (!is_dir ($ sourceDir ) || ! is_dir ( "{ $ sourceDir } /lib/profile " ) ) {
78+ throw new BuildFailureException ("llvm-compiler-rt: missing source at {$ sourceDir } (extraction layout changed?) " );
6879 }
69- $ zig = PKG_ROOT_PATH . '/zig/zig ' ;
7080 f_mkdir ($ libDir , recursive: true );
7181 $ profileLib = "{$ libDir }/libclang_rt.profile.a " ;
7282 $ crtBegin = "{$ libDir }/clang_rt.crtbegin.o " ;
7383 $ crtEnd = "{$ libDir }/clang_rt.crtend.o " ;
7484 if (!file_exists ($ profileLib )) {
75- $ this ->buildProfileRuntime ($ zig , $ sourceDir , $ profileLib , $ triple );
85+ $ this ->buildProfileRuntime ($ sourceDir , $ profileLib , $ triple );
7686 }
7787 if (!file_exists ($ crtBegin ) || !file_exists ($ crtEnd )) {
78- $ this ->buildCrtObjects ($ zig , $ sourceDir , $ crtBegin , $ crtEnd , $ triple );
88+ $ this ->buildCrtObjects ($ sourceDir , $ crtBegin , $ crtEnd , $ triple );
7989 }
8090 }
8191
@@ -86,13 +96,19 @@ public function isBuilt(string $libDir): bool
8696 && file_exists ("{$ libDir }/clang_rt.crtend.o " );
8797 }
8898
89- private function buildProfileRuntime (string $ zig , string $ srcRoot , string $ libPath , string $ triple ): void
99+ private function detectZigLlvmVersion (): ?string
100+ {
101+ [$ rc , $ out ] = shell ()->execWithResult ('zig cc --version ' , false );
102+ if ($ rc !== 0 ) {
103+ return null ;
104+ }
105+ return preg_match ('/clang version (\d+\.\d+\.\d+)/ ' , implode ("\n" , $ out ), $ m ) ? $ m [1 ] : null ;
106+ }
107+
108+ private function buildProfileRuntime (string $ srcRoot , string $ libPath , string $ triple ): void
90109 {
91110 $ profileSrc = "{$ srcRoot }/lib/profile " ;
92111 $ profileInc = "{$ srcRoot }/include " ;
93- if (!is_dir ($ profileSrc )) {
94- throw new BuildFailureException ("llvm-compiler-rt: profile src dir missing at {$ profileSrc }" );
95- }
96112 // Skip OS-specific sources we can't satisfy without their SDKs.
97113 $ skip = ['/PlatformAIX ' , '/PlatformDarwin ' , '/PlatformFuchsia ' , '/PlatformOther ' , '/PlatformWindows ' , '/WindowsMMap ' ];
98114 $ sources = array_filter (
@@ -105,16 +121,12 @@ private function buildProfileRuntime(string $zig, string $srcRoot, string $libPa
105121 $ cflags = "-target {$ triple } -c -O2 -fPIC -fvisibility=hidden "
106122 . '-I ' . escapeshellarg ($ profileInc ) . ' '
107123 . '-DCOMPILER_RT_HAS_ATOMICS=1 -DCOMPILER_RT_HAS_FCNTL_LCK=1 -DCOMPILER_RT_HAS_UNAME=1 ' ;
108- $ objs = [];
109- foreach ($ sources as $ src ) {
110- $ obj = $ objDir . '/ ' . pathinfo ($ src , PATHINFO_FILENAME ) . '.o ' ;
111- shell ()->exec (escapeshellarg ($ zig ) . ' cc ' . $ cflags . ' -o ' . escapeshellarg ($ obj ) . ' ' . escapeshellarg ($ src ));
112- $ objs [] = $ obj ;
113- }
114- shell ()->exec (escapeshellarg ($ zig ) . ' ar rcs ' . escapeshellarg ($ libPath ) . ' ' . implode (' ' , array_map ('escapeshellarg ' , $ objs )));
124+ $ srcArgs = implode (' ' , array_map ('escapeshellarg ' , $ sources ));
125+ shell ()->cd ($ objDir )->exec ("zig cc {$ cflags } {$ srcArgs }" );
126+ shell ()->cd ($ objDir )->exec ('zig ar rcs ' . escapeshellarg ($ libPath ) . ' *.o ' );
115127 }
116128
117- private function buildCrtObjects (string $ zig , string $ srcRoot , string $ crtBegin , string $ crtEnd , string $ triple ): void
129+ private function buildCrtObjects (string $ srcRoot , string $ crtBegin , string $ crtEnd , string $ triple ): void
118130 {
119131 $ beginSrc = "{$ srcRoot }/lib/builtins/crtbegin.c " ;
120132 $ endSrc = "{$ srcRoot }/lib/builtins/crtend.c " ;
@@ -123,20 +135,7 @@ private function buildCrtObjects(string $zig, string $srcRoot, string $crtBegin,
123135 }
124136 $ cflags = "-target {$ triple } -c -O2 -fPIC -fvisibility=hidden -DCRT_HAS_INITFINI_ARRAY " ;
125137 foreach ([[$ beginSrc , $ crtBegin ], [$ endSrc , $ crtEnd ]] as [$ src , $ dst ]) {
126- shell ()->exec (escapeshellarg ( $ zig) . ' cc ' . $ cflags . ' -o ' . escapeshellarg ($ dst ) . ' ' . escapeshellarg ($ src ));
138+ shell ()->exec (" zig cc { $ cflags} -o " . escapeshellarg ($ dst ) . ' ' . escapeshellarg ($ src ));
127139 }
128140 }
129-
130- private function detectZigLlvmVersion (): ?string
131- {
132- $ zig = PKG_ROOT_PATH . '/zig/zig ' ;
133- if (!is_file ($ zig )) {
134- return null ;
135- }
136- [$ rc , $ out ] = shell ()->execWithResult (escapeshellarg ($ zig ) . ' cc --version ' , false );
137- if ($ rc !== 0 ) {
138- return null ;
139- }
140- return preg_match ('/clang version (\d+\.\d+\.\d+)/ ' , implode ("\n" , $ out ), $ m ) ? $ m [1 ] : null ;
141- }
142141}
0 commit comments