simplify common zig code paths

This commit is contained in:
henderkes
2026-05-23 16:14:02 +07:00
parent e7fb1e203f
commit 1ae989df59
8 changed files with 73 additions and 19 deletions

View File

@@ -73,7 +73,7 @@ class llvm_compiler_rt
{
$sourceDir ??= SOURCE_PATH . '/llvm-compiler-rt';
$triple ??= SystemTarget::getCanonicalTriple();
$libDir = PKG_ROOT_PATH . '/zig/lib/' . $triple;
$libDir = zig::path() . '/lib/' . $triple;
if ($this->isBuilt($libDir)) {
return;
}
@@ -101,7 +101,10 @@ class llvm_compiler_rt
private function detectZigLlvmVersion(): ?string
{
[$rc, $out] = shell()->execWithResult('zig cc --version', false);
if (!zig::isInstalled()) {
return null;
}
[$rc, $out] = shell()->execWithResult(escapeshellarg(zig::binary()) . ' cc --version', false);
if ($rc !== 0) {
return null;
}

View File

@@ -102,8 +102,8 @@ class llvm_tools
'-DLLVM_BUILD_LLVM_DYLIB=OFF',
'-DLLVM_LINK_LLVM_DYLIB=OFF',
'-DBUILD_SHARED_LIBS=OFF',
'-DCMAKE_C_COMPILER=' . PKG_ROOT_PATH . '/zig/zig-cc',
'-DCMAKE_CXX_COMPILER=' . PKG_ROOT_PATH . '/zig/zig-c++',
'-DCMAKE_C_COMPILER=' . zig::binary('zig-cc'),
'-DCMAKE_CXX_COMPILER=' . zig::binary('zig-c++'),
'-DCMAKE_INSTALL_PREFIX=' . $installDir,
]));
$jobs = ApplicationContext::get(PackageBuilder::class)->concurrency;
@@ -137,11 +137,10 @@ class llvm_tools
private function detectLlvmVersion(): ?string
{
$zig = PKG_ROOT_PATH . '/zig/zig';
if (!is_file($zig)) {
if (!zig::isInstalled()) {
return null;
}
[$rc, $out] = shell()->execWithResult(escapeshellarg($zig) . ' cc --version', false);
[$rc, $out] = shell()->execWithResult(escapeshellarg(zig::binary()) . ' cc --version', false);
if ($rc !== 0) {
return null;
}

View File

@@ -15,6 +15,23 @@ use StaticPHP\Runtime\SystemTarget;
class zig
{
/** Directory zig extracts into. */
public static function path(): string
{
return PKG_ROOT_PATH . '/zig';
}
/** Path to a binary inside the zig install dir (zig, zig-cc, zig-c++, zig-ar, …). */
public static function binary(string $name = 'zig'): string
{
return self::path() . '/' . $name;
}
public static function isInstalled(): bool
{
return is_file(self::binary());
}
#[CustomBinary('zig', [
'linux-x86_64',
'linux-aarch64',

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace StaticPHP\Doctor\Item;
use Package\Artifact\llvm_compiler_rt;
use Package\Artifact\zig;
use StaticPHP\Attribute\Doctor\CheckItem;
use StaticPHP\Attribute\Doctor\FixItem;
use StaticPHP\Attribute\Doctor\OptionalCheck;
@@ -27,7 +28,7 @@ class LlvmCompilerRtCheck
#[CheckItem('if llvm-compiler-rt is built for current target', level: 799)]
public function checkLlvmCompilerRt(): CheckResult
{
$libDir = PKG_ROOT_PATH . '/zig/lib/' . SystemTarget::getCanonicalTriple();
$libDir = zig::dir() . '/lib/' . SystemTarget::getCanonicalTriple();
if (new llvm_compiler_rt()->isBuilt($libDir)) {
return CheckResult::ok($libDir);
}
@@ -41,7 +42,7 @@ class LlvmCompilerRtCheck
$installer->addInstallPackage('llvm-compiler-rt');
$installer->run(true);
new llvm_compiler_rt()->buildForTriple();
$libDir = PKG_ROOT_PATH . '/zig/lib/' . SystemTarget::getCanonicalTriple();
$libDir = zig::dir() . '/lib/' . SystemTarget::getCanonicalTriple();
return new llvm_compiler_rt()->isBuilt($libDir);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace StaticPHP\Doctor\Item;
use Package\Artifact\zig;
use StaticPHP\Attribute\Doctor\CheckItem;
use StaticPHP\Attribute\Doctor\FixItem;
use StaticPHP\Attribute\Doctor\OptionalCheck;
@@ -26,7 +27,7 @@ class ZigCheck
public function checkZig(): CheckResult
{
if (new PackageInstaller()->addInstallPackage('zig')->isPackageInstalled('zig')) {
return CheckResult::ok(PKG_ROOT_PATH . '/zig/zig');
return CheckResult::ok(zig::binary());
}
return CheckResult::fail('zig is not installed', 'install-zig');
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace StaticPHP\Runtime;
use StaticPHP\Toolchain\ZigToolchain;
use StaticPHP\Util\System\LinuxUtil;
/**
@@ -16,7 +17,7 @@ class SystemTarget
*/
public static function getLibc(): ?string
{
if ($target = getenv('SPC_TARGET')) {
if ($target = self::target()) {
if (str_contains($target, '-gnu')) {
return 'glibc';
}
@@ -57,7 +58,7 @@ class SystemTarget
public static function getLibcVersion(): ?string
{
if (PHP_OS_FAMILY === 'Linux') {
$target = (string) getenv('SPC_TARGET');
$target = self::target();
if (str_contains($target, '-gnu.2.')) {
return preg_match('/-gnu\.(2\.\d+)/', $target, $matches) ? $matches[1] : null;
}
@@ -75,7 +76,7 @@ class SystemTarget
*/
public static function getTargetOS(): string
{
$target = (string) getenv('SPC_TARGET');
$target = self::target();
return match (true) {
str_contains($target, '-linux') => 'Linux',
str_contains($target, '-macos') => 'Darwin',
@@ -91,7 +92,7 @@ class SystemTarget
*/
public static function getTargetArch(): string
{
$target = (string) getenv('SPC_TARGET');
$target = self::target();
return match (true) {
str_contains($target, 'x86_64') || str_contains($target, 'amd64') => 'x86_64',
str_contains($target, 'aarch64') || str_contains($target, 'arm64') => 'aarch64',
@@ -136,7 +137,7 @@ class SystemTarget
*/
public static function getCanonicalTriple(): string
{
$target = (string) getenv('SPC_TARGET');
$target = self::target();
if ($target !== '' && !str_contains($target, 'native')) {
$cleaned = (string) preg_replace('/(-gnu|-musl)\.[\d.]+/', '$1', $target);
$cleaned = preg_split('/\s+/', trim($cleaned))[0] ?? '';
@@ -161,7 +162,7 @@ class SystemTarget
*/
public static function getAutoconfHostTriple(): ?string
{
$target = (string) getenv('SPC_TARGET');
$target = self::target();
if ($target === '' || str_contains($target, 'native')) {
return null;
}
@@ -183,4 +184,14 @@ class SystemTarget
}
return $cleaned;
}
/** native toolchains ignore SPC_TARGET */
private static function target(): string
{
$tc = (string) getenv('SPC_TOOLCHAIN');
if ($tc !== '' && $tc !== ZigToolchain::class) {
return '';
}
return (string) getenv('SPC_TARGET');
}
}

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace StaticPHP\Toolchain;
use Package\Artifact\llvm_compiler_rt;
use Package\Artifact\zig;
use StaticPHP\DI\ApplicationContext;
use StaticPHP\Package\PackageBuilder;
use StaticPHP\Package\PackageInstaller;
@@ -56,7 +57,7 @@ class ZigToolchain implements UnixToolchainInterface
GlobalEnvManager::putenv("SPC_DEFAULT_CXXFLAGS={$cxxflags}");
GlobalEnvManager::putenv("SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS={$extraCflags}");
GlobalEnvManager::putenv('RANLIB=zig-ranlib');
GlobalEnvManager::putenv('SPC_COMPILER_RT_DIR=' . PKG_ROOT_PATH . '/zig/lib/' . SystemTarget::getCanonicalTriple());
GlobalEnvManager::putenv('SPC_COMPILER_RT_DIR=' . zig::path() . '/lib/' . SystemTarget::getCanonicalTriple());
GlobalEnvManager::putenv('OBJCOPY=' . PKG_ROOT_PATH . '/llvm-tools/bin/llvm-objcopy');
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
if (!str_contains($extra_libs, '-lunwind')) {
@@ -112,9 +113,12 @@ class ZigToolchain implements UnixToolchainInterface
private function ensureCompilerRt(): void
{
if (!zig::isInstalled()) {
return;
}
$rt = new llvm_compiler_rt();
$triple = SystemTarget::getCanonicalTriple();
$libDir = PKG_ROOT_PATH . '/zig/lib/' . $triple;
$libDir = zig::path() . '/lib/' . $triple;
if ($rt->isBuilt($libDir)) {
return;
}
@@ -154,6 +158,6 @@ class ZigToolchain implements UnixToolchainInterface
private function getPath(): string
{
return PKG_ROOT_PATH . '/zig';
return zig::path();
}
}

View File

@@ -123,6 +123,24 @@ class GlobalEnvManager
}
}
/** Re-substitute env.ini's CC=${SPC_DEFAULT_CC} bindings after a toolchain swap. */
public static function reapplyOsIni(): void
{
$ini = self::readIniFile();
$os_ini = match (PHP_OS_FAMILY) {
'Windows' => $ini['windows'] ?? [],
'Darwin' => $ini['macos'] ?? [],
'Linux' => $ini['linux'] ?? [],
'BSD' => $ini['freebsd'] ?? [],
default => [],
};
foreach (['CC', 'CXX', 'AR', 'RANLIB', 'LD'] as $k) {
if (isset($os_ini[$k])) {
self::putenv("{$k}={$os_ini[$k]}");
}
}
}
/**
* Initialize the toolchain after the environment variables are set.
* The toolchain or environment availability check is done here.