mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-09 18:05:36 +08:00
Compare commits
11 Commits
270e2d6471
...
db794bf27b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db794bf27b | ||
|
|
b880ef7003 | ||
|
|
9addbe2c7d | ||
|
|
445c0b36c9 | ||
|
|
4754faf43e | ||
|
|
2415b7db35 | ||
|
|
814014e122 | ||
|
|
defd50f459 | ||
|
|
57ef0423d5 | ||
|
|
8453f69eea | ||
|
|
c1c34d8c10 |
@@ -39,7 +39,7 @@ class curl
|
||||
->optionalPackage('zstd', ...cmake_boolean_args('CURL_ZSTD'))
|
||||
->optionalPackage('brotli', ...cmake_boolean_args('CURL_BROTLI'))
|
||||
->addConfigureArgs(
|
||||
'-DBUILD_CURL_EXE=OFF',
|
||||
'-DBUILD_CURL_EXE=ON',
|
||||
'-DZSTD_LIBRARY=zstd_static.lib',
|
||||
'-DBUILD_TESTING=OFF',
|
||||
'-DBUILD_EXAMPLES=OFF',
|
||||
|
||||
@@ -20,6 +20,7 @@ use StaticPHP\Package\PhpExtensionPackage;
|
||||
use StaticPHP\Package\TargetPackage;
|
||||
use StaticPHP\Runtime\SystemTarget;
|
||||
use StaticPHP\Toolchain\Interface\ToolchainInterface;
|
||||
use StaticPHP\Toolchain\ToolchainManager;
|
||||
use StaticPHP\Toolchain\ZigToolchain;
|
||||
use StaticPHP\Util\DirDiff;
|
||||
use StaticPHP\Util\FileSystem;
|
||||
@@ -92,12 +93,10 @@ trait unix
|
||||
$args = [];
|
||||
$version_id = self::getPHPVersionID();
|
||||
|
||||
// disable undefined behavior sanitizer when opcache JIT is enabled (Linux only)
|
||||
if (SystemTarget::getTargetOS() === 'Linux' && !$package->getBuildOption('disable-opcache-jit', false)) {
|
||||
if ($version_id >= 80500 || $installer->isPackageResolved('ext-opcache')) {
|
||||
$compiler_extra = getenv('SPC_COMPILER_EXTRA') ?: '';
|
||||
GlobalEnvManager::putenv('SPC_COMPILER_EXTRA=' . trim($compiler_extra . ' -fno-sanitize=undefined'));
|
||||
}
|
||||
// disable undefined behavior sanitizer for zig, trips up on lua minijit and opcache-jit
|
||||
if (SystemTarget::getTargetOS() === 'Linux' && ToolchainManager::getToolchainClass() === ZigToolchain::class) {
|
||||
$compiler_extra = getenv('SPC_COMPILER_EXTRA') ?: '';
|
||||
GlobalEnvManager::putenv('SPC_COMPILER_EXTRA=' . trim($compiler_extra . ' -fno-sanitize=undefined'));
|
||||
}
|
||||
// PHP JSON extension is built-in since PHP 8.0
|
||||
if ($version_id < 80000) {
|
||||
@@ -168,7 +167,7 @@ trait unix
|
||||
|
||||
#[BeforeStage('php', [self::class, 'makeForUnix'], 'php')]
|
||||
#[PatchDescription('Patch Makefile to fix //lib path for Linux builds')]
|
||||
#[PatchDescription('Patch BUILD_CC to use system cc instead of zig-cc (prevents minilua crash)')]
|
||||
#[PatchDescription('Under CI: patch BUILD_CC to system cc — zig-cc-built minilua segfaults there for reasons we cannot reproduce locally')]
|
||||
public function tryPatchMakefileUnix(TargetPackage $package, ToolchainInterface $toolchain): void
|
||||
{
|
||||
if (SystemTarget::getTargetOS() !== 'Linux') {
|
||||
@@ -178,7 +177,8 @@ trait unix
|
||||
// replace //lib with /lib in Makefile
|
||||
shell()->cd($package->getSourceDir())->exec('sed -i "s|//lib|/lib|g" Makefile');
|
||||
|
||||
if ($toolchain instanceof ZigToolchain) {
|
||||
// CI escape hatch: in CI, zig-cc-built minilua segfaults
|
||||
if ($toolchain instanceof ZigToolchain && getenv('CI')) {
|
||||
$makefile = "{$package->getSourceDir()}/Makefile";
|
||||
FileSystem::replaceFileRegex($makefile, '/^BUILD_CC\s*=\s*zig-cc\s*$/m', 'BUILD_CC = cc');
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ class CraftCommand extends BaseCommand
|
||||
// apply env
|
||||
array_walk($craft['extra-env'], fn ($v, $k) => f_putenv("{$k}={$v}"));
|
||||
|
||||
// stash craft for doctor checks that depend on what's being built (e.g. frankenphp → go-xcaddy)
|
||||
ApplicationContext::set('craft', $craft);
|
||||
|
||||
// run doctor
|
||||
if ($craft['craft-options']['doctor']) {
|
||||
$doctor = new Doctor($this->output, FIX_POLICY_AUTOFIX);
|
||||
|
||||
44
src/StaticPHP/Doctor/Item/GoXcaddyCheck.php
Normal file
44
src/StaticPHP/Doctor/Item/GoXcaddyCheck.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace StaticPHP\Doctor\Item;
|
||||
|
||||
use StaticPHP\Attribute\Doctor\CheckItem;
|
||||
use StaticPHP\Attribute\Doctor\FixItem;
|
||||
use StaticPHP\Attribute\Doctor\OptionalCheck;
|
||||
use StaticPHP\DI\ApplicationContext;
|
||||
use StaticPHP\Doctor\CheckResult;
|
||||
use StaticPHP\Package\PackageInstaller;
|
||||
|
||||
#[OptionalCheck([self::class, 'optionalCheck'])]
|
||||
class GoXcaddyCheck
|
||||
{
|
||||
public static function optionalCheck(): bool
|
||||
{
|
||||
if (!ApplicationContext::has('craft')) {
|
||||
return false;
|
||||
}
|
||||
/** @var null|array $craft */
|
||||
$craft = ApplicationContext::get('craft');
|
||||
return in_array('frankenphp', $craft['sapi'] ?? [], true);
|
||||
}
|
||||
|
||||
#[CheckItem('if go-xcaddy is installed', level: 800)]
|
||||
public function check(): CheckResult
|
||||
{
|
||||
if (!new PackageInstaller()->addInstallPackage('go-xcaddy')->isPackageInstalled('go-xcaddy')) {
|
||||
return CheckResult::fail('go-xcaddy is not installed', 'install-go-xcaddy');
|
||||
}
|
||||
return CheckResult::ok(PKG_ROOT_PATH . '/go-xcaddy/bin/xcaddy');
|
||||
}
|
||||
|
||||
#[FixItem('install-go-xcaddy')]
|
||||
public function installGoXcaddy(): bool
|
||||
{
|
||||
$installer = new PackageInstaller(interactive: false);
|
||||
$installer->addInstallPackage('go-xcaddy');
|
||||
$installer->run(true);
|
||||
return $installer->isPackageInstalled('go-xcaddy');
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class ZigCheck
|
||||
public function checkZig(): CheckResult
|
||||
{
|
||||
if (new PackageInstaller()->addInstallPackage('zig')->isPackageInstalled('zig')) {
|
||||
return CheckResult::ok();
|
||||
return CheckResult::ok(PKG_ROOT_PATH . '/zig/zig');
|
||||
}
|
||||
return CheckResult::fail('zig is not installed', 'install-zig');
|
||||
}
|
||||
|
||||
@@ -367,9 +367,12 @@ class PackageLoader
|
||||
|
||||
public static function getBeforeStageCallbacks(string $package_name, string $stage): iterable
|
||||
{
|
||||
// match condition
|
||||
// match condition; '*' is a wildcard that fires for every package's stage
|
||||
$installer = ApplicationContext::get(PackageInstaller::class);
|
||||
$stages = self::$before_stages[$package_name][$stage] ?? [];
|
||||
$stages = array_merge(
|
||||
self::$before_stages[$package_name][$stage] ?? [],
|
||||
$package_name === '*' ? [] : (self::$before_stages['*'][$stage] ?? []),
|
||||
);
|
||||
foreach ($stages as [$callback, $only_when_package_resolved, $conditionals]) {
|
||||
if ($only_when_package_resolved !== null && !$installer->isPackageResolved($only_when_package_resolved)) {
|
||||
continue;
|
||||
@@ -385,9 +388,12 @@ class PackageLoader
|
||||
|
||||
public static function getAfterStageCallbacks(string $package_name, string $stage): array
|
||||
{
|
||||
// match condition
|
||||
// match condition; '*' is a wildcard that fires for every package's stage
|
||||
$installer = ApplicationContext::get(PackageInstaller::class);
|
||||
$stages = self::$after_stages[$package_name][$stage] ?? [];
|
||||
$stages = array_merge(
|
||||
self::$after_stages[$package_name][$stage] ?? [],
|
||||
$package_name === '*' ? [] : (self::$after_stages['*'][$stage] ?? []),
|
||||
);
|
||||
$result = [];
|
||||
foreach ($stages as [$callback, $only_when_package_resolved, $conditionals]) {
|
||||
if ($only_when_package_resolved !== null && !$installer->isPackageResolved($only_when_package_resolved)) {
|
||||
@@ -425,6 +431,20 @@ class PackageLoader
|
||||
{
|
||||
foreach (['BeforeStage' => self::$before_stages, 'AfterStage' => self::$after_stages] as $event_name => $ev_all) {
|
||||
foreach ($ev_all as $package_name => $stages) {
|
||||
// wildcard hooks fire for every package's stage; nothing to validate against
|
||||
if ($package_name === '*') {
|
||||
foreach ($stages as $stage_name => $before_events) {
|
||||
foreach ($before_events as [$event_callable, $only_when_package_resolved, $conditionals]) {
|
||||
if ($only_when_package_resolved !== null && !self::hasPackage($only_when_package_resolved)) {
|
||||
throw new RegistryException("{$event_name} event for wildcard [*] stage [{$stage_name}] has unknown only_when_package_resolved package [{$only_when_package_resolved}].");
|
||||
}
|
||||
if (!is_callable($event_callable)) {
|
||||
throw new RegistryException("{$event_name} event for wildcard [*] stage [{$stage_name}] has invalid callable.");
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// check package exists
|
||||
if (!self::hasPackage($package_name)) {
|
||||
throw new RegistryException(
|
||||
|
||||
@@ -98,8 +98,10 @@ class Registry
|
||||
if (file_exists($autoload_path)) {
|
||||
logger()->debug("Loading external autoload from: {$autoload_path}");
|
||||
require_once $autoload_path;
|
||||
} elseif (str_contains(rtrim(FileSystem::convertPath($base), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR)) {
|
||||
logger()->debug("Registry autoload not present, relying on consumer autoloader: {$autoload_path}");
|
||||
} else {
|
||||
logger()->warning("Registry autoload not present, relying on consumer autoloader: {$autoload_path}");
|
||||
throw new RegistryException("Path does not exist: {$autoload_path}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user