diff --git a/src/SPC/builder/BuilderProvider.php b/src/SPC/builder/BuilderProvider.php index c9008ceb..4a19aef2 100644 --- a/src/SPC/builder/BuilderProvider.php +++ b/src/SPC/builder/BuilderProvider.php @@ -8,6 +8,7 @@ use SPC\builder\linux\LinuxBuilder; use SPC\builder\macos\MacOSBuilder; use SPC\builder\windows\WindowsBuilder; use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; use Symfony\Component\Console\Input\InputInterface; /** @@ -36,7 +37,7 @@ class BuilderProvider cxx: $input->getOption('cxx'), arch: $input->getOption('arch'), ), - default => throw new RuntimeException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'), + default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'), }; } } diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index f8902e27..8066447a 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -6,6 +6,7 @@ namespace SPC\builder; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; use SPC\store\Config; class Extension @@ -62,7 +63,7 @@ class Extension 'enable' => '--enable-' . $_name, 'with' => '--with-' . $_name, 'none', 'custom' => '', - default => throw new RuntimeException("argType does not accept {$arg_type}, use [enable/with] ."), + default => throw new WrongUsageException("argType does not accept {$arg_type}, use [enable/with] ."), }; } diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 94cb824a..b1e898cb 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -9,6 +9,7 @@ use SPC\builder\linux\library\LinuxLibraryBase; use SPC\builder\traits\UnixBuilderTrait; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; use SPC\util\Patcher; /** @@ -86,7 +87,7 @@ class LinuxBuilder extends BuilderBase } } if (!empty($missing)) { - throw new RuntimeException('missing system commands: ' . implode(', ', $missing)); + throw new WrongUsageException('missing system commands: ' . implode(', ', $missing)); } // 创立 pkg-config 和放头文件的目录 @@ -151,7 +152,7 @@ class LinuxBuilder extends BuilderBase } break; default: - throw new RuntimeException('libc ' . $this->libc . ' is not implemented yet'); + throw new WrongUsageException('libc ' . $this->libc . ' is not implemented yet'); } $envs = "{$envs} CFLAGS='{$cflags}' LIBS='-ldl -lpthread'"; diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index fe2f7d82..686e930e 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -7,6 +7,7 @@ namespace SPC\builder\linux; use JetBrains\PhpStorm\ArrayShape; use SPC\builder\traits\UnixSystemUtilTrait; use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; class SystemUtil { @@ -128,10 +129,10 @@ class SystemUtil 'clang' => match ($arch) { 'x86_64' => '--target=x86_64-unknown-linux', 'arm64', 'aarch64' => '--target=arm64-unknown-linux', - default => throw new RuntimeException('unsupported arch: ' . $arch), + default => throw new WrongUsageException('unsupported arch: ' . $arch), }, 'gcc' => '', - default => throw new RuntimeException('cc compiler ' . $cc . ' is not supported'), + default => throw new WrongUsageException('cc compiler ' . $cc . ' is not supported'), }; } diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index 33b1e939..b749c038 100644 --- a/src/SPC/builder/macos/MacOSBuilder.php +++ b/src/SPC/builder/macos/MacOSBuilder.php @@ -9,6 +9,7 @@ use SPC\builder\macos\library\MacOSLibraryBase; use SPC\builder\traits\UnixBuilderTrait; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; use SPC\util\Patcher; /** @@ -27,7 +28,11 @@ class MacOSBuilder extends BuilderBase private bool $phar_patched = false; /** + * @param null|string $cc C编译器名称,如果不传入则默认使用clang + * @param null|string $cxx C++编译器名称,如果不传入则默认使用clang++ + * @param null|string $arch 当前架构,如果不传入则默认使用当前系统架构 * @throws RuntimeException + * @throws WrongUsageException */ public function __construct(?string $cc = null, ?string $cxx = null, ?string $arch = null) { @@ -218,6 +223,7 @@ class MacOSBuilder extends BuilderBase if ($this->getExt('phar')) { $this->phar_patched = true; try { + // TODO: 未来改进一下 patch,让除了这种 patch 类型的文件以外可以恢复原文件 f_passthru('cd ' . SOURCE_PATH . '/php-src && patch -p1 < sapi/micro/patches/phar.patch'); } catch (RuntimeException $e) { logger()->error('failed to patch phat due to patch exit with code ' . $e->getCode()); @@ -257,6 +263,9 @@ class MacOSBuilder extends BuilderBase ); } + /** + * 获取当前即将编译的 PHP 的版本 ID,五位数那个 + */ public function getPHPVersionID(): int { $file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h'); diff --git a/src/SPC/builder/macos/SystemUtil.php b/src/SPC/builder/macos/SystemUtil.php index 0c156cd7..e810ae22 100644 --- a/src/SPC/builder/macos/SystemUtil.php +++ b/src/SPC/builder/macos/SystemUtil.php @@ -6,6 +6,7 @@ namespace SPC\builder\macos; use SPC\builder\traits\UnixSystemUtilTrait; use SPC\exception\RuntimeException; +use SPC\exception\WrongUsageException; class SystemUtil { @@ -30,14 +31,15 @@ class SystemUtil /** * 获取不同架构对应的 cflags 参数 * - * @throws RuntimeException + * @param string $arch 架构名称 + * @throws WrongUsageException */ public static function getArchCFlags(string $arch): string { return match ($arch) { 'x86_64' => '--target=x86_64-apple-darwin', 'arm64','aarch64' => '--target=arm64-apple-darwin', - default => throw new RuntimeException('unsupported arch: ' . $arch), + default => throw new WrongUsageException('unsupported arch: ' . $arch), }; } } diff --git a/src/SPC/builder/traits/UnixSystemUtilTrait.php b/src/SPC/builder/traits/UnixSystemUtilTrait.php index 1af617ee..6695f243 100644 --- a/src/SPC/builder/traits/UnixSystemUtilTrait.php +++ b/src/SPC/builder/traits/UnixSystemUtilTrait.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace SPC\builder\traits; +use SPC\store\FileSystem; + /** * Unix 系统的工具函数 Trait,适用于 Linux、macOS */ @@ -48,7 +50,7 @@ CMAKE; if (PHP_OS_FAMILY === 'Linux') { $toolchain .= "\nSET(CMAKE_AR \"ar\")"; } - file_put_contents(SOURCE_PATH . '/toolchain.cmake', $toolchain); + FileSystem::writeFile(SOURCE_PATH . '/toolchain.cmake', $toolchain); return realpath(SOURCE_PATH . '/toolchain.cmake'); } diff --git a/src/SPC/command/BuildCliCommand.php b/src/SPC/command/BuildCliCommand.php index b34340b8..f8dda3f4 100644 --- a/src/SPC/command/BuildCliCommand.php +++ b/src/SPC/command/BuildCliCommand.php @@ -6,6 +6,7 @@ namespace SPC\command; use SPC\builder\BuilderProvider; use SPC\exception\ExceptionHandler; +use SPC\exception\WrongUsageException; use SPC\util\DependencyUtil; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -73,6 +74,9 @@ class BuildCliCommand extends BuildCommand logger()->info('phpmicro binary path: ' . BUILD_ROOT_PATH . '/bin/micro.sfx'); } return 0; + } catch (WrongUsageException $e) { + logger()->critical($e->getMessage()); + return 1; } catch (\Throwable $e) { if ($input->getOption('debug')) { ExceptionHandler::getInstance()->handle($e); diff --git a/src/SPC/exception/WrongUsageException.php b/src/SPC/exception/WrongUsageException.php new file mode 100644 index 00000000..c03000da --- /dev/null +++ b/src/SPC/exception/WrongUsageException.php @@ -0,0 +1,9 @@ + ['-windows', '-win', ''], 'Darwin' => ['-macos', '-unix', ''], 'Linux' => ['-linux', '-unix', ''], - default => throw new RuntimeException('OS ' . PHP_OS_FAMILY . ' is not supported'), + default => throw new WrongUsageException('OS ' . PHP_OS_FAMILY . ' is not supported'), }; foreach ($m_key as $v) { if (isset(self::$lib[$name][$key . $v])) { @@ -83,6 +84,7 @@ class Config /** * @throws FileSystemException * @throws RuntimeException + * @throws WrongUsageException */ public static function getExt(string $name, ?string $key = null, mixed $default = null) { @@ -90,7 +92,7 @@ class Config self::$ext = FileSystem::loadConfigArray('ext'); } if (!isset(self::$ext[$name])) { - throw new RuntimeException('ext [' . $name . '] is not supported yet for get'); + throw new WrongUsageException('ext [' . $name . '] is not supported yet'); } $supported_sys_based = ['lib-depends', 'lib-suggests', 'ext-depends', 'ext-suggests', 'arg-type']; if ($key !== null && in_array($key, $supported_sys_based)) { @@ -98,7 +100,7 @@ class Config 'Windows' => ['-windows', '-win', ''], 'Darwin' => ['-macos', '-unix', ''], 'Linux' => ['-linux', '-unix', ''], - default => throw new RuntimeException('OS ' . PHP_OS_FAMILY . ' is not supported'), + default => throw new WrongUsageException('OS ' . PHP_OS_FAMILY . ' is not supported'), }; foreach ($m_key as $v) { if (isset(self::$ext[$name][$key . $v])) { diff --git a/src/SPC/store/FileSystem.php b/src/SPC/store/FileSystem.php index bed41b4e..24bdf0b3 100644 --- a/src/SPC/store/FileSystem.php +++ b/src/SPC/store/FileSystem.php @@ -385,4 +385,13 @@ class FileSystem throw new FileSystemException(sprintf('无法建立目录:%s', $path)); } } + + public static function writeFile(string $path, $content, ...$args): bool|string|int + { + $dir = pathinfo($path, PATHINFO_DIRNAME); + if (!is_dir($dir) && !mkdir($dir, 0755, true)) { + throw new FileSystemException('Write file failed, cannot create parent directory: ' . $dir); + } + return file_put_contents($path, $content, ...$args); + } } diff --git a/src/SPC/util/Patcher.php b/src/SPC/util/Patcher.php index 736114ad..d6307397 100644 --- a/src/SPC/util/Patcher.php +++ b/src/SPC/util/Patcher.php @@ -196,7 +196,7 @@ class Patcher case 'x86_64': break; default: - throw new RuntimeException('unsupported arch: ' . $builder->arch); + throw new RuntimeException('unsupported arch while patching php configure: ' . $builder->arch); } } } diff --git a/src/globals/functions.php b/src/globals/functions.php index a839443d..ddf22369 100644 --- a/src/globals/functions.php +++ b/src/globals/functions.php @@ -3,11 +3,13 @@ declare(strict_types=1); use Psr\Log\LoggerInterface; +use SPC\exception\WrongUsageException; use SPC\util\UnixShell; use ZM\Logger\ConsoleLogger; /** * 判断传入的数组是否为关联数组 + * * @param mixed $array */ function is_assoc_array($array): bool @@ -28,7 +30,8 @@ function logger(): LoggerInterface } /** - * @throws \SPC\exception\RuntimeException + * @param string $arch 架构名称转换为 GNU 标准形式 + * @throws WrongUsageException */ function arch2gnu(string $arch): string { @@ -36,7 +39,7 @@ function arch2gnu(string $arch): string return match ($arch) { 'x86_64', 'x64', 'amd64' => 'x86_64', 'arm64', 'aarch64' => 'aarch64', - default => throw new \SPC\exception\RuntimeException('Not support arch: ' . $arch), + default => throw new WrongUsageException('Not support arch: ' . $arch), // 'armv7' => 'arm', }; } @@ -46,6 +49,11 @@ function quote(string $str, string $quote = '"'): string return $quote . $str . $quote; } +/** + * 将不同系统环境的编译使用工具集的文件夹名称进行一个返回 + * + * @throws WrongUsageException + */ function osfamily2dir(): string { return match (PHP_OS_FAMILY) { @@ -53,7 +61,7 @@ function osfamily2dir(): string 'Windows', 'WINNT', 'Cygwin' => 'windows', 'Darwin' => 'macos', 'Linux' => 'linux', - default => throw new \SPC\exception\RuntimeException('Not support os: ' . PHP_OS_FAMILY), + default => throw new WrongUsageException('Not support os: ' . PHP_OS_FAMILY), }; }