mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
Compare commits
9 Commits
5333da35cb
...
65d66c6073
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65d66c6073 | ||
|
|
7df46be6eb | ||
|
|
5ce9229e7d | ||
|
|
e6c9112575 | ||
|
|
f0a987ba3a | ||
|
|
42b2d36319 | ||
|
|
5d5ffe8866 | ||
|
|
8cd45e3f3f | ||
|
|
baf513bd56 |
42
.github/workflows/build.yml
vendored
42
.github/workflows/build.yml
vendored
@ -20,16 +20,19 @@ on:
|
||||
- '8.1'
|
||||
- '8.0'
|
||||
- '7.4'
|
||||
target:
|
||||
required: true
|
||||
description: which SAPI to deploy
|
||||
default: 'cli'
|
||||
type: choice
|
||||
options:
|
||||
- 'cli'
|
||||
- 'micro'
|
||||
- 'all'
|
||||
build-cli:
|
||||
description: build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: build fpm binary
|
||||
type: boolean
|
||||
extensions:
|
||||
description: extensions to compile (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
debug:
|
||||
type: boolean
|
||||
@ -79,29 +82,40 @@ jobs:
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
|
||||
# With target select: cli, micro or both
|
||||
- if: ${{ inputs.target == 'micro' || inputs.target == 'all' }}
|
||||
run: echo "SPC_BUILD_TARGET='--build-${{ inputs.target }}'" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
|
||||
|
||||
# If there's no dependencies cache, fetch sources, with or without debug
|
||||
- run: CACHE_API_EXEC=yes ./bin/spc fetch --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
|
||||
|
||||
# Run build command
|
||||
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_TARGET }}
|
||||
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.target == 'cli' || inputs.target == 'all' }}
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php
|
||||
|
||||
# Upload micro self-extracted executable
|
||||
- if: ${{ inputs.target == 'micro' || inputs.target == 'all' }}
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/micro.sfx
|
||||
|
||||
# Upload fpm executable
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php-fpm
|
||||
|
||||
# Upload extensions metadata
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
26
README-en.md
26
README-en.md
@ -92,7 +92,7 @@ chmod +x bin/spc
|
||||
# fetch all libraries
|
||||
./bin/spc fetch --all
|
||||
# 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-all
|
||||
./bin/spc build bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl --build-cli --build-micro
|
||||
```
|
||||
|
||||
You can also use the parameter `--with-php=x.y` to specify the downloaded PHP version, currently supports 7.4 ~ 8.2:
|
||||
@ -102,10 +102,17 @@ You can also use the parameter `--with-php=x.y` to specify the downloaded PHP ve
|
||||
./bin/spc fetch --with-php=8.2 --all
|
||||
```
|
||||
|
||||
Now we support `cli`, `micro`, `fpm`, 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-all`: build all
|
||||
|
||||
If anything goes wrong, use `--debug` option to display full terminal output:
|
||||
|
||||
```bash
|
||||
./bin/spc build openssl,pcntl,mbstring --debug
|
||||
./bin/spc build openssl,pcntl,mbstring --debug --build-all
|
||||
./bin/spc fetch --all --debug
|
||||
```
|
||||
|
||||
@ -113,7 +120,7 @@ If anything goes wrong, use `--debug` option to display full terminal output:
|
||||
|
||||
> php-cli is a single static binary, you can use it like normal php installed on your system.
|
||||
|
||||
When using the parameter `--build-all` or not adding the `--build-micro` parameter,
|
||||
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.
|
||||
@ -149,6 +156,17 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
|
||||
> In some cases, PHAR files may not run in a micro environment.
|
||||
|
||||
### php-fpm Usage
|
||||
|
||||
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 normal 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`.
|
||||
|
||||
## Current Status
|
||||
|
||||
- [X] Basic CLI framework (by `symfony/console`)
|
||||
@ -157,7 +175,7 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
- [X] Exception handler
|
||||
- [ ] Windows support
|
||||
- [X] PHP 7.4 support
|
||||
- [ ] fpm support
|
||||
- [X] fpm support
|
||||
|
||||
More functions and features are coming soon, Bugs and TODOs: https://github.com/crazywhalecc/static-php-cli/issues/32
|
||||
|
||||
|
||||
29
README.md
29
README.md
@ -89,7 +89,7 @@ chmod +x bin/spc
|
||||
# 拉取所有依赖库
|
||||
./bin/spc fetch --all
|
||||
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
|
||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-all
|
||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
|
||||
```
|
||||
|
||||
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.4 ~ 8.2:
|
||||
@ -99,10 +99,17 @@ chmod +x bin/spc
|
||||
./bin/spc fetch --with-php=8.2 --all
|
||||
```
|
||||
|
||||
其中,目前支持构建 cli,micro,fpm 三种静态二进制,使用以下参数的一个或多个来指定编译的 SAPI:
|
||||
|
||||
- `--build-cli`:构建 cli 二进制
|
||||
- `--build-micro`:构建 phpmicro 自执行二进制
|
||||
- `--build-fpm`:构建 fpm
|
||||
- `--build-all`:构建所有
|
||||
|
||||
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
|
||||
|
||||
```bash
|
||||
./bin/spc build openssl,pcntl,mbstring --debug
|
||||
./bin/spc build openssl,pcntl,mbstring --debug --build-all
|
||||
./bin/spc fetch --all --debug
|
||||
```
|
||||
|
||||
@ -110,7 +117,7 @@ chmod +x bin/spc
|
||||
|
||||
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
|
||||
|
||||
采用参数 `--build-all` 或不添加 `--build-micro` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
|
||||
采用参数 `--build-cli` 或`--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
|
||||
|
||||
```bash
|
||||
@ -125,8 +132,8 @@ cd buildroot/bin/
|
||||
|
||||
> phpmicro 是一个提供自执行二进制 PHP 的项目,本项目依赖 phpmicro 进行编译自执行二进制。详见 [dixyes/phpmicro](https://github.com/dixyes/phpmicro)。
|
||||
|
||||
采用项目参数 `--build-all` 或 `--build-micro` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
|
||||
该文件编译后会存放在 `source/php-src/sapi/micro/` 目录中,拷贝出来即可。
|
||||
采用项目参数 `--build-micro` 或 `--build-all` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,拷贝出来即可。
|
||||
|
||||
使用时应准备好你的项目源码文件,可以是单个 PHP 文件,也可以是 Phar 文件。
|
||||
|
||||
@ -140,6 +147,16 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
|
||||
> 有些情况下的 phar 文件可能无法在 micro 环境下运行。
|
||||
|
||||
### 使用 php-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`。
|
||||
|
||||
## 项目支持情况
|
||||
|
||||
- [X] 基础结构编写(采用 `symfony/console`)
|
||||
@ -148,7 +165,7 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
- [ ] Windows 支持
|
||||
- [X] Linux 支持
|
||||
- [X] PHP 7.4 支持
|
||||
- [ ] fpm 支持
|
||||
- [X] fpm 支持
|
||||
|
||||
更多功能和特性正在陆续支持中,详见:https://github.com/crazywhalecc/static-php-cli/issues/32
|
||||
|
||||
|
||||
@ -296,9 +296,9 @@
|
||||
}
|
||||
},
|
||||
"zlib": {
|
||||
"type": "filelist",
|
||||
"url": "https://zlib.net/",
|
||||
"regex": "/href=\"(?<file>zlib-(?<version>[^\"]+)\\.tar\\.gz)\"/i",
|
||||
"type": "ghrel",
|
||||
"repo": "madler/zlib",
|
||||
"match": "zlib.+\\.tar\\.gz",
|
||||
"license": {
|
||||
"type": "text",
|
||||
"text": "(C) 1995-2022 Jean-loup Gailly and Mark Adler\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n claim that you wrote the original software. If you use this software\n in a product, an acknowledgment in the product documentation would be\n appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution.\n\nJean-loup Gailly Mark Adler\njloup@gzip.org madler@alumni.caltech.edu"
|
||||
|
||||
113
ext-support.md
113
ext-support.md
@ -6,57 +6,56 @@
|
||||
> - no with issue link: not supported yet due to issue
|
||||
> - partial with issue link: supported but not perfect due to issue
|
||||
|
||||
| | Linux | macOS | Windows |
|
||||
|------------|--------------------------------------------------------------------|---------------------------------------------------------------------|---------|
|
||||
| bcmath | yes | yes | |
|
||||
| bz2 | yes | yes | |
|
||||
| calendar | yes | yes | |
|
||||
| ctype | yes | yes | |
|
||||
| curl | yes | yes | |
|
||||
| date | yes | yes | |
|
||||
| dba | yes | yes | |
|
||||
| dom | yes | yes | |
|
||||
| enchant | | | |
|
||||
| event | | | |
|
||||
| exif | yes | yes | |
|
||||
| filter | yes | yes | |
|
||||
| fileinfo | yes | | |
|
||||
| ftp | yes | yes | |
|
||||
| gd | yes, untested | yes | |
|
||||
| gettext | | | |
|
||||
| gmp | yes, untested | yes, untested | |
|
||||
| iconv | yes | | |
|
||||
| inotify | yes | yes | |
|
||||
| mbstring | yes | yes | |
|
||||
| mcrypt | | [faulty](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| mongodb | yes, untested | | |
|
||||
| mysqli | | | |
|
||||
| mysqlnd | yes | yes | |
|
||||
| openssl | yes | yes | |
|
||||
| pcntl | yes, untested | yes | |
|
||||
| pdo | yes | yes | |
|
||||
| pdo_mysql | yes | yes | |
|
||||
| pdo_sqlite | yes | yes | |
|
||||
| pdo_pgsql | | | |
|
||||
| phar | yes | yes | |
|
||||
| posix | yes | yes | |
|
||||
| protobuf | yes, untested | | |
|
||||
| readline | | | |
|
||||
| redis | yes | yes | |
|
||||
| session | yes | yes | |
|
||||
| shmop | yes, untested | | |
|
||||
| simplexml | yes, untested | yes, untested | |
|
||||
| soap | yes, untested | | |
|
||||
| sockets | yes | yes | |
|
||||
| sqlite3 | yes, untested | yes, untested | |
|
||||
| swow | yes | [faulty](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| swoole | [faulty](https://github.com/crazywhalecc/static-php-cli/issues/32) | [partial](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| tokenizer | yes | yes | |
|
||||
| xml | yes | yes | |
|
||||
| xmlreader | yes, untested | yes, untested | |
|
||||
| xmlwriter | yes, untested | yes, untested | |
|
||||
| zip | yes, untested | yes | |
|
||||
| zlib | yes | yes | |
|
||||
| | Linux | macOS | Windows |
|
||||
|------------|----------------------------------------------------------------|---------------------------------------------------------------------|---------|
|
||||
| bcmath | yes | yes | |
|
||||
| bz2 | yes | yes | |
|
||||
| calendar | yes | yes | |
|
||||
| ctype | yes | yes | |
|
||||
| curl | yes | yes | |
|
||||
| dba | yes | yes | |
|
||||
| dom | yes | yes | |
|
||||
| enchant | | | |
|
||||
| event | | | |
|
||||
| exif | yes | yes | |
|
||||
| filter | yes | yes | |
|
||||
| fileinfo | yes | | |
|
||||
| ftp | yes | yes | |
|
||||
| gd | yes, untested | yes | |
|
||||
| gettext | | | |
|
||||
| gmp | yes, untested | yes, untested | |
|
||||
| iconv | yes | | |
|
||||
| inotify | yes | yes | |
|
||||
| mbstring | yes | yes | |
|
||||
| mcrypt | | [faulty](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| mongodb | yes, untested | | |
|
||||
| mysqli | | | |
|
||||
| mysqlnd | yes | yes | |
|
||||
| openssl | yes | yes | |
|
||||
| pcntl | yes, untested | yes | |
|
||||
| pdo | yes | yes | |
|
||||
| pdo_mysql | yes | yes | |
|
||||
| pdo_sqlite | yes | yes | |
|
||||
| pdo_pgsql | | | |
|
||||
| phar | yes | yes | |
|
||||
| posix | yes | yes | |
|
||||
| protobuf | yes, untested | | |
|
||||
| readline | | | |
|
||||
| redis | yes | yes | |
|
||||
| session | yes | yes | |
|
||||
| shmop | yes, untested | | |
|
||||
| simplexml | yes, untested | yes, untested | |
|
||||
| soap | yes, untested | | |
|
||||
| sockets | yes | yes | |
|
||||
| sqlite3 | yes, untested | yes, untested | |
|
||||
| swow | yes | [no](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| swoole | [no](https://github.com/crazywhalecc/static-php-cli/issues/32) | [partial](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| tokenizer | yes | yes | |
|
||||
| xml | yes | yes | |
|
||||
| xmlreader | yes, untested | yes, untested | |
|
||||
| xmlwriter | yes, untested | yes, untested | |
|
||||
| zip | yes, untested | yes | |
|
||||
| zlib | yes | yes | |
|
||||
|
||||
## Additional Requirements
|
||||
|
||||
@ -64,11 +63,21 @@
|
||||
- swoole >= 5.0 requires PHP >= 8.0
|
||||
- swow requires PHP >= 8.0
|
||||
|
||||
## Typical Extension List Example
|
||||
|
||||
Here are some extension list example for different use.
|
||||
|
||||
- For general use: `"bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,ftp,filter,gd,iconv,xml,mbstring,mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip"`
|
||||
- For static-php-cli self: `"posix,pcntl,phar,tokenizer,iconv,zlib"`
|
||||
- For static-php-cli self (with dev dependencies): `"posix,pcntl,phar,tokenizer,iconv,zlib,xml,dom,xmlwriter,xmlreader,fileinfo"`
|
||||
- Minimum, with no extension: `""`
|
||||
|
||||
## Limitations
|
||||
|
||||
- swow and swoole cannot be compiled at the same time.
|
||||
- openssl needs manual configuration for ssl certificate. (TODO: I will write a wiki about it)
|
||||
- some extensions need system configuration, e.g. `curl` and `openssl` will search ssl certificate on your system.
|
||||
|
||||
## Bugs
|
||||
## Bugs and TODOs
|
||||
|
||||
See [#32](https://github.com/crazywhalecc/static-php-cli/issues/32).
|
||||
|
||||
@ -170,15 +170,11 @@ abstract class BuilderBase
|
||||
|
||||
/**
|
||||
* 开始构建 PHP
|
||||
* 构建 micro 的规则:
|
||||
* - BUILD_MICRO_NONE(默认):只编译 cli
|
||||
* - BUILD_MICRO_ONLY:只编译 micro
|
||||
* - BUILD_MICRO_BOTH:同时编译 micro 和 cli
|
||||
*
|
||||
* @param int $build_micro_rule 规则
|
||||
* @param bool $bloat 保留
|
||||
* @param int $build_target 规则
|
||||
* @param bool $bloat 保留
|
||||
*/
|
||||
abstract public function buildPHP(int $build_micro_rule = BUILD_MICRO_NONE, bool $bloat = false);
|
||||
abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = false);
|
||||
|
||||
/**
|
||||
* 生成依赖的扩展编译启用参数
|
||||
@ -215,6 +211,21 @@ abstract class BuilderBase
|
||||
return intval($match[1]);
|
||||
}
|
||||
|
||||
public function getBuildTypeName(int $type): string
|
||||
{
|
||||
$ls = [];
|
||||
if (($type & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||
$ls[] = 'cli';
|
||||
}
|
||||
if (($type & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||
$ls[] = 'micro';
|
||||
}
|
||||
if (($type & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
||||
$ls[] = 'fpm';
|
||||
}
|
||||
return implode(', ', $ls);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否存在 lib 库对应的源码,如果不存在,则抛出异常
|
||||
*
|
||||
|
||||
@ -133,7 +133,7 @@ abstract class LibraryBase
|
||||
{
|
||||
// 传入 true,表明直接编译
|
||||
if ($force_build) {
|
||||
logger()->info('Building required library ' . static::NAME);
|
||||
logger()->info('Building required library [' . static::NAME . ']');
|
||||
$this->build();
|
||||
return BUILD_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ class LinuxBuilder extends BuilderBase
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function buildPHP(int $build_micro_rule = BUILD_MICRO_NONE, bool $with_clean = false, bool $bloat = false)
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean = false, bool $bloat = false)
|
||||
{
|
||||
if (!$bloat) {
|
||||
$extra_libs = implode(' ', $this->getAllStaticLibFiles());
|
||||
@ -176,6 +176,7 @@ class LinuxBuilder extends BuilderBase
|
||||
'--disable-cgi ' .
|
||||
'--disable-phpdbg ' .
|
||||
'--enable-cli ' .
|
||||
'--enable-fpm ' .
|
||||
'--enable-micro=all-static ' .
|
||||
($this->zts ? '--enable-zts' : '') . ' ' .
|
||||
$this->makeExtensionArgs() . ' ' .
|
||||
@ -194,31 +195,26 @@ class LinuxBuilder extends BuilderBase
|
||||
$extra_libs = "-Wl,--whole-archive {$extra_libs} -Wl,--no-whole-archive";
|
||||
}
|
||||
|
||||
switch ($build_micro_rule) {
|
||||
case BUILD_MICRO_NONE:
|
||||
logger()->info('building cli');
|
||||
$this->buildCli($extra_libs, $use_lld);
|
||||
break;
|
||||
case BUILD_MICRO_ONLY:
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro($extra_libs, $use_lld, $cflags);
|
||||
break;
|
||||
case BUILD_MICRO_BOTH:
|
||||
logger()->info('building cli and micro');
|
||||
$this->buildCli($extra_libs, $use_lld);
|
||||
$this->buildMicro($extra_libs, $use_lld, $cflags);
|
||||
break;
|
||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||
logger()->info('building cli');
|
||||
$this->buildCli($extra_libs, $use_lld);
|
||||
}
|
||||
if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
||||
logger()->info('building fpm');
|
||||
$this->buildFpm($extra_libs, $use_lld);
|
||||
}
|
||||
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro($extra_libs, $use_lld, $cflags);
|
||||
}
|
||||
|
||||
if (php_uname('m') === $this->arch) {
|
||||
$this->sanityCheck($build_micro_rule);
|
||||
$this->sanityCheck($build_target);
|
||||
}
|
||||
|
||||
if ($this->phar_patched) {
|
||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('patch -p1 -R < sapi/micro/patches/phar.patch');
|
||||
}
|
||||
|
||||
file_put_contents(SOURCE_PATH . '/php-src/.extensions.json', json_encode($this->plain_extensions, JSON_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +237,7 @@ class LinuxBuilder extends BuilderBase
|
||||
->exec('elfedit --output-osabi linux php')
|
||||
->exec("{$this->cross_compile_prefix}strip --strip-all php")
|
||||
->exec("{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php.debug --remove-section=.note php");
|
||||
$this->deployBinary(BUILD_TYPE_CLI);
|
||||
$this->deployBinary(BUILD_TARGET_CLI);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -274,7 +270,30 @@ class LinuxBuilder extends BuilderBase
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec("{$this->cross_compile_prefix}strip --strip-all micro.sfx");
|
||||
|
||||
$this->deployBinary(BUILD_TYPE_MICRO);
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function buildFpm(string $extra_libs, string $use_lld): void
|
||||
{
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||
->exec(
|
||||
'make -j' . $this->concurrency .
|
||||
' EXTRA_CFLAGS="-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . '" ' .
|
||||
"EXTRA_LIBS=\"{$extra_libs}\" " .
|
||||
"EXTRA_LDFLAGS_PROGRAM='{$use_lld} -all-static' " .
|
||||
'fpm'
|
||||
);
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')
|
||||
->exec("{$this->cross_compile_prefix}objcopy --only-keep-debug php-fpm php-fpm.debug")
|
||||
->exec('elfedit --output-osabi linux php-fpm')
|
||||
->exec("{$this->cross_compile_prefix}strip --strip-all php-fpm")
|
||||
->exec("{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php-fpm.debug --remove-section=.note php-fpm");
|
||||
$this->deployBinary(BUILD_TARGET_FPM);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -42,7 +42,7 @@ abstract class LinuxLibraryBase extends LibraryBase
|
||||
{
|
||||
// 传入 true,表明直接编译
|
||||
if ($force_build) {
|
||||
logger()->info('Building required library ' . static::NAME);
|
||||
logger()->info('Building required library [' . static::NAME . ']');
|
||||
$this->build();
|
||||
return BUILD_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ class MacOSBuilder extends BuilderBase
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function buildPHP(int $build_micro_rule = BUILD_MICRO_NONE, bool $bloat = false): void
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = false): void
|
||||
{
|
||||
$extra_libs = $this->getFrameworks(true) . ' ' . ($this->getExt('swoole') ? '-lc++ ' : '');
|
||||
if (!$bloat) {
|
||||
@ -159,6 +159,7 @@ class MacOSBuilder extends BuilderBase
|
||||
'--disable-cgi ' .
|
||||
'--disable-phpdbg ' .
|
||||
'--enable-cli ' .
|
||||
'--enable-fpm ' .
|
||||
'--enable-micro ' .
|
||||
($this->zts ? '--enable-zts' : '') . ' ' .
|
||||
$this->makeExtensionArgs() . ' ' .
|
||||
@ -167,24 +168,21 @@ class MacOSBuilder extends BuilderBase
|
||||
|
||||
$this->cleanMake();
|
||||
|
||||
switch ($build_micro_rule) {
|
||||
case BUILD_MICRO_NONE:
|
||||
logger()->info('building cli');
|
||||
$this->buildCli($extra_libs);
|
||||
break;
|
||||
case BUILD_MICRO_ONLY:
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro($extra_libs);
|
||||
break;
|
||||
case BUILD_MICRO_BOTH:
|
||||
logger()->info('building cli and micro');
|
||||
$this->buildCli($extra_libs);
|
||||
$this->buildMicro($extra_libs);
|
||||
break;
|
||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||
logger()->info('building cli');
|
||||
$this->buildCli($extra_libs);
|
||||
}
|
||||
if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
||||
logger()->info('building fpm');
|
||||
$this->buildFpm($extra_libs);
|
||||
}
|
||||
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro($extra_libs);
|
||||
}
|
||||
|
||||
if (php_uname('m') === $this->arch) {
|
||||
$this->sanityCheck($build_micro_rule);
|
||||
$this->sanityCheck($build_target);
|
||||
}
|
||||
|
||||
if ($this->phar_patched) {
|
||||
@ -193,9 +191,24 @@ class MacOSBuilder extends BuilderBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 phpmicro
|
||||
* 构建 cli
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function buildCli(string $extra_libs): void
|
||||
{
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli")
|
||||
->exec('dsymutil -f sapi/cli/php')
|
||||
->exec('strip sapi/cli/php');
|
||||
$this->deployBinary(BUILD_TARGET_CLI);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 phpmicro
|
||||
*
|
||||
* @throws FileSystemException|RuntimeException
|
||||
*/
|
||||
public function buildMicro(string $extra_libs): void
|
||||
{
|
||||
@ -215,22 +228,21 @@ class MacOSBuilder extends BuilderBase
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" STRIP=\"dsymutil -f \" micro");
|
||||
$this->deployBinary(BUILD_TYPE_MICRO);
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 cli
|
||||
* 构建 fpm
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function buildCli(string $extra_libs): void
|
||||
public function buildFpm(string $extra_libs): void
|
||||
{
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
// 生成调试信息、优化编译后的尺寸、禁用标识符(如变量、函数名)缩短
|
||||
->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli")
|
||||
->exec('dsymutil -f sapi/cli/php')
|
||||
->exec('strip sapi/cli/php');
|
||||
$this->deployBinary(BUILD_TYPE_CLI);
|
||||
->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" fpm")
|
||||
->exec('dsymutil -f sapi/fpm/php-fpm')
|
||||
->exec('strip sapi/fpm/php-fpm');
|
||||
$this->deployBinary(BUILD_TARGET_FPM);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\traits;
|
||||
|
||||
/**
|
||||
* 仅供 Command 使用,如果使用了该 Trait,则在执行对应命令时不打印 motd
|
||||
*/
|
||||
trait NoMotdTrait
|
||||
{
|
||||
protected bool $no_motd = true;
|
||||
}
|
||||
@ -56,12 +56,15 @@ trait UnixBuilderTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanity check after build complete
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function sanityCheck(int $build_micro_rule): void
|
||||
public function sanityCheck(int $build_target): void
|
||||
{
|
||||
logger()->info('running sanity check');
|
||||
if ($build_micro_rule !== BUILD_MICRO_ONLY) {
|
||||
// sanity check for php-cli
|
||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||
logger()->info('running cli sanity check');
|
||||
[$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"');
|
||||
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
|
||||
throw new RuntimeException('cli failed sanity check');
|
||||
@ -80,7 +83,9 @@ trait UnixBuilderTrait
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($build_micro_rule !== BUILD_MICRO_NONE) {
|
||||
|
||||
// sanity check for phpmicro
|
||||
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||
if (file_exists(SOURCE_PATH . '/hello.exe')) {
|
||||
@unlink(SOURCE_PATH . '/hello.exe');
|
||||
}
|
||||
@ -107,11 +112,12 @@ trait UnixBuilderTrait
|
||||
public function deployBinary(int $type): bool
|
||||
{
|
||||
$src = match ($type) {
|
||||
BUILD_TYPE_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
|
||||
BUILD_TYPE_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
|
||||
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
|
||||
BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
|
||||
BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm',
|
||||
default => throw new RuntimeException('Deployment does not accept type ' . $type),
|
||||
};
|
||||
logger()->info('Deploying ' . ($type === BUILD_TYPE_CLI ? 'cli' : 'micro') . ' file');
|
||||
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
||||
FileSystem::createDir(BUILD_ROOT_PATH . '/bin');
|
||||
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '/bin/'));
|
||||
return true;
|
||||
|
||||
@ -13,6 +13,8 @@ use ZM\Logger\ConsoleLogger;
|
||||
|
||||
abstract class BaseCommand extends Command
|
||||
{
|
||||
protected bool $no_motd = false;
|
||||
|
||||
/**
|
||||
* 输入
|
||||
*/
|
||||
@ -29,10 +31,14 @@ abstract class BaseCommand extends Command
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->addOption('debug', null, null, 'Enable debug mode');
|
||||
$this->addOption('no-motd', null, null, 'Disable motd');
|
||||
}
|
||||
|
||||
public function initialize(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($input->getOption('no-motd')) {
|
||||
$this->no_motd = true;
|
||||
}
|
||||
// 注册全局错误处理器
|
||||
set_error_handler(static function ($error_no, $error_msg, $error_file, $error_line) {
|
||||
$tips = [
|
||||
@ -58,7 +64,7 @@ abstract class BaseCommand extends Command
|
||||
define('DEBUG_MODE', true);
|
||||
}
|
||||
$version = ConsoleApplication::VERSION;
|
||||
if (!isset($this->no_motd)) {
|
||||
if (!$this->no_motd) {
|
||||
echo " _ _ _ _
|
||||
___| |_ __ _| |_(_) ___ _ __ | |__ _ __
|
||||
/ __| __/ _` | __| |/ __|____| '_ \\| '_ \\| '_ \\
|
||||
|
||||
@ -12,6 +12,7 @@ use SPC\util\LicenseDumper;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use ZM\Logger\ConsoleColor;
|
||||
|
||||
#[AsCommand('build', 'build CLI binary')]
|
||||
class BuildCliCommand extends BuildCommand
|
||||
@ -20,8 +21,10 @@ class BuildCliCommand extends BuildCommand
|
||||
{
|
||||
$this->addArgument('extensions', InputArgument::REQUIRED, 'The extensions will be compiled, comma separated');
|
||||
$this->addOption('with-libs', null, InputOption::VALUE_REQUIRED, 'add additional libraries, comma separated', '');
|
||||
$this->addOption('build-micro', null, null, 'build micro only');
|
||||
$this->addOption('build-all', null, null, 'build both cli and micro');
|
||||
$this->addOption('build-micro', null, null, 'build micro');
|
||||
$this->addOption('build-cli', null, null, 'build cli');
|
||||
$this->addOption('build-fpm', null, null, 'build fpm');
|
||||
$this->addOption('build-all', null, null, 'build cli, micro, fpm');
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
@ -33,24 +36,30 @@ class BuildCliCommand extends BuildCommand
|
||||
|
||||
define('BUILD_ALL_STATIC', true);
|
||||
|
||||
if ($this->getOption('build-all')) {
|
||||
$rule = BUILD_MICRO_BOTH;
|
||||
logger()->info('Builder will build php-cli and phpmicro SAPI');
|
||||
} elseif ($this->getOption('build-micro')) {
|
||||
$rule = BUILD_MICRO_ONLY;
|
||||
logger()->info('Builder will build phpmicro SAPI');
|
||||
} else {
|
||||
$rule = BUILD_MICRO_NONE;
|
||||
logger()->info('Builder will build php-cli SAPI');
|
||||
$rule = BUILD_TARGET_NONE;
|
||||
$rule = $rule | ($this->getOption('build-cli') ? BUILD_TARGET_CLI : BUILD_TARGET_NONE);
|
||||
$rule = $rule | ($this->getOption('build-micro') ? BUILD_TARGET_MICRO : BUILD_TARGET_NONE);
|
||||
$rule = $rule | ($this->getOption('build-fpm') ? BUILD_TARGET_FPM : BUILD_TARGET_NONE);
|
||||
$rule = $rule | ($this->getOption('build-all') ? BUILD_TARGET_ALL : BUILD_TARGET_NONE);
|
||||
if ($rule === BUILD_TARGET_NONE) {
|
||||
$this->output->writeln('<error>Please add at least one build target!</error>');
|
||||
$this->output->writeln("<comment>\t--build-cli\tBuild php-cli SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-micro\tBuild phpmicro SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-fpm\tBuild php-fpm SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-all\tBuild all SAPI: cli, micro, fpm</comment>");
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
// 构建对象
|
||||
$builder = BuilderProvider::makeBuilderByInput($this->input);
|
||||
// 根据提供的扩展列表获取依赖库列表并编译
|
||||
[$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries);
|
||||
|
||||
logger()->info('Enabled extensions: ' . implode(', ', $extensions));
|
||||
logger()->info('Required libraries: ' . implode(', ', $libraries));
|
||||
/* @phpstan-ignore-next-line */
|
||||
logger()->info('Build target: ' . ConsoleColor::yellow($builder->getBuildTypeName($rule)));
|
||||
/* @phpstan-ignore-next-line */
|
||||
logger()->info('Enabled extensions: ' . ConsoleColor::yellow(implode(', ', $extensions)));
|
||||
/* @phpstan-ignore-next-line */
|
||||
logger()->info('Required libraries: ' . ConsoleColor::yellow(implode(', ', $libraries)));
|
||||
if (!empty($not_included)) {
|
||||
logger()->warning('some extensions will be enabled due to dependencies: ' . implode(',', $not_included));
|
||||
}
|
||||
@ -64,12 +73,15 @@ class BuildCliCommand extends BuildCommand
|
||||
// 统计时间
|
||||
$time = round(microtime(true) - START_TIME, 3);
|
||||
logger()->info('Build complete, used ' . $time . ' s !');
|
||||
if ($rule !== BUILD_MICRO_ONLY) {
|
||||
if (($rule & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||
logger()->info('Static php binary path: ' . BUILD_ROOT_PATH . '/bin/php');
|
||||
}
|
||||
if ($rule !== BUILD_MICRO_NONE) {
|
||||
if (($rule & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||
logger()->info('phpmicro binary path: ' . BUILD_ROOT_PATH . '/bin/micro.sfx');
|
||||
}
|
||||
if (($rule & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
||||
logger()->info('Static php-fpm binary path: ' . BUILD_ROOT_PATH . '/bin/php-fpm');
|
||||
}
|
||||
// 导出相关元数据
|
||||
file_put_contents(BUILD_ROOT_PATH . '/build-extensions.json', json_encode($extensions, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||
file_put_contents(BUILD_ROOT_PATH . '/build-libraries.json', json_encode($libraries, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||
|
||||
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\command;
|
||||
|
||||
use SPC\builder\traits\NoMotdTrait;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\Config;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
@ -12,7 +11,7 @@ use Symfony\Component\Console\Attribute\AsCommand;
|
||||
#[AsCommand('list-ext', 'List supported extensions')]
|
||||
class ListExtCommand extends BaseCommand
|
||||
{
|
||||
use NoMotdTrait;
|
||||
protected bool $no_motd = true;
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
|
||||
@ -33,20 +33,17 @@ const REPLACE_FILE_STR = 1;
|
||||
const REPLACE_FILE_PREG = 2;
|
||||
const REPLACE_FILE_USER = 3;
|
||||
|
||||
// build sapi type
|
||||
const BUILD_MICRO_NONE = 0;
|
||||
const BUILD_MICRO_ONLY = 1;
|
||||
const BUILD_MICRO_BOTH = 2;
|
||||
|
||||
// library build status
|
||||
const BUILD_STATUS_OK = 0;
|
||||
const BUILD_STATUS_ALREADY = 1;
|
||||
const BUILD_STATUS_FAILED = 2;
|
||||
|
||||
// build target type
|
||||
const BUILD_TYPE_CLI = 1;
|
||||
const BUILD_TYPE_MICRO = 2;
|
||||
const BUILD_TYPE_FPM = 3;
|
||||
const BUILD_TARGET_NONE = 0;
|
||||
const BUILD_TARGET_CLI = 1;
|
||||
const BUILD_TARGET_MICRO = 2;
|
||||
const BUILD_TARGET_FPM = 4;
|
||||
const BUILD_TARGET_ALL = 7;
|
||||
|
||||
// doctor error fix policy
|
||||
const FIX_POLICY_DIE = 1; // die directly
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user