mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-06 16:25:39 +08:00
refactor: replace SPC_LIBC with SPC_TARGET and update related logic
This commit is contained in:
@@ -40,24 +40,6 @@ class GlobalEnvManager
|
||||
self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig');
|
||||
}
|
||||
|
||||
// Define env vars for linux
|
||||
if (PHP_OS_FAMILY === 'Linux') {
|
||||
$arch = getenv('GNU_ARCH');
|
||||
if (SystemUtil::isMuslDist() || getenv('SPC_LIBC') === 'glibc') {
|
||||
self::putenv('SPC_LINUX_DEFAULT_CC=gcc');
|
||||
self::putenv('SPC_LINUX_DEFAULT_CXX=g++');
|
||||
self::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||
self::putenv('SPC_LINUX_DEFAULT_LD=ld.gold');
|
||||
} else {
|
||||
self::putenv("SPC_LINUX_DEFAULT_CC={$arch}-linux-musl-gcc");
|
||||
self::putenv("SPC_LINUX_DEFAULT_CXX={$arch}-linux-musl-g++");
|
||||
self::putenv("SPC_LINUX_DEFAULT_AR={$arch}-linux-musl-ar");
|
||||
self::putenv("SPC_LINUX_DEFAULT_LD={$arch}-linux-musl-ld");
|
||||
self::addPathIfNotExists('/usr/local/musl/bin');
|
||||
self::addPathIfNotExists("/usr/local/musl/{$arch}-linux-musl/bin");
|
||||
}
|
||||
}
|
||||
|
||||
$ini = self::readIniFile();
|
||||
|
||||
$default_put_list = [];
|
||||
@@ -80,6 +62,29 @@ class GlobalEnvManager
|
||||
self::putenv("{$k}={$v}");
|
||||
}
|
||||
}
|
||||
|
||||
// deprecated: convert SPC_LIBC to SPC_TARGET
|
||||
if (getenv('SPC_LIBC') !== false) {
|
||||
logger()->warning('SPC_LIBC is deprecated, please use SPC_TARGET instead.');
|
||||
$target = match (getenv('SPC_LIBC')) {
|
||||
'musl' => SPCTarget::MUSL_STATIC,
|
||||
default => SPCTarget::GLIBC,
|
||||
};
|
||||
self::putenv("SPC_TARGET={$target}");
|
||||
self::putenv('SPC_LIBC');
|
||||
}
|
||||
|
||||
// auto-select toolchain based on target and OS temporarily
|
||||
// TODO: use 'zig' instead of 'gcc-native' when ZigToolchain is implemented
|
||||
$toolchain = match (getenv('SPC_TARGET')) {
|
||||
SPCTarget::MUSL_STATIC, SPCTarget::MUSL => SystemUtil::isMuslDist() ? 'gcc-native' : 'musl',
|
||||
SPCTarget::MACHO => 'clang-native',
|
||||
SPCTarget::MSVC_STATIC => 'msvc',
|
||||
default => 'gcc-native',
|
||||
};
|
||||
|
||||
SPCTarget::initTargetForToolchain($toolchain);
|
||||
|
||||
// apply second time
|
||||
$ini2 = self::readIniFile();
|
||||
|
||||
@@ -108,13 +113,18 @@ class GlobalEnvManager
|
||||
self::$env_cache[] = $val;
|
||||
}
|
||||
|
||||
private static function addPathIfNotExists(string $path): void
|
||||
public static function addPathIfNotExists(string $path): void
|
||||
{
|
||||
if (is_unix() && !str_contains(getenv('PATH'), $path)) {
|
||||
self::putenv("PATH={$path}:" . getenv('PATH'));
|
||||
}
|
||||
}
|
||||
|
||||
public static function afterInit(): void
|
||||
{
|
||||
SPCTarget::afterInitTargetForToolchain();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
|
||||
@@ -55,7 +55,7 @@ class SPCConfigUtil
|
||||
ob_get_clean();
|
||||
$ldflags = $this->getLdflagsString();
|
||||
$libs = $this->getLibsString($libraries, $with_dependencies);
|
||||
if (PHP_OS_FAMILY === 'Darwin') {
|
||||
if (SPCTarget::isTarget(SPCTarget::MACHO)) {
|
||||
$libs .= " {$this->getFrameworksString($extensions)}";
|
||||
}
|
||||
$cflags = $this->getIncludesString();
|
||||
@@ -146,7 +146,7 @@ class SPCConfigUtil
|
||||
}
|
||||
}
|
||||
// patch: imagick (imagemagick wrapper) for linux needs libgomp
|
||||
if (in_array('imagemagick', $libraries) && PHP_OS_FAMILY === 'Linux' && !(getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10'))) {
|
||||
if (in_array('imagemagick', $libraries) && !SPCTarget::isTarget(SPCTarget::GLIBC)) {
|
||||
$short_name[] = '-lgomp';
|
||||
}
|
||||
return implode(' ', $short_name);
|
||||
|
||||
83
src/SPC/util/SPCTarget.php
Normal file
83
src/SPC/util/SPCTarget.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\toolchain\ClangNativeToolchain;
|
||||
use SPC\util\toolchain\GccNativeToolchain;
|
||||
use SPC\util\toolchain\MSVCToolchain;
|
||||
use SPC\util\toolchain\MuslToolchain;
|
||||
use SPC\util\toolchain\ToolchainInterface;
|
||||
use SPC\util\toolchain\ZigToolchain;
|
||||
|
||||
/**
|
||||
* SPC build target constants and toolchain initialization.
|
||||
* format: {target_name}[-{libc_subtype}]
|
||||
*/
|
||||
class SPCTarget
|
||||
{
|
||||
public const MUSL = 'musl';
|
||||
|
||||
public const MUSL_STATIC = 'musl-static';
|
||||
|
||||
public const GLIBC = 'glibc';
|
||||
|
||||
public const MACHO = 'macho';
|
||||
|
||||
public const MSVC_STATIC = 'msvc-static';
|
||||
|
||||
public const TOOLCHAIN_LIST = [
|
||||
'musl' => MuslToolchain::class,
|
||||
'gcc-native' => GccNativeToolchain::class,
|
||||
'clang-native' => ClangNativeToolchain::class,
|
||||
'msvc' => MSVCToolchain::class,
|
||||
'zig' => ZigToolchain::class,
|
||||
];
|
||||
|
||||
public static function isTarget(string $target): bool
|
||||
{
|
||||
$env = getenv('SPC_TARGET');
|
||||
if ($env === false) {
|
||||
return false;
|
||||
}
|
||||
$env = strtolower($env);
|
||||
return $env === $target;
|
||||
}
|
||||
|
||||
public static function isStaticTarget(): bool
|
||||
{
|
||||
$env = getenv('SPC_TARGET');
|
||||
if ($env === false) {
|
||||
return false;
|
||||
}
|
||||
$env = strtolower($env);
|
||||
return str_ends_with($env, '-static') || $env === self::MUSL_STATIC;
|
||||
}
|
||||
|
||||
public static function initTargetForToolchain(string $toolchain): void
|
||||
{
|
||||
$target = getenv('SPC_TARGET');
|
||||
$toolchain = strtolower($toolchain);
|
||||
if (isset(self::TOOLCHAIN_LIST[$toolchain])) {
|
||||
$toolchainClass = self::TOOLCHAIN_LIST[$toolchain];
|
||||
/* @var ToolchainInterface $toolchainClass */
|
||||
(new $toolchainClass())->initEnv($target);
|
||||
}
|
||||
GlobalEnvManager::putenv("SPC_TOOLCHAIN={$toolchain}");
|
||||
}
|
||||
|
||||
public static function afterInitTargetForToolchain()
|
||||
{
|
||||
if (!getenv('SPC_TOOLCHAIN')) {
|
||||
throw new WrongUsageException('SPC_TOOLCHAIN not set');
|
||||
}
|
||||
$toolchain = getenv('SPC_TOOLCHAIN');
|
||||
if (!isset(self::TOOLCHAIN_LIST[$toolchain])) {
|
||||
throw new WrongUsageException("Unknown toolchain: {$toolchain}");
|
||||
}
|
||||
$toolchainClass = self::TOOLCHAIN_LIST[$toolchain];
|
||||
(new $toolchainClass())->afterInit(getenv('SPC_TARGET'));
|
||||
}
|
||||
}
|
||||
33
src/SPC/util/toolchain/ClangNativeToolchain.php
Normal file
33
src/SPC/util/toolchain/ClangNativeToolchain.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
use SPC\builder\freebsd\SystemUtil as FreeBSDSystemUtil;
|
||||
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class ClangNativeToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
{
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CC=clang');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=clang++');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld');
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
{
|
||||
// check clang exists
|
||||
match (PHP_OS_FAMILY) {
|
||||
'Linux' => LinuxSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or manually set CC/CXX to a valid path.'),
|
||||
'Darwin' => MacOSSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or set CC/CXX to a valid path.'),
|
||||
'BSD' => FreeBSDSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or set CC/CXX to a valid path.'),
|
||||
default => throw new WrongUsageException('Clang is not supported on ' . PHP_OS_FAMILY . '.'),
|
||||
};
|
||||
}
|
||||
}
|
||||
32
src/SPC/util/toolchain/GccNativeToolchain.php
Normal file
32
src/SPC/util/toolchain/GccNativeToolchain.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
use SPC\builder\freebsd\SystemUtil as FreeBSDSystemUtil;
|
||||
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class GccNativeToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
{
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CC=gcc');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=g++');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld.gold');
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
{
|
||||
// check gcc exists
|
||||
match (PHP_OS_FAMILY) {
|
||||
'Linux' => LinuxSystemUtil::findCommand('g++') ?? throw new \RuntimeException('g++ not found, please install it or set CC/CXX to a valid path.'),
|
||||
'Darwin' => MacOSSystemUtil::findCommand('g++') ?? throw new \RuntimeException('g++ not found, please install it or set CC/CXX to a valid path.'),
|
||||
'BSD' => FreeBSDSystemUtil::findCommand('g++') ?? throw new \RuntimeException('g++ not found, please install it or set CC/CXX to a valid path.'),
|
||||
default => throw new \RuntimeException('GCC is not supported on ' . PHP_OS_FAMILY . '.'),
|
||||
};
|
||||
}
|
||||
}
|
||||
12
src/SPC/util/toolchain/MSVCToolchain.php
Normal file
12
src/SPC/util/toolchain/MSVCToolchain.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
class MSVCToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void {}
|
||||
|
||||
public function afterInit(string $target): void {}
|
||||
}
|
||||
44
src/SPC/util/toolchain/MuslToolchain.php
Normal file
44
src/SPC/util/toolchain/MuslToolchain.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class MuslToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
{
|
||||
// Check if the target is musl-static (the musl(-shared) target is not supported yet)
|
||||
if (!in_array($target, [SPCTarget::MUSL_STATIC/* , SPCTarget::MUSL */], true)) {
|
||||
throw new WrongUsageException('MuslToolchain can only be used with the "musl-static" target.');
|
||||
}
|
||||
$arch = getenv('GNU_ARCH');
|
||||
// Set environment variables for musl toolchain
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_CC={$arch}-linux-musl-gcc");
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_CXX={$arch}-linux-musl-g++");
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_AR={$arch}-linux-musl-ar");
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LD={$arch}-linux-musl-ld");
|
||||
GlobalEnvManager::addPathIfNotExists('/usr/local/musl/bin');
|
||||
GlobalEnvManager::addPathIfNotExists("/usr/local/musl/{$arch}-linux-musl/bin");
|
||||
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LD_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
{
|
||||
$arch = getenv('GNU_ARCH');
|
||||
// append LD_LIBRARY_PATH to $configure = getenv('SPC_CMD_PREFIX_PHP_CONFIGURE');
|
||||
$configure = getenv('SPC_CMD_PREFIX_PHP_CONFIGURE');
|
||||
$ld_library_path = getenv('SPC_LINUX_DEFAULT_LD_LIBRARY_PATH');
|
||||
GlobalEnvManager::putenv("SPC_CMD_PREFIX_PHP_CONFIGURE=LD_LIBRARY_PATH=\"{$ld_library_path}\" {$configure}");
|
||||
|
||||
if (!file_exists("/usr/local/musl/{$arch}-linux-musl/lib/libc.a")) {
|
||||
throw new WrongUsageException('You are building with musl-libc target in glibc distro, but musl-toolchain is not installed, please install musl-toolchain first. (You can use `doctor` command to install it)');
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/SPC/util/toolchain/ToolchainInterface.php
Normal file
18
src/SPC/util/toolchain/ToolchainInterface.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
interface ToolchainInterface
|
||||
{
|
||||
/**
|
||||
* Initialize the environment for the given target.
|
||||
*/
|
||||
public function initEnv(string $target): void;
|
||||
|
||||
/**
|
||||
* Perform actions after the environment has been initialized for the given target.
|
||||
*/
|
||||
public function afterInit(string $target): void;
|
||||
}
|
||||
18
src/SPC/util/toolchain/ZigToolchain.php
Normal file
18
src/SPC/util/toolchain/ZigToolchain.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
class ZigToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
{
|
||||
// TODO: Implement zig
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
{
|
||||
// TODO: Implement afterInit() method.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user