build in SOURCE_PATH

This commit is contained in:
henderkes
2026-05-19 20:44:47 +07:00
parent 7bb4a09a3c
commit efa7946c14
5 changed files with 59 additions and 159 deletions

View File

@@ -10,6 +10,7 @@ use StaticPHP\Artifact\Downloader\Type\CheckUpdateResult;
use StaticPHP\Attribute\Artifact\AfterBinaryExtract;
use StaticPHP\Attribute\Artifact\CustomBinary;
use StaticPHP\Attribute\Artifact\CustomBinaryCheckUpdate;
use StaticPHP\Exception\BuildFailureException;
use StaticPHP\Exception\DownloaderException;
use StaticPHP\Runtime\SystemTarget;
@@ -27,7 +28,7 @@ class llvm_compiler_rt
$url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-{$llvmVersion}/{$tarball}";
$tarballPath = DOWNLOAD_PATH . '/' . $tarball;
default_shell()->executeCurlDownload($url, $tarballPath, retries: $downloader->getRetry());
return DownloadResult::archive($tarball, ['url' => $url, 'version' => $llvmVersion], extract: '{pkg_root_path}/llvm-compiler-rt', verified: false, version: $llvmVersion);
return DownloadResult::archive($tarball, ['url' => $url, 'version' => $llvmVersion], extract: '{source_path}/llvm-compiler-rt', verified: false, version: $llvmVersion);
}
#[CustomBinaryCheckUpdate('llvm-compiler-rt', [
@@ -54,25 +55,17 @@ class llvm_compiler_rt
$this->buildForCurrentTarget($target_path);
}
public function buildForCurrentTarget(?string $sourceDir = null): bool
public function buildForCurrentTarget(?string $sourceDir = null): void
{
$sourceDir ??= PKG_ROOT_PATH . '/llvm-compiler-rt';
$sourceDir ??= SOURCE_PATH . '/llvm-compiler-rt';
$triple = SystemTarget::getCanonicalTriple();
$libDir = PKG_ROOT_PATH . '/zig/lib/' . $triple;
if ($this->isBuilt($libDir)) {
return true;
return;
}
if (!is_dir($sourceDir)) {
logger()->warning("[llvm-compiler-rt] source dir missing at {$sourceDir}; cannot build runtime bits for {$triple}");
return false;
throw new BuildFailureException("llvm-compiler-rt: missing source at {$sourceDir}");
}
$llvmVersion = $this->detectZigLlvmVersion();
if ($llvmVersion === null) {
logger()->warning('[llvm-compiler-rt] could not detect bundled clang version; skipping runtime bit build (PGO + shared libs without __dso_handle will fail to link)');
return false;
}
logger()->info("Building llvm compiler-rt bits for {$triple} (LLVM {$llvmVersion})");
$zig = PKG_ROOT_PATH . '/zig/zig';
f_mkdir($libDir, recursive: true);
$profileLib = "{$libDir}/libclang_rt.profile.a";
@@ -84,7 +77,6 @@ class llvm_compiler_rt
if (!file_exists($crtBegin) || !file_exists($crtEnd)) {
$this->buildCrtObjects($zig, $sourceDir, $crtBegin, $crtEnd, $triple);
}
return $this->isBuilt($libDir);
}
public function isBuilt(string $libDir): bool
@@ -99,44 +91,27 @@ class llvm_compiler_rt
$profileSrc = "{$srcRoot}/lib/profile";
$profileInc = "{$srcRoot}/include";
if (!is_dir($profileSrc)) {
logger()->warning("[llvm-compiler-rt] profile src dir missing at {$profileSrc} — PGO will not work");
return;
throw new BuildFailureException("llvm-compiler-rt: profile src dir missing at {$profileSrc}");
}
$sources = array_merge(
glob("{$profileSrc}/*.c") ?: [],
glob("{$profileSrc}/*.cpp") ?: []
);
// Keep Linux-only compilation units; the others bring in OS-specific headers
// we can't satisfy without their respective SDKs.
// Skip OS-specific sources we can't satisfy without their SDKs.
$skip = ['/PlatformAIX', '/PlatformDarwin', '/PlatformFuchsia', '/PlatformOther', '/PlatformWindows', '/WindowsMMap'];
$sources = array_filter($sources, function ($f) use ($skip) {
foreach ($skip as $s) {
if (str_contains($f, $s)) {
return false;
}
}
return true;
});
$sources = array_filter(
array_merge(glob("{$profileSrc}/*.c") ?: [], glob("{$profileSrc}/*.cpp") ?: []),
fn ($f) => !array_any($skip, fn ($s) => str_contains($f, $s)),
);
$objDir = "{$srcRoot}/obj-profile-{$triple}";
f_mkdir($objDir, recursive: true);
$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';
$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';
$cmd = escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($obj) . ' ' . escapeshellarg($src) . ' 2>&1';
if (!$this->runZigCmd($cmd, $obj, "failed to compile {$src}")) {
return;
}
shell()->exec(escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($obj) . ' ' . escapeshellarg($src));
$objs[] = $obj;
}
$arCmd = escapeshellarg($zig) . ' ar rcs ' . escapeshellarg($libPath) . ' ' . implode(' ', array_map('escapeshellarg', $objs)) . ' 2>&1';
if (!$this->runZigCmd($arCmd, $libPath, 'zig ar failed')) {
return;
}
logger()->info('[llvm-compiler-rt] libclang_rt.profile.a installed (' . filesize($libPath) . ' bytes)');
shell()->exec(escapeshellarg($zig) . ' ar rcs ' . escapeshellarg($libPath) . ' ' . implode(' ', array_map('escapeshellarg', $objs)));
}
private function buildCrtObjects(string $zig, string $srcRoot, string $crtBegin, string $crtEnd, string $triple): void
@@ -144,27 +119,12 @@ class llvm_compiler_rt
$beginSrc = "{$srcRoot}/lib/builtins/crtbegin.c";
$endSrc = "{$srcRoot}/lib/builtins/crtend.c";
if (!is_file($beginSrc) || !is_file($endSrc)) {
logger()->error("[llvm-compiler-rt] crtbegin/crtend source missing under {$srcRoot}/lib/builtins — shared libs will lack __dso_handle");
return;
throw new BuildFailureException("llvm-compiler-rt: crtbegin/crtend source missing under {$srcRoot}/lib/builtins");
}
$cflags = "-target {$triple} -c -O2 -fPIC -fvisibility=hidden -DCRT_HAS_INITFINI_ARRAY";
foreach ([[$beginSrc, $crtBegin], [$endSrc, $crtEnd]] as [$src, $dst]) {
$cmd = escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($dst) . ' ' . escapeshellarg($src) . ' 2>&1';
if (!$this->runZigCmd($cmd, $dst, "failed to compile {$src}")) {
return;
}
shell()->exec(escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($dst) . ' ' . escapeshellarg($src));
}
logger()->info('[llvm-compiler-rt] clang_rt.crtbegin.o + clang_rt.crtend.o installed (' . filesize($crtBegin) . ' + ' . filesize($crtEnd) . ' bytes)');
}
private function runZigCmd(string $cmd, string $dst, string $errPrefix): bool
{
exec($cmd, $out, $rc);
if ($rc !== 0 || !is_file($dst)) {
logger()->warning("[llvm-compiler-rt] {$errPrefix}: " . implode("\n", $out));
return false;
}
return true;
}
private function detectZigLlvmVersion(): ?string
@@ -173,10 +133,10 @@ class llvm_compiler_rt
if (!is_file($zig)) {
return null;
}
$verLine = trim((string) shell_exec(escapeshellarg($zig) . ' cc --version 2>/dev/null'));
if (!preg_match('/clang version (\d+\.\d+\.\d+)/', $verLine, $m)) {
[$rc, $out] = shell()->execWithResult(escapeshellarg($zig) . ' cc --version', false);
if ($rc !== 0) {
return null;
}
return $m[1];
return preg_match('/clang version (\d+\.\d+\.\d+)/', implode("\n", $out), $m) ? $m[1] : null;
}
}