diff --git a/README-zh.md b/README-zh.md
index b159a5c3..d8d1b396 100755
--- a/README-zh.md
+++ b/README-zh.md
@@ -5,310 +5,168 @@
[](https://github.com/crazywhalecc/static-php-cli/releases)
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
-[](https://static-php.dev/zh/guide/extensions.html)
-**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。
-
-目前 static-php-cli 支持 `cli`、`fpm`、`embed`、`micro` 和 `frankenphp` SAPI。
-
-**static-php-cli**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。
+**static-php-cli** 是一个用于构建静态、独立 PHP 运行时的强大工具,支持众多流行扩展。
## 特性
-static-php-cli(简称 `spc`)有许多特性:
+- :elephant: **支持多 PHP 版本** - 支持 PHP 8.1, 8.2, 8.3, 8.4, 8.5
+- :handbag: **单文件 PHP 可执行文件** - 构建零依赖的独立 PHP
+- :hamburger: **phpmicro 集成** - 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自解压可执行文件(将 PHP 二进制文件和源代码合并为一个文件)
+- :pill: **智能环境检查器** - 自动构建环境检查器,具备自动修复功能
+- :zap: **跨平台支持** - 支持 Linux、macOS、FreeBSD 和 Windows
+- :wrench: **可配置补丁** - 可自定义的源代码补丁系统
+- :books: **智能依赖管理** - 自动处理构建依赖
+- 📦 **自包含工具** - 提供使用 [box](https://github.com/box-project/box) 构建的 `spc` 可执行文件
+- :fire: **广泛的扩展支持** - 支持 75+ 流行 [扩展](https://static-php.dev/zh/guide/extensions.html)
+- :floppy_disk: **UPX 压缩** - 减小二进制文件大小 30-50%(仅 Linux/Windows)
-- :handbag: 构建独立的单文件 PHP 解释器,无需任何依赖
-- :hamburger: 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自执行二进制(将 PHP 代码和 PHP 解释器打包为一个文件)
-- :pill: 提供一键检查和修复编译环境的 Doctor 模块
-- :zap: 支持多个系统:`Linux`、`macOS`、`FreeBSD`、`Windows`
-- :wrench: 高度自定义的代码 patch 功能
-- :books: 自带编译依赖管理
-- 📦 提供由自身编译的独立 `spc` 二进制(使用 spc 和 [box](https://github.com/box-project/box) 构建)
-- :fire: 支持大量 [扩展](https://static-php.dev/zh/guide/extensions.html)
-- :floppy_disk: 整合 UPX 工具(减小二进制文件体积)
-
-**静态 php-cli:**
+**单文件独立 php-cli:**
-**使用 phpmicro 打包 PHP 代码:**
+**使用 phpmicro 将 PHP 代码与 PHP 解释器结合:**
-## 文档
+## 快速开始
-目前 README 编写了基本用法。有关 static-php-cli 所有的功能,请点击这里查看文档:。
-
-## 直接下载
-
-如果你不想自行编译 PHP,可以从本项目现有的示例 Action 下载 Artifact,也可以从自托管的服务器下载。
-
-| 组合名称 | 组合扩展数 | 系统 | 备注 |
-|---------------------------------------------------------------------|----------------------------------------------------------------------------|-------------|--------------|
-| [common](https://dl.static-php.dev/static-php-cli/common/) | [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) | Linux/macOS | 体积为 7.5MB 左右 |
-| [bulk](https://dl.static-php.dev/static-php-cli/bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux/macOS | 体积为 25MB 左右 |
-| [minimal](https://dl.static-php.dev/static-php-cli/minimal/) | [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) | Linux/macOS | 体积为 3MB 左右 |
-| [spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min) | [5](https://dl.static-php.dev/static-php-cli/windows/spc-min/README.txt) | Windows | 体积为 3MB 左右 |
-| [spc-max](https://dl.static-php.dev/static-php-cli/windows/spc-max) | [40+](https://dl.static-php.dev/static-php-cli/windows/spc-max/README.txt) | Windows | 体积为 8.5MB 左右 |
-
-> Linux 和 Windows 默认启用了 UPX 压缩,可减小 30~50% 的 PHP 二进制体积。
-> macOS 当前不支持 UPX,所以上述预编译的 macOS 版本体积可能较大。
-
-## 使用 static-php-cli 构建 PHP
-
-### 编译环境需求
-
-- PHP >= 8.4(这是 spc 自身需要的版本,不是支持的构建版本)
-- 扩展:`mbstring,tokenizer,phar`
-- 系统安装了 `curl` 和 `git`
-
-是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
-但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含上面提到的扩展和 PHP 版本大于等于 8.1 即可。
-
-下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
-
-| | x86_64 | aarch64 |
-|---------|----------------------|----------------------|
-| macOS | :octocat: :computer: | :octocat: :computer: |
-| Linux | :octocat: :computer: | :octocat: :computer: |
-| Windows | :octocat: :computer: | |
-| FreeBSD | :computer: | :computer: |
-
-当前支持编译的 PHP 版本:
-
-> :warning: 部分支持,对于新的测试版和旧版本可能存在问题。
->
-> :heavy_check_mark: 支持
->
-> :x: 不支持
-
-| PHP Version | Status | Comment |
-|-------------|--------------------|---------------------------------------------------------|
-| 7.2 | :x: | |
-| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
-| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
-| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
-| 8.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新,在 8.5 发布后我们不再处理 8.1 相关的 backport 支持 |
-| 8.2 | :heavy_check_mark: | |
-| 8.3 | :heavy_check_mark: | |
-| 8.4 | :heavy_check_mark: | |
-| 8.5 (alpha) | :warning: | PHP 8.5 目前处于 alpha 阶段 |
-
-> 这个表格的支持状态是 static-php-cli 对构建对应版本的支持情况,不是 PHP 官方对该版本的支持情况。
-
-### 支持的扩展
-
-请先根据下方扩展列表选择你要编译的扩展。
-
-- [扩展支持列表](https://static-php.dev/zh/guide/extensions.html)
-- [编译命令生成器](https://static-php.dev/zh/guide/cli-generator.html)
-
-> 如果这里没有你需要的扩展,可以提交 Issue。
-
-### 在线构建(使用 GitHub Actions)
-
-使用 GitHub Action 可以方便地构建一个静态编译的 PHP,同时可以自行定义要编译的扩展。
-
-1. Fork 本项目。
-2. 进入项目的 Actions,选择 CI。
-3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`)
-4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`。
-
-如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
-
-### 本地构建(使用 spc 二进制,推荐)
-
-该项目提供了 static-php-cli 的二进制文件:`spc`。
-您可以使用 `spc` 二进制文件,无需安装任何运行时(用起来就像 golang 程序)。
-目前,`spc` 二进制文件提供的平台有 Linux 和 macOS。
-
-使用以下命令从自托管服务器下载:
+### 1. 下载 spc 二进制文件
```bash
-# Download from self-hosted nightly builds (sync with main branch)
-# For Linux x86_64
+# Linux x86_64
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
-# For Linux aarch64
+# Linux aarch64
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
-# Windows (x86_64, win10 build 17063 or later)
+# Windows (x86_64, win10 build 17063 或更高版本,请先安装 VS2022)
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
+```
-# Add execute perm (Linux and macOS only)
+对于 macOS 和 Linux,请先添加执行权限:
+
+```bash
chmod +x ./spc
-
-# Run (Linux and macOS)
-./spc --version
-# Run (Windows powershell)
-.\spc.exe --version
```
-自托管 `spc` 由 GitHub Actions 构建,你也可以从 Actions 直接下载:[此处](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml)。
+### 2. 构建静态 PHP
-### 本地构建(使用 git 源码)
+首先,创建一个 `craft.yml` 文件,并从 [扩展列表](https://static-php.dev/zh/guide/extensions.html) 或 [命令生成器](https://static-php.dev/zh/guide/cli-generator.html) 中指定要包含的扩展:
-如果你需要修改 static-php-cli 源码,或者使用 spc 二进制构建有问题,你可以使用 git 源码下载 static-php-cli。
+```yml
+# PHP 版本支持:8.1, 8.2, 8.3, 8.4, 8.5
+php-version: 8.4
+# 在此处放置您的扩展列表
+extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
+sapi:
+ - cli
+ - micro
+ - fpm
+download-options:
+ prefer-pre-built: true
+```
+
+运行命令:
```bash
-# clone 仓库即可
-git clone https://github.com/crazywhalecc/static-php-cli.git
+./spc craft
+
+# 输出完整控制台日志
+./spc craft --debug
```
-如果您的系统上尚未安装 php,我们建议你使用内置的 setup-runtime 自动安装 PHP 和 Composer。
+### 3. 静态 PHP 使用
-```bash
-cd static-php-cli
-chmod +x bin/setup-runtime
-# it will download static php (from self-hosted server) and composer (from getcomposer)
-bin/setup-runtime
-# initialize composer deps
-bin/composer install
-# chmod
-chmod +x bin/spc
-bin/spc --version
+现在您可以将 static-php-cli 构建的二进制文件复制到另一台机器上,无需依赖即可运行:
+
+```
+# php-cli
+buildroot/bin/php -v
+
+# phpmicro
+echo ' a.php
+./spc micro:combine a.php -O my-app
+./my-app
+
+# php-fpm
+buildroot/bin/php-fpm -v
```
-### 开始构建 PHP
+## 文档
-下面是使用 static-php-cli 的基础用法:
+当前 README 包含基本用法。有关 static-php-cli 的所有功能,
+请访问 。
-> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `./bin/spc` 替换为 `./spc`。
+## 直接下载
-```bash
-# 检查环境依赖,并根据尝试自动安装缺失的编译工具
-./bin/spc doctor --auto-fix
+如果您不想构建或想先测试,可以从 [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml) 下载示例预编译工件,或从自托管服务器下载。
-# 输出目标项目依赖的扩展列表
-./bin/spc dump-extensions /path/to/your/project --format=text
+以下是几个具有不同扩展组合的预编译静态 PHP 二进制文件,
+您可以根据需要直接下载。
-# 拉取所有依赖库
-./bin/spc download --all
-# 只拉取编译指定扩展需要的所有依赖(推荐)
-./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
-# 下载依赖时,优先下载有预编译的库(节省编译依赖的时间)
-./bin/spc download --for-extensions="openssl,curl,mbstring,mbregex" --prefer-pre-built
-# 下载编译不同版本的 PHP (--with-php=x.y 或 --with-php=x.y.z,推荐 8.1 ~ 8.3)
-./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
+| 组合名称 | 扩展数量 | 系统 | 备注 |
+|----------------------------------------------------------------------|----------------------------------------------------------------------------|--------------|--------------------|
+| [common](https://dl.static-php.dev/static-php-cli/common/) | [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) | Linux, macOS | 二进制文件大小约为 7.5MB |
+| [bulk](https://dl.static-php.dev/static-php-cli/bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | 二进制文件大小约为 25MB |
+| [gnu-bulk](https://dl.static-php.dev/static-php-cli/gnu-bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | 使用 glibc 的 bulk 组合 |
+| [minimal](https://dl.static-php.dev/static-php-cli/minimal/) | [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) | Linux, macOS | 二进制文件大小约为 3MB |
+| [spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/) | [5](https://dl.static-php.dev/static-php-cli/windows/spc-min/README.txt) | Windows | 二进制文件大小约为 3MB |
+| [spc-max](https://dl.static-php.dev/static-php-cli/windows/spc-max/) | [40+](https://dl.static-php.dev/static-php-cli/windows/spc-max/README.txt) | Windows | 二进制文件大小约为 8.5MB |
-# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
-./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
-# 编译线程安全版本 (--enable-zts)
-./bin/spc build "curl,phar" --enable-zts --build-cli
-# 编译后使用 UPX 减小可执行文件体积 (仅 Linux、Windows 可用) (至少压缩至原来的 30~50%)
-./bin/spc build "curl,phar" --enable-zts --build-cli --with-upx-pack
-```
+> Linux 和 Windows 支持对二进制文件进行 UPX 压缩,可以将二进制文件大小减少 30% 到 50%。
+> macOS 不支持 UPX 压缩,因此 mac 的预构建二进制文件大小较大。
-其中,目前支持构建 cli,micro,fpm 和 embed,使用以下参数的一个或多个来指定编译的 SAPI:
+### 在线构建(使用 GitHub Actions)
-- `--build-cli`:构建 cli 二进制
-- `--build-micro`:构建 phpmicro 自执行二进制
-- `--build-fpm`:构建 fpm
-- `--build-embed`:构建 embed(libphp)
-- `--build-cgi`: 构建 cgi(不推荐)
-- `--build-all`:构建所有
+上方直接下载的二进制不能满足需求时,可使用 GitHub Action 可以轻松构建静态编译的 PHP,
+同时自行定义要编译的扩展。
-如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
+1. Fork 本项目。
+2. 进入项目的 Actions 并选择 `CI`。
+3. 选择 `Run workflow`,填入您要编译的 PHP 版本、目标类型和扩展列表。(扩展用逗号分隔,例如 `bcmath,curl,mbstring`)
+4. 等待一段时间后,进入相应的任务并获取 `Artifacts`。
-```bash
-./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
-./bin/spc download --all --debug
-```
-
-## 不同 SAPI 的使用
-
-### 使用 cli
-
-> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
-
-采用参数 `--build-cli` 或`--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
-该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
-
-```bash
-cd buildroot/bin/
-./php -v # 检查版本
-./php -m # 检查编译的扩展
-./php your_code.php # 运行代码
-./php your_project.phar # 运行打包为 phar 单文件的项目
-```
-
-### 使用 micro
-
-> phpmicro 是一个提供自执行二进制 PHP 的项目,本项目依赖 phpmicro 进行编译自执行二进制。详见 [dixyes/phpmicro](https://github.com/dixyes/phpmicro)。
-
-采用项目参数 `--build-micro` 或 `--build-all` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
-该文件编译后会存放在 `buildroot/bin/` 目录中,拷贝出来即可。
-
-使用时应准备好你的项目源码文件,可以是单个 PHP 文件,也可以是 Phar 文件。
-
-```bash
-echo " code.php
-cat micro.sfx code.php > single-app && chmod +x single-app
-./single-app
-```
-
-如果打包 PHAR 文件,仅需把 code.php 更换为 phar 文件路径即可。
-你可以使用 [box-project/box](https://github.com/box-project/box) 将你的 CLI 项目打包为 Phar,
-然后将它与 phpmicro 结合,生成独立可执行的二进制文件。
-
-```bash
-# 使用 static-php-cli 生成的 micro.sfx 结合,也可以直接使用 cat 命令结合它们
-bin/spc micro:combine my-app.phar
-cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
-
-# 使用 micro:combine 结合可以将 INI 选项注入到二进制中
-bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
-```
-
-> 有些情况下的 phar 文件或 PHP 项目可能无法在 micro 环境下运行。
-
-### 使用 fpm
-
-采用项目参数 `--build-fpm` 或 `--build-all` 时,最后编译结果会输出一个 `./php-fpm` 的文件。
-该文件存放在 `buildroot/bin/` 目录,拷贝出来即可使用。
-
-在正常的 Linux 发行版和 macOS 系统中,安装 php-fpm 后包管理会自动生成默认的 fpm 配置文件。
-因为 php-fpm 必须指定配置文件才可启动,本项目编译的 php-fpm 不会带任何配置文件,所以需自行编写 `php-fpm.conf` 和 `pool.conf` 配置文件。
-
-指定 `php-fpm.conf` 可以使用命令参数 `-y`,例如:`./php-fpm -y php-fpm.conf`。
-
-### 使用 embed
-
-采用项目参数 `--build-embed` 或 `--build-all` 时,最后编译结果会输出一个 `libphp.a`、`php-config` 以及一系列头文件,存放在 `buildroot/`,你可以在你的其他代码中引入它们。
-
-如果你知道 [embed SAPI](https://github.com/php/php-src/tree/master/sapi/embed),你应该知道如何使用它。对于有可能编译用到引入其他库的问题,你可以使用 `buildroot/bin/php-config` 来获取编译时的配置。
-
-另外,有关如何使用此功能的高级示例,请查看[如何使用它构建 FrankenPHP 的静态版本](https://github.com/php/frankenphp/blob/main/docs/static.md)。
+如果您启用 `debug`,构建时将输出所有日志,包括编译日志,以便故障排除。
## 贡献
-如果缺少你需要的扩展,可发起 Issue。如果你对本项目较熟悉,也欢迎为本项目发起 Pull Request。
+如果您需要的扩展缺失,可以创建 issue。
+如果您熟悉本项目,也欢迎发起 pull request。
-另外,添加新扩展的贡献方式,可以参考下方 `进阶`。
+如果您想贡献文档,请直接编辑 `docs/` 目录。
-如果你想贡献文档内容,请直接修改 `docs/` 目录。
+现在有一个 [static-php](https://github.com/static-php) 组织,用于存储与项目相关的仓库。
## 赞助本项目
-你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。你捐赠的一部分将会被用于维护 **static-php.dev** 服务器。
+您可以从 [GitHub Sponsor](https://github.com/crazywhalecc) 赞助我或我的项目。您捐赠的一部分将用于维护 **static-php.dev** 服务器。
-**特别赞助商**:
+**特别感谢以下赞助商**:
-## 开源协议
+## 开源许可证
-本项目采用 MIT License 许可开源,下面是类似的项目:
+本项目本身基于 MIT 许可证,
+一些新添加的扩展和依赖可能来自其他项目,
+这些代码文件的头部也会给出额外的许可证和作者说明。
+
+这些是类似的项目:
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
-该项目使用了 [dixyes/lwmbs](https://github.com/dixyes/lwmbs) 中的一些代码,例如 Windows 静态构建目标和 libiconv 库支持。
-lwmbs 使用 [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2) 许可进行分发。对应文件有关于作者和许可的特殊说明,除此之外,均使用 MIT 授权许可。
+本项目使用了 [dixyes/lwmbs](https://github.com/dixyes/lwmbs) 的一些代码,例如 Windows 静态构建目标和 libiconv 支持。
+lwmbs 基于 [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2) 许可证。
-因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
-请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
+由于本项目的特殊性,
+项目编译过程中会使用许多其他开源项目,如 curl 和 protobuf,
+它们都有自己的开源许可证。
+
+请在编译后使用 `bin/spc dump-license` 命令导出项目中使用的开源许可证,
+并遵守相应项目的 LICENSE。
diff --git a/README.md b/README.md
index e405edf4..21fbda14 100755
--- a/README.md
+++ b/README.md
@@ -5,29 +5,22 @@
[](https://github.com/crazywhalecc/static-php-cli/releases)
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
-[](https://static-php.dev/en/guide/extensions.html)
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
with popular extensions.
-Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed`, `micro` and `frankenphp` SAPI.
-
-**static-php-cli** also has the ability to package PHP projects
-along with the PHP interpreter into one single executable file.
-
## Features
-static-php-cli (you can call it `spc`) has a lot of features:
-
-- :handbag: Build single-file php executable, without any dependencies
-- :hamburger: Build **[phpmicro](https://github.com/dixyes/phpmicro)** self-extracted executable (glue php binary and php source code into one file)
-- :pill: Automatic build environment checker (Doctor module)
+- :elephant: Support multiple PHP versions - PHP 8.1, 8.2, 8.3, 8.4, 8.5
+- :handbag: Build single-file PHP executable with zero dependencies
+- :hamburger:Build **[phpmicro](https://github.com/dixyes/phpmicro)** self-extracting executables (combines PHP binary and source code into one file)
+- :pill: Automatic build environment checker with auto-fix capabilities
- :zap: `Linux`, `macOS`, `FreeBSD`, `Windows` support
-- :wrench: Configurable source code patches
-- :books: Build dependency management
-- 📦 Provide `spc` own standalone executable (built by spc and [box](https://github.com/box-project/box))
-- :fire: Support many popular [extensions](https://static-php.dev/en/guide/extensions.html)
-- :floppy_disk: UPX integration (significantly reduces binary size)
+- :wrench: Configurable source code patching
+- :books: Intelligent dependency management
+- 📦 Self-contained `spc` executable (built with [box](https://github.com/box-project/box))
+- :fire: Support 75+ popular [extensions](https://static-php.dev/en/guide/extensions.html)
+- :floppy_disk: UPX compression support (reduces binary size by 30-50%)
**Single-file standalone php-cli:**
@@ -37,6 +30,72 @@ static-php-cli (you can call it `spc`) has a lot of features:
+## Quickstart
+
+### 1. Download spc binary
+
+```bash
+# For Linux x86_64
+curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
+# For Linux aarch64
+curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
+# macOS x86_64 (Intel)
+curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
+# macOS aarch64 (Apple)
+curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
+# Windows (x86_64, win10 build 17063 or later, please install VS2022 first)
+curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
+```
+
+For macOS and Linux, add execute permission first:
+
+```bash
+chmod +x ./spc
+```
+
+### 2. Build Static PHP
+
+First, create a `craft.yml` file and specify which extensions you want to include from [extension list](https://static-php.dev/en/guide/extensions.html) or [command generator](https://static-php.dev/en/guide/cli-generator.html):
+
+```yml
+# PHP version support: 8.1, 8.2, 8.3, 8.4, 8.5
+php-version: 8.4
+# Put your extension list here
+extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
+sapi:
+ - cli
+ - micro
+ - fpm
+download-options:
+ prefer-pre-built: true
+```
+
+Run command:
+
+```bash
+./spc craft
+
+# Output full console log
+./spc craft --debug
+```
+
+### 3. Static PHP usage
+
+Now you can copy binaries built by static-php-cli to another machine and run with no dependencies:
+
+```
+# php-cli
+buildroot/bin/php -v
+
+# phpmicro
+echo ' a.php
+./spc micro:combine a.php -O my-app
+./my-app
+
+# php-fpm
+buildroot/bin/php-fpm -v
+```
+
## Documentation
The current README contains basic usage. For all the features of static-php-cli,
@@ -53,6 +112,7 @@ which can be downloaded directly according to your needs.
|----------------------------------------------------------------------|----------------------------------------------------------------------------|--------------|--------------------------------|
| [common](https://dl.static-php.dev/static-php-cli/common/) | [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) | Linux, macOS | The binary size is about 7.5MB |
| [bulk](https://dl.static-php.dev/static-php-cli/bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | The binary size is about 25MB |
+| [gnu-bulk](https://dl.static-php.dev/static-php-cli/gnu-bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | Using shared glibc |
| [minimal](https://dl.static-php.dev/static-php-cli/minimal/) | [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) | Linux, macOS | The binary size is about 3MB |
| [spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/) | [5](https://dl.static-php.dev/static-php-cli/windows/spc-min/README.txt) | Windows | The binary size is about 3MB |
| [spc-max](https://dl.static-php.dev/static-php-cli/windows/spc-max/) | [40+](https://dl.static-php.dev/static-php-cli/windows/spc-max/README.txt) | Windows | The binary size is about 8.5MB |
@@ -60,64 +120,10 @@ which can be downloaded directly according to your needs.
> Linux and Windows supports UPX compression for binaries, which can reduce the size of the binary by 30% to 50%.
> macOS does not support UPX compression, so the size of the pre-built binaries for mac is larger.
-## Build
-
-### Compilation Requirements
-
-You can say I made a PHP builder written in PHP, pretty funny.
-But static-php-cli runtime only requires an environment above PHP 8.1 and extensions mentioned below.
-
-- PHP >= 8.4 (This is the version required by spc itself, not the build version)
-- Extension: `mbstring,tokenizer,phar`
-- Supported OS with `curl` and `git` installed
-
-Here is the supported OS and arch, where :octocat: represents support for GitHub Action builds,
-:computer: represents support for local manual builds, and blank represents not currently supported.
-
-| | x86_64 | aarch64 |
-|---------|----------------------|----------------------|
-| macOS | :octocat: :computer: | :octocat: :computer: |
-| Linux | :octocat: :computer: | :octocat: :computer: |
-| Windows | :octocat: :computer: | |
-| FreeBSD | :computer: | :computer: |
-
-Currently supported PHP versions for compilation:
-
-> :warning: Partial support, there may be issues with newer test versions or older versions.
->
-> :heavy_check_mark: supported
->
-> :x: not supported
-
-| PHP Version | Status | Comment |
-|-------------|--------------------|----------------------------------------------------------------------------------------------------|
-| 7.2 | :x: | |
-| 7.3 | :x: | phpmicro and some extensions not supported on 7.x |
-| 7.4 | :x: | phpmicro and some extensions not supported on 7.x |
-| 8.0 | :warning: | PHP official has stopped maintenance of 8.0, we no longer provide backport support for version 8.0 |
-| 8.1 | :heavy_check_mark: | PHP official has security fixes only, we no longer provide backport support when 8.5 released |
-| 8.2 | :heavy_check_mark: | |
-| 8.3 | :heavy_check_mark: | |
-| 8.4 | :heavy_check_mark: | |
-| 8.5 (alpha) | :warning: | PHP 8.5 is in alpha |
-
-> This table shows the support status for static-php-cli in building the corresponding version,
-> not the official PHP support status for that version.
-
-### Supported Extensions
-
-Please first select the extension you want to compile based on the extension list below.
-
-- [Supported Extension List](https://static-php.dev/en/guide/extensions.html)
-- [Command Generator](https://static-php.dev/en/guide/cli-generator.html)
-
-> If an extension you need is missing, you can submit an issue.
-
-Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
-
### Build Online (using GitHub Actions)
-Use GitHub Action to easily build a statically compiled PHP,
+When the above direct download binaries cannot meet your needs,
+you can use GitHub Action to easily build a statically compiled PHP,
and at the same time define the extensions to be compiled by yourself.
1. Fork me.
@@ -127,185 +133,6 @@ and at the same time define the extensions to be compiled by yourself.
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
-### Build Locally (using SPC binary, recommended)
-
-This project provides a binary file of static-php-cli: `spc`.
-You can use `spc` binary instead of installing any runtime like golang app.
-Currently, the platforms supported by `spc` binary are Linux and macOS.
-
-Download from self-hosted nightly builds using commands below:
-
-```bash
-# Download from self-hosted nightly builds (sync with main branch)
-# For Linux x86_64
-curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
-# For Linux aarch64
-curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
-# macOS x86_64 (Intel)
-curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
-# macOS aarch64 (Apple)
-curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
-# Windows (x86_64, win10 build 17063 or later)
-curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
-
-# Add execute perm (Linux and macOS only)
-chmod +x ./spc
-
-# Run (Linux and macOS)
-./spc --version
-# Run (Windows powershell)
-.\spc.exe --version
-```
-
-Self-hosted `spc` is built by GitHub Actions, you can also download from Actions artifacts [here](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml).
-
-### Build Locally (using git source)
-
-If you need to modify the static-php-cli source code, or have problems using the spc binary build,
-you can download static-php-cli using the git source code.
-
-```bash
-# just clone me!
-git clone https://github.com/crazywhalecc/static-php-cli.git
-```
-
-If you have not installed php on your system, we recommend that you use the built-in setup-runtime to install PHP and Composer automatically.
-
-```bash
-cd static-php-cli
-chmod +x bin/setup-runtime
-# it will download static php (from self-hosted server) and composer (from getcomposer)
-bin/setup-runtime
-# initialize composer deps
-bin/composer install
-# chmod
-chmod +x bin/spc
-bin/spc --version
-```
-
-### Start Building PHP
-
-Basic usage for building php with some extensions:
-
-> If you are using the packaged standalone `spc` binary, you need to replace `bin/spc` with `./spc` or `.\spc.exe` in the following commands.
-
-```bash
-# Check system tool dependencies, auto-fix them if possible
-./bin/spc doctor --auto-fix
-
-# fetch all libraries
-./bin/spc download --all
-# dump a list of extensions required by your project
-./bin/spc dump-extensions /path/to/your/project --format=text
-# only fetch necessary sources by needed extensions (recommended)
-./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
-# download pre-built libraries first (save time for compiling dependencies)
-./bin/spc download --for-extensions="openssl,curl,mbstring,mbregex" --prefer-pre-built
-# download different PHP version (--with-php=x.y or --with-php=x.y.z, recommend 8.3 ~ 8.4)
-./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
-
-# with bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl extension, build both CLI and phpmicro SAPI
-./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
-# build thread-safe (ZTS) version (--enable-zts)
-./bin/spc build "curl,phar" --enable-zts --build-cli
-# build, pack executable with UPX (linux and windows only) (reduce binary size for 30~50%)
-./bin/spc build "curl,phar" --enable-zts --build-cli --with-upx-pack
-```
-
-Now we support `cli`, `micro`, `fpm` and `embed` SAPI. You can use one or more of the following parameters to specify the compiled SAPI:
-
-- `--build-cli`: build static cli executable
-- `--build-micro`: build static phpmicro self-extracted executable
-- `--build-fpm`: build static fpm binary
-- `--build-embed`: build embed (libphp)
-- `--build-cgi`: build cgi binary (not recommended)
-- `--build-all`: build all
-
-If anything goes wrong, use `--debug` option to display full terminal output:
-
-```bash
-./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
-./bin/spc download --all --debug
-```
-
-## Different SAPI Usage
-
-### Use cli
-
-> php-cli is a single static binary, you can use it like normal php installed on your system.
-
-When using the parameter `--build-cli` or `--build-all`,
-the final compilation result will output a binary file named `./php`,
-which can be distributed and used directly.
-This file will be located in the directory `buildroot/bin/`, copy it out for use.
-
-```bash
-cd buildroot/bin/
-./php -v # check version
-./php -m # check extensions
-./php your_code.php # run your php code
-./php your_project.phar # run your phar (project archive)
-```
-
-### Use micro
-
-> phpmicro is a SelF-extracted eXecutable SAPI module,
-> provided by [phpmicro](https://github.com/dixyes/phpmicro) project.
-> But this project is using a [fork](https://github.com/static-php/phpmicro) of phpmicro, because we need to add some features to it.
-> It can put php runtime and your source code together.
-
-When using the parameter `--build-all` or `--build-micro`,
-the final compilation result will output a file named `./micro.sfx`,
-which needs to be used with your PHP source code like `code.php`.
-This file will be located in the path `buildroot/bin/micro.sfx`, simply copy it out for use.
-
-Prepare your project source code, which can be a single PHP file or a Phar file, for use.
-
-```bash
-echo " code.php
-cat micro.sfx code.php > single-app && chmod +x single-app
-./single-app
-```
-
-If you package a PHAR file, just replace `code.php` with the phar file path.
-You can use [box-project/box](https://github.com/box-project/box) to package your CLI project as Phar,
-It is then combined with phpmicro to produce a standalone executable binary.
-
-```bash
-# Use the micro.sfx generated by static-php-cli to combine,
-bin/spc micro:combine my-app.phar
-# or you can directly use the cat command to combine them.
-cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
-
-# Use micro:combine combination to inject INI options into the binary.
-bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
-```
-
-> In some cases, PHAR files may not run in a micro environment. Overall, micro is not production ready.
-
-### Use fpm
-
-When using the parameter `--build-all` or `--build-fpm`,
-the final compilation result will output a file named `./php-fpm`,
-This file will be located in the path `buildroot/bin/`, simply copy it out for use.
-
-In common Linux distributions and macOS systems, the package manager will automatically generate a default fpm configuration file after installing php-fpm.
-Because php-fpm must specify a configuration file before running, the php-fpm compiled by this project will not have any configuration files, so you need to write `php-fpm.conf` and `pool.conf` configuration files yourself.
-
-Specifying `php-fpm.conf` can use the command parameter `-y`, for example: `./php-fpm -y php-fpm.conf`.
-
-### Use embed
-
-When using the project parameters `--build-embed` or `--build-all`,
-the final compilation result will output a `libphp.a`, `php-config` and a series of header files,
-stored in `buildroot/`. You can introduce them in your other projects.
-
-If you know [embed SAPI](https://github.com/php/php-src/tree/master/sapi/embed), you should know how to use it.
-You may require the introduction of other libraries during compilation,
-you can use `buildroot/bin/php-config` to obtain the compile-time configuration.
-
-For an advanced example of how to use this feature, take a look at [how to use it to build a static version of FrankenPHP](https://github.com/php/frankenphp/blob/main/docs/static.md).
-
## Contribution
If the extension you need is missing, you can create an issue.
diff --git a/docs/en/guide/index.md b/docs/en/guide/index.md
index 253562b5..54e7840c 100644
--- a/docs/en/guide/index.md
+++ b/docs/en/guide/index.md
@@ -21,19 +21,30 @@ The following is the architecture support situation, where :gear: represents sup
| Windows | :gear: :computer: | |
| FreeBSD | :computer: | :computer: |
-Among them, Linux is currently only tested on Ubuntu, Debian, and Alpine distributions,
-and other distributions have not been tested, which cannot guarantee successful compilation.
-For untested distributions, local compilation can be done using methods such as Docker to avoid environmental issues.
+Current supported PHP versions for compilation:
-There are two architectures for macOS: `x86_64` and `Arm`, but binaries compiled on one architecture cannot be directly used on the other architecture.
-Rosetta 2 cannot guarantee that programs compiled with `Arm` architecture can fully run on `x86_64` environment.
+> :warning: Partial support, there may be issues with new beta versions and old versions.
+>
+> :heavy_check_mark: Supported
+>
+> :x: Not supported
-Windows currently only supports the x86_64 architecture, and does not support 32-bit x86 or arm64 architecture.
+| PHP Version | Status | Comment |
+|-------------|--------------------|-------------------------------------------------------------------------------------------------------------------------|
+| 7.2 | :x: | |
+| 7.3 | :x: | phpmicro and many extensions do not support 7.3, 7.4 versions |
+| 7.4 | :x: | phpmicro and many extensions do not support 7.3, 7.4 versions |
+| 8.0 | :warning: | PHP official has stopped maintaining 8.0, we no longer handle 8.0 related backport support |
+| 8.1 | :warning: | PHP official only provides security updates for 8.1, we no longer handle 8.1 related backport support after 8.5 release |
+| 8.2 | :heavy_check_mark: | |
+| 8.3 | :heavy_check_mark: | |
+| 8.4 | :heavy_check_mark: | |
+| 8.5 (beta) | :warning: | PHP 8.5 is currently in beta stage |
-## Supported PHP Version
+> This table shows the support status of static-php-cli for building corresponding versions, not the PHP official support status for that version.
-Currently, static php cli supports PHP versions 8.1 to 8.5, and theoretically supports PHP 8.0 and earlier versions.
-Simply select the earlier version when downloading.
-However, due to some extensions and special components that have stopped supporting earlier versions of PHP,
-static-php-cli will not explicitly support earlier versions.
+## PHP Support Versions
+
+Currently, static-php-cli supports PHP versions 8.2 ~ 8.5, and theoretically supports PHP 8.1 and earlier versions, just select the earlier version when downloading.
+However, due to some extensions and special components that have stopped supporting earlier versions of PHP, static-php-cli will not explicitly support earlier versions.
We recommend that you compile the latest PHP version possible for a better experience.
diff --git a/docs/zh/guide/index.md b/docs/zh/guide/index.md
index 318c40b8..8e5727c2 100644
--- a/docs/zh/guide/index.md
+++ b/docs/zh/guide/index.md
@@ -19,16 +19,30 @@ static-php-cli 是一个用于构建静态编译的 PHP 二进制的工具,目
| Windows | :gear: :computer: | |
| FreeBSD | :computer: | :computer: |
-其中,Linux 目前仅在 Ubuntu、Debian、Alpine 发行版测试通过,其他发行版未进行测试,不能保证编译成功。
-对于未经过测试的发行版,可以使用 Docker 等方式本地编译,避免环境导致的问题。
+当前支持编译的 PHP 版本:
-macOS 下支持 x86_64 和 Arm 两种架构,但在其中一个架构上编译的二进制无法直接在另一个架构上使用。
-Rosetta 2 不能保证 Arm 架构编译的程序可以完全运行在 x86_64 环境下。
+> :warning: 部分支持,对于新的测试版和旧版本可能存在问题。
+>
+> :heavy_check_mark: 支持
+>
+> :x: 不支持
-Windows 目前只支持 x86_64 架构,不支持 32 位 x86、不支持 arm64 架构。
+| PHP Version | Status | Comment |
+|-------------|--------------------|---------------------------------------------------------|
+| 7.2 | :x: | |
+| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
+| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
+| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
+| 8.1 | :warning: | PHP 官方仅对 8.1 提供安全更新,在 8.5 发布后我们不再处理 8.1 相关的 backport 支持 |
+| 8.2 | :heavy_check_mark: | |
+| 8.3 | :heavy_check_mark: | |
+| 8.4 | :heavy_check_mark: | |
+| 8.5 (beta) | :warning: | PHP 8.5 目前处于 beta 阶段 |
+
+> 这个表格的支持状态是 static-php-cli 对构建对应版本的支持情况,不是 PHP 官方对该版本的支持情况。
## PHP 支持版本
-目前,static-php-cli 对 PHP 8.1 ~ 8.5 版本是支持的,对于 PHP 8.0 及更早版本理论上支持,只需下载时选择早期版本即可。
+目前,static-php-cli 对 PHP 8.2 ~ 8.5 版本是支持的,对于 PHP 8.1 及更早版本理论上支持,只需下载时选择早期版本即可。
但由于部分扩展和特殊组件已对早期版本的 PHP 停止了支持,所以 static-php-cli 不会明确支持早期版本。
我们推荐你编译尽可能新的 PHP 版本,以获得更好的体验。
diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php
index b410aab3..e6e27cda 100644
--- a/src/SPC/builder/BuilderBase.php
+++ b/src/SPC/builder/BuilderBase.php
@@ -10,6 +10,7 @@ use SPC\exception\WrongUsageException;
use SPC\store\Config;
use SPC\store\FileSystem;
use SPC\store\LockFile;
+use SPC\store\pkg\GoXcaddy;
use SPC\store\SourceManager;
use SPC\store\SourcePatcher;
use SPC\util\AttributeMapper;
@@ -507,8 +508,7 @@ abstract class BuilderBase
throw new WrongUsageException('FrankenPHP SAPI is only available on Linux and macOS!');
}
// frankenphp needs package go-xcaddy installed
- $pkg_dir = PKG_ROOT_PATH . '/go-xcaddy-' . arch2gnu(php_uname('m')) . '-' . osfamily2shortname();
- if (!file_exists("{$pkg_dir}/bin/go") || !file_exists("{$pkg_dir}/bin/xcaddy")) {
+ if (!GoXcaddy::isInstalled()) {
global $argv;
throw new WrongUsageException("FrankenPHP SAPI requires the go-xcaddy package, please install it first: {$argv[0]} install-pkg go-xcaddy");
}
diff --git a/src/SPC/builder/extension/dba.php b/src/SPC/builder/extension/dba.php
index abda5651..d1f8cda3 100644
--- a/src/SPC/builder/extension/dba.php
+++ b/src/SPC/builder/extension/dba.php
@@ -12,7 +12,7 @@ class dba extends Extension
{
public function getUnixConfigureArg(bool $shared = false): string
{
- $qdbm = $this->builder->getLib('qdbm') ? (' --with-qdbm=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH) : '';
+ $qdbm = $this->builder->getLib('qdbm') ? (' --with-qdbm=' . BUILD_ROOT_PATH) : '';
return '--enable-dba' . ($shared ? '=shared' : '') . $qdbm;
}
diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php
index 3525ffb7..b1b1ffc5 100644
--- a/src/SPC/builder/linux/LinuxBuilder.php
+++ b/src/SPC/builder/linux/LinuxBuilder.php
@@ -147,16 +147,15 @@ class LinuxBuilder extends UnixBuilderBase
}
$this->buildEmbed();
}
- // build dynamic extensions if needed, must happen before building FrankenPHP to make sure we export all necessary, undefined symbols
+ if ($enableFrankenphp) {
+ logger()->info('building frankenphp');
+ $this->buildFrankenphp();
+ }
$shared_extensions = array_map('trim', array_filter(explode(',', $this->getOption('build-shared'))));
if (!empty($shared_extensions)) {
logger()->info('Building shared extensions ...');
$this->buildSharedExts();
}
- if ($enableFrankenphp) {
- logger()->info('building frankenphp');
- $this->buildFrankenphp();
- }
}
public function testPHP(int $build_target = BUILD_TARGET_NONE)
@@ -326,7 +325,7 @@ class LinuxBuilder extends UnixBuilderBase
$target = "{$libDir}/{$realLibName}";
if (file_exists($target)) {
[, $output] = shell()->execWithResult('readelf -d ' . escapeshellarg($target));
- $output = join("\n", $output);
+ $output = implode("\n", $output);
if (preg_match('/SONAME.*\[(.+)]/', $output, $sonameMatch)) {
$currentSoname = $sonameMatch[1];
if ($currentSoname !== basename($target)) {
diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php
index 20a2ed13..ef7b303b 100644
--- a/src/SPC/builder/macos/MacOSBuilder.php
+++ b/src/SPC/builder/macos/MacOSBuilder.php
@@ -161,15 +161,15 @@ class MacOSBuilder extends UnixBuilderBase
}
$this->buildEmbed();
}
+ if ($enableFrankenphp) {
+ logger()->info('building frankenphp');
+ $this->buildFrankenphp();
+ }
$shared_extensions = array_map('trim', array_filter(explode(',', $this->getOption('build-shared'))));
if (!empty($shared_extensions)) {
logger()->info('Building shared extensions ...');
$this->buildSharedExts();
}
- if ($enableFrankenphp) {
- logger()->info('building frankenphp');
- $this->buildFrankenphp();
- }
}
public function testPHP(int $build_target = BUILD_TARGET_NONE)
diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php
index 88ee20aa..5942f90c 100644
--- a/src/SPC/builder/unix/UnixBuilderBase.php
+++ b/src/SPC/builder/unix/UnixBuilderBase.php
@@ -267,7 +267,7 @@ abstract class UnixBuilderBase extends BuilderBase
protected function buildFrankenphp(): void
{
- GlobalEnvManager::addPathIfNotExists(GoXcaddy::getEnvironment()['PATH']);
+ GlobalEnvManager::addPathIfNotExists(GoXcaddy::getPath());
$nobrotli = $this->getLib('brotli') === null ? ',nobrotli' : '';
$nowatcher = $this->getLib('watcher') === null ? ',nowatcher' : '';
$xcaddyModules = getenv('SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES');
@@ -311,22 +311,17 @@ abstract class UnixBuilderBase extends BuilderBase
$cflags .= ' -Wno-error=missing-profile';
$libs .= ' -lgcov';
}
- $env = [
+ $env = [...[
'CGO_ENABLED' => '1',
'CGO_CFLAGS' => clean_spaces($cflags),
'CGO_LDFLAGS' => "{$this->arch_ld_flags} {$staticFlags} {$config['ldflags']} {$libs}",
'XCADDY_GO_BUILD_FLAGS' => '-buildmode=pie ' .
'-ldflags \"-linkmode=external ' . $extLdFlags . ' ' . $debugFlags .
'-X \'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ' .
- "{$frankenPhpVersion} PHP {$libphpVersion} Caddy'\\\" " .
+ "v{$frankenPhpVersion} PHP {$libphpVersion} Caddy'\\\" " .
"-tags={$muslTags}nobadger,nomysql,nopgx{$nobrotli}{$nowatcher}",
'LD_LIBRARY_PATH' => BUILD_LIB_PATH,
- ];
- foreach (GoXcaddy::getEnvironment() as $key => $value) {
- if ($key !== 'PATH') {
- $env[$key] = $value;
- }
- }
+ ], ...GoXcaddy::getEnvironment()];
shell()->cd(BUILD_BIN_PATH)
->setEnv($env)
->exec("xcaddy build --output frankenphp {$xcaddyModules}");
diff --git a/src/SPC/command/CraftCommand.php b/src/SPC/command/CraftCommand.php
index 27b3c38f..6c40133d 100644
--- a/src/SPC/command/CraftCommand.php
+++ b/src/SPC/command/CraftCommand.php
@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace SPC\command;
use SPC\exception\ValidationException;
+use SPC\store\pkg\GoXcaddy;
+use SPC\store\pkg\Zig;
use SPC\toolchain\ToolchainManager;
use SPC\toolchain\ZigToolchain;
use SPC\util\ConfigValidator;
@@ -63,7 +65,7 @@ class CraftCommand extends BuildCommand
}
}
// install go and xcaddy for frankenphp
- if (in_array('frankenphp', $craft['sapi'])) {
+ if (in_array('frankenphp', $craft['sapi']) && !GoXcaddy::isInstalled()) {
$retcode = $this->runCommand('install-pkg', 'go-xcaddy');
if ($retcode !== 0) {
$this->output->writeln('craft go-xcaddy failed');
@@ -71,7 +73,7 @@ class CraftCommand extends BuildCommand
}
}
// install zig if requested
- if (ToolchainManager::getToolchainClass() === ZigToolchain::class) {
+ if (ToolchainManager::getToolchainClass() === ZigToolchain::class && !Zig::isInstalled()) {
$retcode = $this->runCommand('install-pkg', 'zig');
if ($retcode !== 0) {
$this->output->writeln('craft zig failed');
diff --git a/src/SPC/doctor/item/LinuxToolCheckList.php b/src/SPC/doctor/item/LinuxToolCheckList.php
index c3611dcc..2f6e866d 100644
--- a/src/SPC/doctor/item/LinuxToolCheckList.php
+++ b/src/SPC/doctor/item/LinuxToolCheckList.php
@@ -28,7 +28,7 @@ class LinuxToolCheckList
public const TOOLS_DEBIAN = [
'make', 'bison', 're2c', 'flex',
'git', 'autoconf', 'automake', 'autopoint',
- 'tar', 'unzip', 'gzip',
+ 'tar', 'unzip', 'gzip', 'gcc', 'g++',
'bzip2', 'cmake', 'patch',
'xz', 'libtoolize', 'which',
'patchelf',
@@ -37,7 +37,7 @@ class LinuxToolCheckList
public const TOOLS_RHEL = [
'perl', 'make', 'bison', 're2c', 'flex',
'git', 'autoconf', 'automake',
- 'tar', 'unzip', 'gzip', 'gcc',
+ 'tar', 'unzip', 'gzip', 'gcc', 'g++',
'bzip2', 'cmake', 'patch', 'which',
'xz', 'libtool', 'gettext-devel',
'patchelf',
@@ -53,7 +53,8 @@ class LinuxToolCheckList
'base-devel' => 'automake',
'gettext-devel' => 'gettextize',
'gettext-dev' => 'gettextize',
- 'perl-IPC-Cmd' => '/usr/share/doc/perl-IPC-Cmd',
+ 'perl-IPC-Cmd' => '/usr/share/perl5/vendor_perl/IPC/Cmd.pm',
+ 'perl-Time-Piece' => '/usr/lib64/perl5/Time/Piece.pm',
];
/** @noinspection PhpUnused */
@@ -65,7 +66,7 @@ class LinuxToolCheckList
$required = match ($distro['dist']) {
'alpine' => self::TOOLS_ALPINE,
'redhat' => self::TOOLS_RHEL,
- 'centos' => array_merge(self::TOOLS_RHEL, ['perl-IPC-Cmd']),
+ 'centos' => array_merge(self::TOOLS_RHEL, ['perl-IPC-Cmd', 'perl-Time-Piece']),
'arch' => self::TOOLS_ARCH,
default => self::TOOLS_DEBIAN,
};
diff --git a/src/SPC/store/FileSystem.php b/src/SPC/store/FileSystem.php
index a40f5f01..7a574925 100644
--- a/src/SPC/store/FileSystem.php
+++ b/src/SPC/store/FileSystem.php
@@ -274,7 +274,7 @@ class FileSystem
public static function convertWinPathToMinGW(string $path): string
{
if (preg_match('/^[A-Za-z]:/', $path)) {
- $path = '/' . strtolower(substr($path, 0, 1)) . '/' . str_replace('\\', '/', substr($path, 2));
+ $path = '/' . strtolower($path[0]) . '/' . str_replace('\\', '/', substr($path, 2));
}
return $path;
}
@@ -314,8 +314,13 @@ class FileSystem
$sub_file = self::convertPath($dir . '/' . $v);
if (is_dir($sub_file) && $recursive) {
# 如果是 目录 且 递推 , 则递推添加下级文件
- $list = array_merge($list, self::scanDirFiles($sub_file, $recursive, $relative));
- } elseif (is_file($sub_file) || is_dir($sub_file) && !$recursive && $include_dir) {
+ $sub_list = self::scanDirFiles($sub_file, $recursive, $relative);
+ if (is_array($sub_list)) {
+ foreach ($sub_list as $item) {
+ $list[] = $item;
+ }
+ }
+ } elseif (is_file($sub_file) || (is_dir($sub_file) && !$recursive && $include_dir)) {
# 如果是 文件 或 (是 目录 且 不递推 且 包含目录)
if (is_string($relative) && mb_strpos($sub_file, $relative) === 0) {
$list[] = ltrim(mb_substr($sub_file, mb_strlen($relative)), '/\\');
@@ -440,7 +445,7 @@ class FileSystem
public static function writeFile(string $path, mixed $content, ...$args): bool|int|string
{
$dir = pathinfo(self::convertPath($path), PATHINFO_DIRNAME);
- if (!is_dir($dir) && !mkdir($dir, 0755, true)) {
+ if (!is_dir($dir) && !mkdir($dir, 0755, true) && !is_dir($dir)) {
throw new FileSystemException('Write file failed, cannot create parent directory: ' . $dir);
}
return file_put_contents($path, $content, ...$args);
diff --git a/src/SPC/store/pkg/CustomPackage.php b/src/SPC/store/pkg/CustomPackage.php
index 093f65d0..eb972d74 100644
--- a/src/SPC/store/pkg/CustomPackage.php
+++ b/src/SPC/store/pkg/CustomPackage.php
@@ -30,10 +30,14 @@ abstract class CustomPackage
/**
* Get the environment variables this package needs to be usable.
- * PATH needs to be appended, rather than replaced.
*/
abstract public static function getEnvironment(): array;
+ /**
+ * Get the PATH required to use this package.
+ */
+ abstract public static function getPath(): ?string;
+
abstract public static function isInstalled(): bool;
/**
diff --git a/src/SPC/store/pkg/GoXcaddy.php b/src/SPC/store/pkg/GoXcaddy.php
index daac9dc9..0c1c6f8c 100644
--- a/src/SPC/store/pkg/GoXcaddy.php
+++ b/src/SPC/store/pkg/GoXcaddy.php
@@ -90,22 +90,17 @@ class GoXcaddy extends CustomPackage
public static function getEnvironment(): array
{
- $arch = arch2gnu(php_uname('m'));
- $os = match (PHP_OS_FAMILY) {
- 'Windows' => 'win',
- 'Darwin' => 'macos',
- 'BSD' => 'freebsd',
- default => 'linux',
- };
-
- $packageName = "go-xcaddy-{$arch}-{$os}";
+ $packageName = 'go-xcaddy';
$pkgroot = PKG_ROOT_PATH;
-
return [
- 'PATH' => "{$pkgroot}/{$packageName}/bin",
'GOROOT' => "{$pkgroot}/{$packageName}",
'GOBIN' => "{$pkgroot}/{$packageName}/bin",
'GOPATH' => "{$pkgroot}/go",
];
}
+
+ public static function getPath(): ?string
+ {
+ return PKG_ROOT_PATH . '/go-xcaddy/bin';
+ }
}
diff --git a/src/SPC/store/pkg/Zig.php b/src/SPC/store/pkg/Zig.php
index 7c206f7c..e9865dbe 100644
--- a/src/SPC/store/pkg/Zig.php
+++ b/src/SPC/store/pkg/Zig.php
@@ -129,23 +129,10 @@ class Zig extends CustomPackage
public static function getEnvironment(): array
{
- $arch = arch2gnu(php_uname('m'));
- $os = match (PHP_OS_FAMILY) {
- 'Windows' => 'win',
- 'Darwin' => 'macos',
- 'BSD' => 'freebsd',
- default => 'linux',
- };
-
- $packageName = "zig-{$arch}-{$os}";
- $path = PKG_ROOT_PATH . "/{$packageName}";
-
- return [
- 'PATH' => $path,
- ];
+ return [];
}
- private static function getPath(): string
+ public static function getPath(): ?string
{
return PKG_ROOT_PATH . '/zig';
}
diff --git a/src/SPC/toolchain/ZigToolchain.php b/src/SPC/toolchain/ZigToolchain.php
index 3a929f2b..8f2e261e 100644
--- a/src/SPC/toolchain/ZigToolchain.php
+++ b/src/SPC/toolchain/ZigToolchain.php
@@ -42,10 +42,10 @@ class ZigToolchain implements ToolchainInterface
public function afterInit(): void
{
- if (!is_dir(Zig::getEnvironment()['PATH'])) {
+ if (!Zig::isInstalled()) {
throw new EnvironmentException('You are building with zig, but zig is not installed, please install zig first. (You can use `doctor` command to install it)');
}
- GlobalEnvManager::addPathIfNotExists(Zig::getEnvironment()['PATH']);
+ GlobalEnvManager::addPathIfNotExists(Zig::getPath());
f_passthru('ulimit -n 2048'); // zig opens extra file descriptors, so when a lot of extensions are built statically, 1024 is not enough
$cflags = getenv('SPC_DEFAULT_C_FLAGS') ?: '';
$cxxflags = getenv('SPC_DEFAULT_CXX_FLAGS') ?: '';