mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-06 16:25:39 +08:00
install runtime rt after zig init
This commit is contained in:
@@ -14,16 +14,23 @@ use StaticPHP\Exception\BuildFailureException;
|
||||
use StaticPHP\Exception\DownloaderException;
|
||||
use StaticPHP\Runtime\SystemTarget;
|
||||
|
||||
/**
|
||||
* Builds the compiler-rt bits zig ships without — libclang_rt.profile.a (PGO instrumentation)
|
||||
* and clang_rt.crtbegin.o/crtend.o (__dso_handle for shared libs). Target-arch specific:
|
||||
* libs land in PKG_ROOT_PATH/zig/lib/{triple}.
|
||||
*/
|
||||
class llvm_compiler_rt
|
||||
{
|
||||
#[CustomBinary('llvm-compiler-rt', [
|
||||
'linux-x86_64',
|
||||
'linux-aarch64',
|
||||
'macos-x86_64',
|
||||
'macos-aarch64',
|
||||
])]
|
||||
public function downBinary(ArtifactDownloader $downloader): DownloadResult
|
||||
{
|
||||
$llvmVersion = $this->detectZigLlvmVersion()
|
||||
?? throw new DownloaderException('Could not detect bundled clang version from zig cc --version; ensure zig is installed');
|
||||
?? throw new DownloaderException('llvm-compiler-rt: could not detect bundled clang version from zig cc --version');
|
||||
$tarball = "compiler-rt-{$llvmVersion}.src.tar.xz";
|
||||
$url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-{$llvmVersion}/{$tarball}";
|
||||
$tarballPath = DOWNLOAD_PATH . '/' . $tarball;
|
||||
@@ -34,11 +41,13 @@ class llvm_compiler_rt
|
||||
#[CustomBinaryCheckUpdate('llvm-compiler-rt', [
|
||||
'linux-x86_64',
|
||||
'linux-aarch64',
|
||||
'macos-x86_64',
|
||||
'macos-aarch64',
|
||||
])]
|
||||
public function checkUpdateBinary(?string $old_version, ArtifactDownloader $downloader): CheckUpdateResult
|
||||
{
|
||||
$llvmVersion = $this->detectZigLlvmVersion()
|
||||
?? throw new DownloaderException('Could not detect bundled clang version from zig cc --version; ensure zig is installed');
|
||||
?? throw new DownloaderException('llvm-compiler-rt: could not detect bundled clang version from zig cc --version');
|
||||
return new CheckUpdateResult(
|
||||
old: $old_version,
|
||||
new: $llvmVersion,
|
||||
@@ -49,33 +58,34 @@ class llvm_compiler_rt
|
||||
#[AfterBinaryExtract('llvm-compiler-rt', [
|
||||
'linux-x86_64',
|
||||
'linux-aarch64',
|
||||
'macos-x86_64',
|
||||
'macos-aarch64',
|
||||
])]
|
||||
public function postExtract(string $target_path): void
|
||||
{
|
||||
$this->buildForCurrentTarget($target_path);
|
||||
$this->buildForTriple($target_path);
|
||||
}
|
||||
|
||||
public function buildForCurrentTarget(?string $sourceDir = null): void
|
||||
public function buildForTriple(?string $sourceDir = null, ?string $triple = null): void
|
||||
{
|
||||
$sourceDir ??= SOURCE_PATH . '/llvm-compiler-rt';
|
||||
$triple = SystemTarget::getCanonicalTriple();
|
||||
$triple ??= SystemTarget::getCanonicalTriple();
|
||||
$libDir = PKG_ROOT_PATH . '/zig/lib/' . $triple;
|
||||
if ($this->isBuilt($libDir)) {
|
||||
return;
|
||||
}
|
||||
if (!is_dir($sourceDir)) {
|
||||
throw new BuildFailureException("llvm-compiler-rt: missing source at {$sourceDir}");
|
||||
if (!is_dir($sourceDir) || !is_dir("{$sourceDir}/lib/profile")) {
|
||||
throw new BuildFailureException("llvm-compiler-rt: missing source at {$sourceDir} (extraction layout changed?)");
|
||||
}
|
||||
$zig = PKG_ROOT_PATH . '/zig/zig';
|
||||
f_mkdir($libDir, recursive: true);
|
||||
$profileLib = "{$libDir}/libclang_rt.profile.a";
|
||||
$crtBegin = "{$libDir}/clang_rt.crtbegin.o";
|
||||
$crtEnd = "{$libDir}/clang_rt.crtend.o";
|
||||
if (!file_exists($profileLib)) {
|
||||
$this->buildProfileRuntime($zig, $sourceDir, $profileLib, $triple);
|
||||
$this->buildProfileRuntime($sourceDir, $profileLib, $triple);
|
||||
}
|
||||
if (!file_exists($crtBegin) || !file_exists($crtEnd)) {
|
||||
$this->buildCrtObjects($zig, $sourceDir, $crtBegin, $crtEnd, $triple);
|
||||
$this->buildCrtObjects($sourceDir, $crtBegin, $crtEnd, $triple);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,13 +96,19 @@ class llvm_compiler_rt
|
||||
&& file_exists("{$libDir}/clang_rt.crtend.o");
|
||||
}
|
||||
|
||||
private function buildProfileRuntime(string $zig, string $srcRoot, string $libPath, string $triple): void
|
||||
private function detectZigLlvmVersion(): ?string
|
||||
{
|
||||
[$rc, $out] = shell()->execWithResult('zig cc --version', false);
|
||||
if ($rc !== 0) {
|
||||
return null;
|
||||
}
|
||||
return preg_match('/clang version (\d+\.\d+\.\d+)/', implode("\n", $out), $m) ? $m[1] : null;
|
||||
}
|
||||
|
||||
private function buildProfileRuntime(string $srcRoot, string $libPath, string $triple): void
|
||||
{
|
||||
$profileSrc = "{$srcRoot}/lib/profile";
|
||||
$profileInc = "{$srcRoot}/include";
|
||||
if (!is_dir($profileSrc)) {
|
||||
throw new BuildFailureException("llvm-compiler-rt: profile src dir missing at {$profileSrc}");
|
||||
}
|
||||
// Skip OS-specific sources we can't satisfy without their SDKs.
|
||||
$skip = ['/PlatformAIX', '/PlatformDarwin', '/PlatformFuchsia', '/PlatformOther', '/PlatformWindows', '/WindowsMMap'];
|
||||
$sources = array_filter(
|
||||
@@ -105,16 +121,12 @@ class llvm_compiler_rt
|
||||
$cflags = "-target {$triple} -c -O2 -fPIC -fvisibility=hidden "
|
||||
. '-I' . escapeshellarg($profileInc) . ' '
|
||||
. '-DCOMPILER_RT_HAS_ATOMICS=1 -DCOMPILER_RT_HAS_FCNTL_LCK=1 -DCOMPILER_RT_HAS_UNAME=1';
|
||||
$objs = [];
|
||||
foreach ($sources as $src) {
|
||||
$obj = $objDir . '/' . pathinfo($src, PATHINFO_FILENAME) . '.o';
|
||||
shell()->exec(escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($obj) . ' ' . escapeshellarg($src));
|
||||
$objs[] = $obj;
|
||||
}
|
||||
shell()->exec(escapeshellarg($zig) . ' ar rcs ' . escapeshellarg($libPath) . ' ' . implode(' ', array_map('escapeshellarg', $objs)));
|
||||
$srcArgs = implode(' ', array_map('escapeshellarg', $sources));
|
||||
shell()->cd($objDir)->exec("zig cc {$cflags} {$srcArgs}");
|
||||
shell()->cd($objDir)->exec('zig ar rcs ' . escapeshellarg($libPath) . ' *.o');
|
||||
}
|
||||
|
||||
private function buildCrtObjects(string $zig, string $srcRoot, string $crtBegin, string $crtEnd, string $triple): void
|
||||
private function buildCrtObjects(string $srcRoot, string $crtBegin, string $crtEnd, string $triple): void
|
||||
{
|
||||
$beginSrc = "{$srcRoot}/lib/builtins/crtbegin.c";
|
||||
$endSrc = "{$srcRoot}/lib/builtins/crtend.c";
|
||||
@@ -123,20 +135,7 @@ class llvm_compiler_rt
|
||||
}
|
||||
$cflags = "-target {$triple} -c -O2 -fPIC -fvisibility=hidden -DCRT_HAS_INITFINI_ARRAY";
|
||||
foreach ([[$beginSrc, $crtBegin], [$endSrc, $crtEnd]] as [$src, $dst]) {
|
||||
shell()->exec(escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($dst) . ' ' . escapeshellarg($src));
|
||||
shell()->exec("zig cc {$cflags} -o " . escapeshellarg($dst) . ' ' . escapeshellarg($src));
|
||||
}
|
||||
}
|
||||
|
||||
private function detectZigLlvmVersion(): ?string
|
||||
{
|
||||
$zig = PKG_ROOT_PATH . '/zig/zig';
|
||||
if (!is_file($zig)) {
|
||||
return null;
|
||||
}
|
||||
[$rc, $out] = shell()->execWithResult(escapeshellarg($zig) . ' cc --version', false);
|
||||
if ($rc !== 0) {
|
||||
return null;
|
||||
}
|
||||
return preg_match('/clang version (\d+\.\d+\.\d+)/', implode("\n", $out), $m) ? $m[1] : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,26 +110,24 @@ class zig
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($all_exist) {
|
||||
return;
|
||||
if (!$all_exist) {
|
||||
$script_path = ROOT_DIR . '/src/globals/scripts/zig-cc.sh';
|
||||
$script_content = file_get_contents($script_path);
|
||||
|
||||
file_put_contents("{$target_path}/zig-cc", $script_content);
|
||||
chmod("{$target_path}/zig-cc", 0755);
|
||||
|
||||
$script_content = str_replace('zig cc', 'zig c++', $script_content);
|
||||
file_put_contents("{$target_path}/zig-c++", $script_content);
|
||||
file_put_contents("{$target_path}/zig-ar", "#!/usr/bin/env bash\nexec zig ar $@");
|
||||
file_put_contents("{$target_path}/zig-ld.lld", "#!/usr/bin/env bash\nexec zig ld.lld $@");
|
||||
file_put_contents("{$target_path}/zig-ranlib", "#!/usr/bin/env bash\nexec zig ranlib $@");
|
||||
file_put_contents("{$target_path}/zig-objcopy", "#!/usr/bin/env bash\nexec zig objcopy $@");
|
||||
chmod("{$target_path}/zig-c++", 0755);
|
||||
chmod("{$target_path}/zig-ar", 0755);
|
||||
chmod("{$target_path}/zig-ld.lld", 0755);
|
||||
chmod("{$target_path}/zig-ranlib", 0755);
|
||||
chmod("{$target_path}/zig-objcopy", 0755);
|
||||
}
|
||||
|
||||
$script_path = ROOT_DIR . '/src/globals/scripts/zig-cc.sh';
|
||||
$script_content = file_get_contents($script_path);
|
||||
|
||||
file_put_contents("{$target_path}/zig-cc", $script_content);
|
||||
chmod("{$target_path}/zig-cc", 0755);
|
||||
|
||||
$script_content = str_replace('zig cc', 'zig c++', $script_content);
|
||||
file_put_contents("{$target_path}/zig-c++", $script_content);
|
||||
file_put_contents("{$target_path}/zig-ar", "#!/usr/bin/env bash\nexec zig ar $@");
|
||||
file_put_contents("{$target_path}/zig-ld.lld", "#!/usr/bin/env bash\nexec zig ld.lld $@");
|
||||
file_put_contents("{$target_path}/zig-ranlib", "#!/usr/bin/env bash\nexec zig ranlib $@");
|
||||
file_put_contents("{$target_path}/zig-objcopy", "#!/usr/bin/env bash\nexec zig objcopy $@");
|
||||
chmod("{$target_path}/zig-c++", 0755);
|
||||
chmod("{$target_path}/zig-ar", 0755);
|
||||
chmod("{$target_path}/zig-ld.lld", 0755);
|
||||
chmod("{$target_path}/zig-ranlib", 0755);
|
||||
chmod("{$target_path}/zig-objcopy", 0755);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user