Merge branch 'main' into php-85

# Conflicts:
#	src/SPC/builder/linux/LinuxBuilder.php
#	src/SPC/store/source/PhpSource.php
#	src/globals/test-extensions.php
This commit is contained in:
crazywhalecc
2025-07-31 23:46:34 +08:00
88 changed files with 1129 additions and 678 deletions

View File

@@ -16,6 +16,8 @@ class GlobalEnvManager
{
private static array $env_cache = [];
private static bool $initialized = false;
public static function getInitializedEnv(): array
{
return self::$env_cache;
@@ -29,6 +31,9 @@ class GlobalEnvManager
*/
public static function init(): void
{
if (self::$initialized) {
return;
}
// Check pre-defined env vars exists
if (getenv('BUILD_ROOT_PATH') === false) {
throw new RuntimeException('You must include src/globals/internal-env.php before using GlobalEnvManager');
@@ -86,6 +91,7 @@ class GlobalEnvManager
self::putenv("{$k}={$v}");
}
}
self::$initialized = true;
}
public static function putenv(string $val): void

View File

@@ -57,7 +57,7 @@ class SPCConfigUtil
* @throws WrongUsageException
* @throws \Throwable
*/
public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false, bool $with_dependencies = false): array
public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false): array
{
[$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions, $libraries, $include_suggest_ext, $include_suggest_lib);
@@ -73,9 +73,9 @@ class SPCConfigUtil
$libs = $this->getLibsString($libraries, !$this->absolute_libs);
// additional OS-specific libraries (e.g. macOS -lresolv)
$extra_env = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS');
if (is_string($extra_env)) {
$libs .= ' ' . trim($extra_env, '"');
// embed
if ($extra_libs = SPCTarget::getRuntimeLibs()) {
$libs .= " {$extra_libs}";
}
$extra_env = getenv('SPC_EXTRA_LIBS');
if (is_string($extra_env) && !empty($extra_env)) {
@@ -86,14 +86,21 @@ class SPCConfigUtil
$libs .= " {$this->getFrameworksString($extensions)}";
}
if ($this->builder->hasCpp()) {
$libs .= SPCTarget::getTargetOS() === 'Darwin' ? ' -lc++' : ' -lstdc++';
$libcpp = SPCTarget::getTargetOS() === 'Darwin' ? '-lc++' : '-lstdc++';
if (!str_contains($libs, $libcpp)) {
$libs .= " {$libcpp}";
}
}
if ($this->libs_only_deps) {
// mimalloc must come first
if ($this->builder->getLib('mimalloc') && file_exists(BUILD_LIB_PATH . '/libmimalloc.a')) {
$libs = BUILD_LIB_PATH . '/libmimalloc.a ' . str_replace([BUILD_LIB_PATH . '/libmimalloc.a', '-lmimalloc'], ['', ''], $libs);
}
return [
'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags),
'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags),
'libs' => trim(getenv('LIBS') . ' ' . $libs),
'cflags' => clean_spaces(getenv('CFLAGS') . ' ' . $cflags),
'ldflags' => clean_spaces(getenv('LDFLAGS') . ' ' . $ldflags),
'libs' => clean_spaces(getenv('LIBS') . ' ' . $libs),
];
}
@@ -105,14 +112,14 @@ class SPCConfigUtil
$allLibs = getenv('LIBS') . ' ' . $libs;
// mimalloc must come first
if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) {
$allLibs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $allLibs);
if ($this->builder->getLib('mimalloc') && file_exists(BUILD_LIB_PATH . '/libmimalloc.a')) {
$allLibs = BUILD_LIB_PATH . '/libmimalloc.a ' . str_replace([BUILD_LIB_PATH . '/libmimalloc.a', '-lmimalloc'], ['', ''], $allLibs);
}
return [
'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags),
'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags),
'libs' => trim($allLibs),
'cflags' => clean_spaces(getenv('CFLAGS') . ' ' . $cflags),
'ldflags' => clean_spaces(getenv('LDFLAGS') . ' ' . $ldflags),
'libs' => clean_spaces($allLibs),
];
}
@@ -179,7 +186,7 @@ class SPCConfigUtil
$lib_names = [...$lib_names, ...$pc_libs];
}
// convert all static-libs to short names
$libs = Config::getLib($library, 'static-libs', []);
$libs = array_reverse(Config::getLib($library, 'static-libs', []));
foreach ($libs as $lib) {
// check file existence
if (!file_exists(BUILD_LIB_PATH . "/{$lib}")) {

View File

@@ -5,7 +5,10 @@ declare(strict_types=1);
namespace SPC\util;
use SPC\builder\linux\SystemUtil;
use SPC\exception\WrongUsageException;
use SPC\toolchain\ClangNativeToolchain;
use SPC\toolchain\GccNativeToolchain;
use SPC\toolchain\MuslToolchain;
use SPC\toolchain\ToolchainManager;
/**
* SPC build target constants and toolchain initialization.
@@ -13,23 +16,44 @@ use SPC\exception\WrongUsageException;
*/
class SPCTarget
{
public const array LIBC_LIST = [
'musl',
'glibc',
];
public const array LIBC_LIST = ['musl', 'glibc'];
/**
* Returns whether the target is a full-static target.
* Returns whether we link the C runtime in statically.
*/
public static function isStatic(): bool
{
$env = getenv('SPC_TARGET');
$libc = getenv('SPC_LIBC');
if (ToolchainManager::getToolchainClass() === MuslToolchain::class) {
return true;
}
if (ToolchainManager::getToolchainClass() === GccNativeToolchain::class) {
return PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist();
}
if (ToolchainManager::getToolchainClass() === ClangNativeToolchain::class) {
return PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist();
}
// if SPC_LIBC is set, it means the target is static, remove it when 3.0 is released
if ($libc === 'musl') {
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;
}
if (str_contains($target, '-musl')) {
return true;
}
if (PHP_OS_FAMILY === 'Linux') {
return SystemUtil::isMuslDist();
}
return true;
}
if (getenv('SPC_LIBC') === 'musl') {
return true;
}
// TODO: add zig target parser here
return false;
}
@@ -38,29 +62,45 @@ class SPCTarget
*/
public static function getLibc(): ?string
{
$env = getenv('SPC_TARGET');
if ($target = getenv('SPC_TARGET')) {
if (str_contains($target, '-gnu')) {
return 'glibc';
}
if (str_contains($target, '-musl')) {
return 'musl';
}
if (PHP_OS_FAMILY === 'Linux') {
return SystemUtil::isMuslDist() ? 'musl' : 'glibc';
}
}
$libc = getenv('SPC_LIBC');
if ($libc !== false) {
return $libc;
}
// TODO: zig target parser
if (PHP_OS_FAMILY === 'Linux') {
return SystemUtil::isMuslDist() ? 'musl' : 'glibc';
}
return null;
}
public static function getRuntimeLibs(): string
{
if (PHP_OS_FAMILY === 'Linux') {
return self::getLibc() === 'musl' ? '-ldl -lpthread -lm' : '-ldl -lrt -lpthread -lm -lresolv -lutil';
}
if (PHP_OS_FAMILY === 'Darwin') {
return '-lresolv';
}
return '';
}
/**
* Returns the libc version if set, for other OS, it will always return null.
*/
public static function getLibcVersion(): ?string
{
$env = getenv('SPC_TARGET');
$libc = getenv('SPC_LIBC');
if ($libc !== false) {
// legacy method: get a version from system
return SystemUtil::getLibcVersionIfExists($libc);
}
// TODO: zig target parser
return null;
$libc = self::getLibc();
return SystemUtil::getLibcVersionIfExists($libc);
}
/**
@@ -68,20 +108,16 @@ class SPCTarget
* Currently, we only support native building.
*
* @return 'BSD'|'Darwin'|'Linux'|'Windows'
* @throws WrongUsageException
*/
public static function getTargetOS(): string
{
$target = getenv('SPC_TARGET');
if ($target === false || $target === '') {
return PHP_OS_FAMILY;
}
// TODO: zig target parser like below?
$target = (string) getenv('SPC_TARGET');
return match (true) {
str_contains($target, 'linux') => 'Linux',
str_contains($target, 'macos') => 'Darwin',
str_contains($target, 'windows') => 'Windows',
default => throw new WrongUsageException('Cannot parse target.'),
str_contains($target, '-linux') => 'Linux',
str_contains($target, '-macos') => 'Darwin',
str_contains($target, '-windows') => 'Windows',
str_contains($target, '-native') => PHP_OS_FAMILY,
default => PHP_OS_FAMILY,
};
}
}

View File

@@ -61,9 +61,9 @@ class UnixShell
{
$this->setEnv([
'CFLAGS' => $library->getLibExtraCFlags(),
'CXXFLAGS' => $library->getLibExtraCXXFlags(),
'LDFLAGS' => $library->getLibExtraLdFlags(),
'LIBS' => $library->getLibExtraLibs(),
'CXXFLAGS' => $library->getLibExtraCXXFlags(),
]);
return $this;
}

View File

@@ -135,6 +135,7 @@ class UnixAutoconfExecutor extends Executor
{
$this->shell = shell()->cd($this->library->getSourceDir())->initializeEnv($this->library)->appendEnv([
'CFLAGS' => "-I{$this->library->getIncludeDir()}",
'CXXFLAGS' => "-I{$this->library->getIncludeDir()}",
'LDFLAGS' => "-L{$this->library->getLibDir()}",
]);
}