2025-06-28 16:36:05 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace SPC\util;
|
|
|
|
|
|
2025-06-29 16:00:17 +08:00
|
|
|
use SPC\builder\linux\SystemUtil;
|
2025-07-05 14:26:04 +07:00
|
|
|
use SPC\toolchain\ClangNativeToolchain;
|
|
|
|
|
use SPC\toolchain\GccNativeToolchain;
|
|
|
|
|
use SPC\toolchain\MuslToolchain;
|
|
|
|
|
use SPC\toolchain\ToolchainManager;
|
2025-06-28 16:36:05 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* SPC build target constants and toolchain initialization.
|
|
|
|
|
* format: {target_name}[-{libc_subtype}]
|
|
|
|
|
*/
|
|
|
|
|
class SPCTarget
|
|
|
|
|
{
|
2025-07-29 10:49:08 +07:00
|
|
|
public const array LIBC_LIST = ['musl', 'glibc'];
|
2025-07-29 10:39:21 +07:00
|
|
|
|
2025-06-29 16:00:17 +08:00
|
|
|
/**
|
2025-07-01 12:55:32 +07:00
|
|
|
* Returns whether we link the C runtime in statically.
|
2025-06-29 16:00:17 +08:00
|
|
|
*/
|
2025-06-29 22:49:48 +08:00
|
|
|
public static function isStatic(): bool
|
2025-06-28 16:36:05 +08:00
|
|
|
{
|
2025-07-05 14:26:04 +07:00
|
|
|
if (ToolchainManager::getToolchainClass() === MuslToolchain::class) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (ToolchainManager::getToolchainClass() === GccNativeToolchain::class) {
|
2026-01-27 00:57:58 +01:00
|
|
|
return PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist() && !getenv('SPC_MUSL_DYNAMIC');
|
2025-07-05 14:26:04 +07:00
|
|
|
}
|
|
|
|
|
if (ToolchainManager::getToolchainClass() === ClangNativeToolchain::class) {
|
2026-01-27 00:57:58 +01:00
|
|
|
return PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist() && !getenv('SPC_MUSL_DYNAMIC');
|
2025-07-05 14:26:04 +07:00
|
|
|
}
|
2025-06-29 16:00:17 +08:00
|
|
|
// if SPC_LIBC is set, it means the target is static, remove it when 3.0 is released
|
2025-07-01 12:55:32 +07:00
|
|
|
if ($target = getenv('SPC_TARGET')) {
|
|
|
|
|
if (str_contains($target, '-macos') || str_contains($target, '-native') && PHP_OS_FAMILY === 'Darwin') {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (str_contains($target, '-gnu')) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (str_contains($target, '-dynamic')) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-07-03 12:33:55 +07:00
|
|
|
if (str_contains($target, '-musl')) {
|
2025-07-05 21:54:36 +07:00
|
|
|
return true;
|
2025-07-03 12:33:55 +07:00
|
|
|
}
|
|
|
|
|
if (PHP_OS_FAMILY === 'Linux') {
|
|
|
|
|
return SystemUtil::isMuslDist();
|
|
|
|
|
}
|
2025-07-01 12:55:32 +07:00
|
|
|
return true;
|
|
|
|
|
}
|
2025-07-01 17:08:19 +07:00
|
|
|
if (getenv('SPC_LIBC') === 'musl') {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-06-29 16:00:17 +08:00
|
|
|
return false;
|
2025-06-28 16:36:05 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-29 16:00:17 +08:00
|
|
|
/**
|
|
|
|
|
* Returns the libc type if set, for other OS, it will always return null.
|
|
|
|
|
*/
|
|
|
|
|
public static function getLibc(): ?string
|
|
|
|
|
{
|
2025-07-01 18:06:18 +07:00
|
|
|
if ($target = getenv('SPC_TARGET')) {
|
|
|
|
|
if (str_contains($target, '-gnu')) {
|
|
|
|
|
return 'glibc';
|
|
|
|
|
}
|
|
|
|
|
if (str_contains($target, '-musl')) {
|
|
|
|
|
return 'musl';
|
|
|
|
|
}
|
2025-07-03 12:44:49 +07:00
|
|
|
if (PHP_OS_FAMILY === 'Linux') {
|
|
|
|
|
return SystemUtil::isMuslDist() ? 'musl' : 'glibc';
|
2025-07-01 18:06:18 +07:00
|
|
|
}
|
2025-07-01 12:55:32 +07:00
|
|
|
}
|
2025-07-01 17:08:19 +07:00
|
|
|
$libc = getenv('SPC_LIBC');
|
|
|
|
|
if ($libc !== false) {
|
|
|
|
|
return $libc;
|
|
|
|
|
}
|
2025-07-03 12:44:49 +07:00
|
|
|
if (PHP_OS_FAMILY === 'Linux') {
|
|
|
|
|
return SystemUtil::isMuslDist() ? 'musl' : 'glibc';
|
|
|
|
|
}
|
2025-06-29 16:00:17 +08:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-04 14:27:48 +07:00
|
|
|
public static function getRuntimeLibs(): string
|
|
|
|
|
{
|
|
|
|
|
if (PHP_OS_FAMILY === 'Linux') {
|
2025-07-05 10:49:20 +08:00
|
|
|
return self::getLibc() === 'musl' ? '-ldl -lpthread -lm' : '-ldl -lrt -lpthread -lm -lresolv -lutil';
|
2025-07-04 14:27:48 +07:00
|
|
|
}
|
|
|
|
|
if (PHP_OS_FAMILY === 'Darwin') {
|
|
|
|
|
return '-lresolv';
|
|
|
|
|
}
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-29 16:00:17 +08:00
|
|
|
/**
|
|
|
|
|
* Returns the libc version if set, for other OS, it will always return null.
|
|
|
|
|
*/
|
|
|
|
|
public static function getLibcVersion(): ?string
|
|
|
|
|
{
|
2025-08-01 01:53:38 +08:00
|
|
|
if (PHP_OS_FAMILY === 'Linux') {
|
2025-08-26 14:51:07 +07:00
|
|
|
$target = (string) getenv('SPC_TARGET');
|
2025-08-26 14:07:49 +07:00
|
|
|
if (str_contains($target, '-gnu.2.')) {
|
|
|
|
|
return preg_match('/-gnu\.(2\.\d+)/', $target, $matches) ? $matches[1] : null;
|
|
|
|
|
}
|
2025-08-01 01:53:38 +08:00
|
|
|
$libc = self::getLibc();
|
|
|
|
|
return SystemUtil::getLibcVersionIfExists($libc);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
2025-06-29 16:00:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the target OS family, e.g. Linux, Darwin, Windows, BSD.
|
|
|
|
|
* Currently, we only support native building.
|
|
|
|
|
*
|
|
|
|
|
* @return 'BSD'|'Darwin'|'Linux'|'Windows'
|
|
|
|
|
*/
|
|
|
|
|
public static function getTargetOS(): string
|
2025-06-28 16:36:05 +08:00
|
|
|
{
|
2025-07-01 23:31:54 +07:00
|
|
|
$target = (string) getenv('SPC_TARGET');
|
2025-06-29 16:00:17 +08:00
|
|
|
return match (true) {
|
2025-07-01 16:40:12 +07:00
|
|
|
str_contains($target, '-linux') => 'Linux',
|
|
|
|
|
str_contains($target, '-macos') => 'Darwin',
|
|
|
|
|
str_contains($target, '-windows') => 'Windows',
|
|
|
|
|
str_contains($target, '-native') => PHP_OS_FAMILY,
|
2025-07-01 23:31:54 +07:00
|
|
|
default => PHP_OS_FAMILY,
|
2025-06-29 16:00:17 +08:00
|
|
|
};
|
2025-06-28 23:11:26 +08:00
|
|
|
}
|
2025-06-28 16:36:05 +08:00
|
|
|
}
|