mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
zig toolchain stuff
This commit is contained in:
parent
5370af4a84
commit
0a33fba23e
@ -65,21 +65,23 @@ UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe"
|
||||
SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static
|
||||
|
||||
[linux]
|
||||
; Linux can use different build toolchain, but the toolchain can not be changed in this file:
|
||||
; - musl (default): used for general linux distros, can build `musl-static` target only.
|
||||
; - zig (WIP): used for general linux distros, can build `musl` and `glibc` targets.
|
||||
; - musl-native: used for alpine linux, can build `musl-static` and `musl`(WIP) target.
|
||||
; - gnu-native (assume): used for general linux distros, can build `glibc` target only and have portability issues.
|
||||
; Linux can use different build toolchains.
|
||||
; - musl (default, when SPC_LIBC=musl): used for general linux distros, can build `musl` (statically linked) only.
|
||||
; - zig (will become default): usable on all Linux distros, can build `-musl`, `arch-linux-musl -dynamic` and `arch-linux-gnu` targets. Can specify version such as `x86_64-linux-gnu.2.17`.
|
||||
; - musl-native: used for alpine linux, can build `musl` and `musl -dynamic` target.
|
||||
; - gnu-native: used for general linux distros, can build gnu target for the installed glibc version only.
|
||||
|
||||
; build target:
|
||||
; - musl-static (default): pure static linking, using musl-libc, can run on any linux distro.
|
||||
; - musl: static linking with dynamic linking to musl-libc, can run on musl-based linux distro.
|
||||
; - glibc: static linking with dynamic linking to glibc, can run on glibc-based linux distro.
|
||||
|
||||
; include PATH for musl libc.
|
||||
; LEGACY option to specify the target, switch to SPC_TARGET with zig toolchain instead
|
||||
SPC_LIBC=musl
|
||||
SPC_LIBC_VERSION=
|
||||
SPC_LIBC_LINKAGE=-static
|
||||
|
||||
; Recommended: specify your target here. Zig toolchain will be used.
|
||||
; examples:
|
||||
; `native-native-gnu` - links against glibc, version 2.17
|
||||
; `native-native-gnu.2.17` - links against glibc, version 2.17
|
||||
; `native-native` - static linking against musl
|
||||
; `native-native-musl -dynamic` - links against musl libc
|
||||
; SPC_TARGET=
|
||||
|
||||
; compiler environments
|
||||
CC=${SPC_LINUX_DEFAULT_CC}
|
||||
CXX=${SPC_LINUX_DEFAULT_CXX}
|
||||
|
||||
@ -82,7 +82,7 @@ and this extension cannot be compiled into php by static linking, so it cannot b
|
||||
|
||||
## xdebug
|
||||
|
||||
1. Xdebug is only buildable as a shared extension. You need to use a build target other than `musl-static` for SPC_TARGET.
|
||||
1. Xdebug is only buildable as a shared extension. On Linux, you'll need to use a SPC_TARGET like `native-native -dynamic` or `native-native-gnu`.
|
||||
2. When using Linux/glibc or macOS, you can compile Xdebug as a shared extension using --build-shared="xdebug".
|
||||
The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`.
|
||||
|
||||
|
||||
@ -10,6 +10,8 @@ use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class LinuxBuilder extends UnixBuilderBase
|
||||
@ -66,7 +68,7 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
}
|
||||
// add libstdc++, some extensions or libraries need it
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : '');
|
||||
$extra_libs .= (SystemUtil::getCCType() === 'clang' ? ' -lunwind' : '');
|
||||
$extra_libs .= (ToolchainManager::getToolchainClass() === ZigToolchain::class ? ' -lunwind' : '');
|
||||
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
|
||||
$cflags = $this->arch_c_flags;
|
||||
f_putenv('CFLAGS=' . $cflags);
|
||||
|
||||
@ -33,10 +33,10 @@ trait libxslt
|
||||
'--without-debugger',
|
||||
"--with-libxml-prefix={$this->getBuildRootPath()}",
|
||||
);
|
||||
if (getenv('SPC_LINUX_DEFAULT_LD_LIBRARY_PATH') && getenv('SPC_LINUX_DEFAULT_LIBRARY_PATH')) {
|
||||
if (getenv('SPC_LD_LIBRARY_PATH') && getenv('SPC_LIBRARY_PATH')) {
|
||||
$ac->appendEnv([
|
||||
'LD_LIBRARY_PATH' => getenv('SPC_LINUX_DEFAULT_LD_LIBRARY_PATH'),
|
||||
'LIBRARY_PATH' => getenv('SPC_LINUX_DEFAULT_LIBRARY_PATH'),
|
||||
'LD_LIBRARY_PATH' => getenv('SPC_LD_LIBRARY_PATH'),
|
||||
'LIBRARY_PATH' => getenv('SPC_LIBRARY_PATH'),
|
||||
]);
|
||||
}
|
||||
$ac->configure()->make();
|
||||
|
||||
59
src/SPC/doctor/item/ZigCheck.php
Normal file
59
src/SPC/doctor/item/ZigCheck.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\doctor\item;
|
||||
|
||||
use SPC\doctor\AsCheckItem;
|
||||
use SPC\doctor\AsFixItem;
|
||||
use SPC\doctor\CheckResult;
|
||||
use SPC\doctor\OptionalCheck;
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\PackageManager;
|
||||
use SPC\store\pkg\Zig;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\toolchain\MuslToolchain;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
|
||||
#[OptionalCheck([self::class, 'optionalCheck'])]
|
||||
class ZigCheck
|
||||
{
|
||||
public static function optionalCheck(): bool
|
||||
{
|
||||
return getenv('SPC_TOOLCHAIN') === ZigToolchain::class;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
#[AsCheckItem('if zig is installed', level: 800)]
|
||||
public function checkZig(): CheckResult
|
||||
{
|
||||
if (Zig::isInstalled()) {
|
||||
return CheckResult::ok();
|
||||
}
|
||||
return CheckResult::fail('zig is not installed', 'install-zig');
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
#[AsFixItem('install-zig')]
|
||||
public function fixMuslCrossMake(): bool
|
||||
{
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => 'linux',
|
||||
};
|
||||
PackageManager::installPackage("musl-toolchain-{$arch}-{$os}");
|
||||
return Zig::isInstalled();
|
||||
}
|
||||
}
|
||||
@ -13,4 +13,6 @@ abstract class CustomPackage
|
||||
abstract public function extract(string $name): void;
|
||||
|
||||
abstract public static function getEnvironment(): array;
|
||||
|
||||
abstract public static function isInstalled(): bool;
|
||||
}
|
||||
|
||||
@ -11,6 +11,27 @@ use SPC\store\LockFile;
|
||||
|
||||
class Zig extends CustomPackage
|
||||
{
|
||||
private static function getPath(): string
|
||||
{
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Linux' => 'linux',
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => 'linux',
|
||||
};
|
||||
|
||||
$packageName = "zig-{$arch}-{$os}";
|
||||
return PKG_ROOT_PATH . "/{$packageName}";
|
||||
}
|
||||
|
||||
public static function isInstalled(): bool
|
||||
{
|
||||
$path = self::getPath();
|
||||
return file_exists("$path/zig") && file_exists("$path/zig-cc") && file_exists("$path/zig-c++");
|
||||
}
|
||||
|
||||
public function getSupportName(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@ -20,8 +20,8 @@ class MuslToolchain implements ToolchainInterface
|
||||
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");
|
||||
GlobalEnvManager::putenv("SPC_LD_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
GlobalEnvManager::putenv("SPC_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
}
|
||||
|
||||
public function afterInit(): void
|
||||
@ -29,7 +29,7 @@ class MuslToolchain implements ToolchainInterface
|
||||
$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');
|
||||
$ld_library_path = getenv('SPC_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")) {
|
||||
|
||||
@ -11,33 +11,36 @@ use SPC\util\GlobalEnvManager;
|
||||
class ToolchainManager
|
||||
{
|
||||
public const array OS_DEFAULT_TOOLCHAIN = [
|
||||
'Linux' => MuslToolchain::class, // use musl toolchain by default, after zig pr merged, change this to ZigToolchain::class
|
||||
'Linux' => ZigToolchain::class,
|
||||
'Windows' => MSVCToolchain::class,
|
||||
'Darwin' => ClangNativeToolchain::class,
|
||||
'BSD' => ClangNativeToolchain::class,
|
||||
];
|
||||
|
||||
public static function getToolchainClass(): string
|
||||
{
|
||||
$libc = getenv('SPC_LIBC');
|
||||
if ($libc !== false) {
|
||||
logger()->warning('SPC_LIBC is deprecated, please use SPC_TARGET instead.');
|
||||
return match ($libc) {
|
||||
'musl' => SystemUtil::isMuslDist() ? GccNativeToolchain::class : MuslToolchain::class,
|
||||
'glibc' => !SystemUtil::isMuslDist() ? GccNativeToolchain::class : throw new WrongUsageException('SPC_TARGET must be musl for musl dist.'),
|
||||
default => throw new WrongUsageException('Unsupported SPC_LIBC value: ' . $libc),
|
||||
};
|
||||
}
|
||||
|
||||
return self::OS_DEFAULT_TOOLCHAIN[PHP_OS_FAMILY];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function initToolchain(): void
|
||||
{
|
||||
$libc = getenv('SPC_LIBC');
|
||||
if ($libc !== false) {
|
||||
// uncomment this when zig pr is merged
|
||||
// logger()->warning('SPC_LIBC is deprecated, please use SPC_TARGET instead.');
|
||||
$toolchain = match ($libc) {
|
||||
'musl' => SystemUtil::isMuslDist() ? GccNativeToolchain::class : MuslToolchain::class,
|
||||
'glibc' => !SystemUtil::isMuslDist() ? GccNativeToolchain::class : throw new WrongUsageException('SPC_TARGET must be musl-static or musl for musl dist.'),
|
||||
default => throw new WrongUsageException('Unsupported SPC_LIBC value: ' . $libc),
|
||||
};
|
||||
} else {
|
||||
$toolchain = self::OS_DEFAULT_TOOLCHAIN[PHP_OS_FAMILY];
|
||||
}
|
||||
$toolchainClass = $toolchain;
|
||||
$toolchainClass = self::getToolchainClass();
|
||||
/* @var ToolchainInterface $toolchainClass */
|
||||
(new $toolchainClass())->initEnv();
|
||||
GlobalEnvManager::putenv("SPC_TOOLCHAIN={$toolchain}");
|
||||
GlobalEnvManager::putenv("SPC_TOOLCHAIN={$toolchainClass}");
|
||||
}
|
||||
|
||||
public static function afterInitToolchain(): void
|
||||
|
||||
@ -4,9 +4,31 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\toolchain;
|
||||
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\pkg\Zig;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class ZigToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(): void {}
|
||||
public function initEnv(): void
|
||||
{
|
||||
$arch = getenv('GNU_ARCH');
|
||||
// Set environment variables for musl toolchain
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_CC=zig-cc");
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_CXX=zig-c++");
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_AR=ar");
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LD=ld");
|
||||
GlobalEnvManager::addPathIfNotExists('/usr/local/musl/bin');
|
||||
GlobalEnvManager::addPathIfNotExists("/usr/local/musl/{$arch}-linux-musl/bin");
|
||||
|
||||
public function afterInit(): void {}
|
||||
GlobalEnvManager::putenv("SPC_LD_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
GlobalEnvManager::putenv("SPC_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
}
|
||||
|
||||
public function afterInit(): void
|
||||
{
|
||||
if (!is_dir(Zig::getEnvironment()['PATH'])) {
|
||||
throw new WrongUsageException('You are building with zig, but zig is not installed, please install zig first. (You can use `doctor` command to install it)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user