mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-08 17:35:36 +08:00
Compare commits
55 Commits
f2e483540b
...
2.0-rc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7730735c0 | ||
|
|
752b88f62d | ||
|
|
6131e1881b | ||
|
|
980da4ea0f | ||
|
|
b698ae2f50 | ||
|
|
50632f6527 | ||
|
|
6d4755d8c9 | ||
|
|
75b85c26dc | ||
|
|
1c8bbfbbdf | ||
|
|
c5a70f101a | ||
|
|
956c87a657 | ||
|
|
778b0eadcd | ||
|
|
b8e6f9d1be | ||
|
|
0e024a8c43 | ||
|
|
65b0bd01c8 | ||
|
|
3745dfc931 | ||
|
|
0186ae5ff2 | ||
|
|
f1eacac4fd | ||
|
|
4abe0064e6 | ||
|
|
cbc3adbec0 | ||
|
|
0902f80b46 | ||
|
|
47101d058b | ||
|
|
bc978ecbde | ||
|
|
a2cb5165d3 | ||
|
|
e582fa8b22 | ||
|
|
8ec8838634 | ||
|
|
8f259ffed9 | ||
|
|
74c2cf824b | ||
|
|
9ea3b04e82 | ||
|
|
99cb8c77b7 | ||
|
|
7056280c57 | ||
|
|
c14421c9ca | ||
|
|
97eff64b5b | ||
|
|
e522258693 | ||
|
|
b84c68fe11 | ||
|
|
8505feaa66 | ||
|
|
41f49c20ff | ||
|
|
1912ae36e6 | ||
|
|
08efc81cf0 | ||
|
|
a3b09c69cc | ||
|
|
5cf105c3a5 | ||
|
|
7408781d13 | ||
|
|
0afc8ea2c3 | ||
|
|
67b073776c | ||
|
|
8b48cf7f70 | ||
|
|
63287dd9c4 | ||
|
|
fc7ac921e2 | ||
|
|
57e3193a2a | ||
|
|
388f547878 | ||
|
|
085437e925 | ||
|
|
fa17a48483 | ||
|
|
78c1484570 | ||
|
|
9c2ea79bec | ||
|
|
b7ffe3fd1f | ||
|
|
dac14ae16e |
9
.github/workflows/build-linux-x86_64.yml
vendored
9
.github/workflows/build-linux-x86_64.yml
vendored
@@ -77,10 +77,10 @@ jobs:
|
|||||||
|
|
||||||
# If there's no dependencies cache, fetch sources, with or without debug
|
# If there's no dependencies cache, fetch sources, with or without debug
|
||||||
- if: steps.cache-download.outputs.cache-hit != 'true'
|
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||||
run: CACHE_API_EXEC=yes ./bin/spc download --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
|
run: CACHE_API_EXEC=yes ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
|
||||||
|
|
||||||
# Run build command
|
# Run build command
|
||||||
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
- run: ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||||
|
|
||||||
# Upload cli executable
|
# Upload cli executable
|
||||||
- if: ${{ inputs.build-cli == true }}
|
- if: ${{ inputs.build-cli == true }}
|
||||||
@@ -115,8 +115,3 @@ jobs:
|
|||||||
buildroot/build-extensions.json
|
buildroot/build-extensions.json
|
||||||
buildroot/build-libraries.json
|
buildroot/build-libraries.json
|
||||||
|
|
||||||
# Upload downloaded files
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: download-files
|
|
||||||
path: downloads/
|
|
||||||
|
|||||||
5
.github/workflows/build-macos-x86_64.yml
vendored
5
.github/workflows/build-macos-x86_64.yml
vendored
@@ -115,8 +115,3 @@ jobs:
|
|||||||
buildroot/build-extensions.json
|
buildroot/build-extensions.json
|
||||||
buildroot/build-libraries.json
|
buildroot/build-libraries.json
|
||||||
|
|
||||||
# Upload downloaded files
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: download-files
|
|
||||||
path: downloads/
|
|
||||||
|
|||||||
29
README-en.md
29
README-en.md
@@ -11,14 +11,16 @@ This feature is provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro
|
|||||||
|
|
||||||
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
|
|
||||||
|
> The project has renamed the `refactor` branch to the `main` branch, please pay attention to changing the branch name for dependent projects.
|
||||||
|
|
||||||
## Compilation Requirements
|
## Compilation Requirements
|
||||||
|
|
||||||
Yes, this project is written in PHP, pretty funny.
|
Yes, this project is written in PHP, pretty funny.
|
||||||
@@ -37,7 +39,11 @@ Here is the architecture support status, where `CI` represents support for GitHu
|
|||||||
|
|
||||||
Currently supported PHP versions for compilation are: `7.4`, `8.0`, `8.1`, `8.2`.
|
Currently supported PHP versions for compilation are: `7.4`, `8.0`, `8.1`, `8.2`.
|
||||||
|
|
||||||
## Usage
|
## Docs
|
||||||
|
|
||||||
|
docs here: <https://static-php-cli.zhamao.me>.
|
||||||
|
|
||||||
|
## Simple Usage
|
||||||
|
|
||||||
Please first select the extension you want to compile based on the extension list below.
|
Please first select the extension you want to compile based on the extension list below.
|
||||||
|
|
||||||
@@ -49,7 +55,7 @@ If you don't compile yourself, you can download pre-compiled artifact from Actio
|
|||||||
|
|
||||||
### Supported Extensions
|
### Supported Extensions
|
||||||
|
|
||||||
[Supported Extension List](/ext-support.md)
|
[Supported Extension List](https://static-php-cli.zhamao.me/en/guide/extensions.html)
|
||||||
|
|
||||||
> If there is no extension you need here, you can submit an issue.
|
> If there is no extension you need here, you can submit an issue.
|
||||||
|
|
||||||
@@ -100,7 +106,7 @@ Basic usage for building php and micro with some extensions:
|
|||||||
cd static-php-cli
|
cd static-php-cli
|
||||||
composer update
|
composer update
|
||||||
chmod +x bin/spc
|
chmod +x bin/spc
|
||||||
# Check system tool dependencies, fix them automatically (only support macOS) (TODO: Linux distro support)
|
# Check system tool dependencies, fix them automatically
|
||||||
./bin/spc doctor
|
./bin/spc doctor
|
||||||
# fetch all libraries
|
# fetch all libraries
|
||||||
./bin/spc fetch --all
|
./bin/spc fetch --all
|
||||||
@@ -217,6 +223,13 @@ The basic principles for contributing are as follows:
|
|||||||
camelCase and underscore formats should be followed, and mixing within the same module is prohibited.
|
camelCase and underscore formats should be followed, and mixing within the same module is prohibited.
|
||||||
- When compiling external libraries and creating patches, compatibility with different operating systems should be considered.
|
- When compiling external libraries and creating patches, compatibility with different operating systems should be considered.
|
||||||
|
|
||||||
|
If you want to contribute document content, please go to [crazywhalecc/static-php-cli-docs](https://github.com/crazywhalecc/static-php-cli-docs).
|
||||||
|
|
||||||
|
Part of the English document is written by me, and part is translated by Google,
|
||||||
|
and there may be inaccurate descriptions, strange or offensive expressions.
|
||||||
|
If you are a native English speaker, some corrections to the documentation are welcome.
|
||||||
|
|
||||||
|
|
||||||
## Sponsor this project
|
## Sponsor this project
|
||||||
|
|
||||||
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
|
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
|
||||||
@@ -238,6 +251,6 @@ and comply with the corresponding project's LICENSE.
|
|||||||
|
|
||||||
## Advanced
|
## Advanced
|
||||||
|
|
||||||
This project is pure open source project, and some modules are separated for developing.
|
The refactoring branch of this project is written modularly.
|
||||||
|
If you are interested in this project and want to join the development,
|
||||||
This section will be improved after refactor version released.
|
you can refer to the [Contribution Guide](https://static-php-cli.zhamao.me) of the documentation to contribute code or documentation. (TODO)
|
||||||
|
|||||||
22
README.md
22
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Compile A Statically Linked PHP With Swoole and other Extensions.
|
Compile A Statically Linked PHP With Swoole and other Extensions.
|
||||||
|
|
||||||
If you are using English, see [English README](README-en.md).
|
**If you are using English, see [English README](README-en.md).**
|
||||||
|
|
||||||
编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携!(cli SAPI)
|
编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携!(cli SAPI)
|
||||||
|
|
||||||
@@ -12,13 +12,15 @@ If you are using English, see [English README](README-en.md).
|
|||||||
|
|
||||||
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||||
[]()
|
[]()
|
||||||
[]()
|
[]()
|
||||||
|
|
||||||
|
> 项目已重命名 `refactor` 分支为 `main` 分支,请依赖的项目注意更改分支名称。
|
||||||
|
|
||||||
## 编译环境需求
|
## 编译环境需求
|
||||||
|
|
||||||
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
||||||
@@ -36,6 +38,10 @@ If you are using English, see [English README](README-en.md).
|
|||||||
|
|
||||||
目前支持编译的 PHP 版本为:`7.4`,`8.0`,`8.1`,`8.2`。
|
目前支持编译的 PHP 版本为:`7.4`,`8.0`,`8.1`,`8.2`。
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
点击这里查看文档:<https://static-php-cli.zhamao.me>。
|
||||||
|
|
||||||
## 使用
|
## 使用
|
||||||
|
|
||||||
请先根据下方扩展列表选择你要编译的扩展。
|
请先根据下方扩展列表选择你要编译的扩展。
|
||||||
@@ -48,7 +54,7 @@ If you are using English, see [English README](README-en.md).
|
|||||||
|
|
||||||
### 支持的扩展情况
|
### 支持的扩展情况
|
||||||
|
|
||||||
[扩展支持列表](/ext-support.md)
|
[扩展支持列表](https://static-php-cli.zhamao.me/zh/guide/extensions.html)
|
||||||
|
|
||||||
> 如果这里没有你需要的扩展,可以提交 Issue。
|
> 如果这里没有你需要的扩展,可以提交 Issue。
|
||||||
|
|
||||||
@@ -94,7 +100,7 @@ chmod +x bin/setup-runtime
|
|||||||
cd static-php-cli
|
cd static-php-cli
|
||||||
composer update
|
composer update
|
||||||
chmod +x bin/spc
|
chmod +x bin/spc
|
||||||
# 检查环境依赖,并根据提示的命令安装缺失的编译工具(目前仅支持 macOS,Linux 后续会支持)
|
# 检查环境依赖,并根据提示的命令安装缺失的编译工具
|
||||||
./bin/spc doctor
|
./bin/spc doctor
|
||||||
# 拉取所有依赖库
|
# 拉取所有依赖库
|
||||||
./bin/spc fetch --all
|
./bin/spc fetch --all
|
||||||
@@ -200,6 +206,8 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
|||||||
|
|
||||||
另外,添加新扩展的贡献方式,可以参考下方 `进阶`。
|
另外,添加新扩展的贡献方式,可以参考下方 `进阶`。
|
||||||
|
|
||||||
|
如果你想贡献文档内容,请到项目仓库 [crazywhalecc/static-php-cli-docs](https://github.com/crazywhalecc/static-php-cli-docs) 贡献。
|
||||||
|
|
||||||
## 赞助本项目
|
## 赞助本项目
|
||||||
|
|
||||||
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。
|
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。
|
||||||
@@ -216,6 +224,4 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
|||||||
|
|
||||||
## 进阶
|
## 进阶
|
||||||
|
|
||||||
本项目重构分支为模块化编写。
|
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php-cli.zhamao.me) 贡献代码或文档。(TODO)
|
||||||
|
|
||||||
TODO:这部分将在基础功能完成后编写完成。
|
|
||||||
|
|||||||
@@ -53,6 +53,19 @@
|
|||||||
"sockets"
|
"sockets"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"memcached": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "memcached",
|
||||||
|
"arg-type": "custom",
|
||||||
|
"cpp-extension": true,
|
||||||
|
"lib-depends": [
|
||||||
|
"libmemcached"
|
||||||
|
],
|
||||||
|
"ext-depends": [
|
||||||
|
"session",
|
||||||
|
"zlib"
|
||||||
|
]
|
||||||
|
},
|
||||||
"exif": {
|
"exif": {
|
||||||
"type": "builtin"
|
"type": "builtin"
|
||||||
},
|
},
|
||||||
@@ -138,6 +151,7 @@
|
|||||||
},
|
},
|
||||||
"intl": {
|
"intl": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
|
"cpp-extension": true,
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"icu"
|
"icu"
|
||||||
]
|
]
|
||||||
@@ -151,8 +165,9 @@
|
|||||||
},
|
},
|
||||||
"mbregex": {
|
"mbregex": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"lib-depends": [
|
"arg-type": "custom",
|
||||||
"onig"
|
"ext-depends": [
|
||||||
|
"mbstring"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mbstring": {
|
"mbstring": {
|
||||||
@@ -162,6 +177,17 @@
|
|||||||
"onig"
|
"onig"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"memcache": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "ext-memcache",
|
||||||
|
"arg-type": "custom",
|
||||||
|
"lib-depends": [
|
||||||
|
"zlib"
|
||||||
|
],
|
||||||
|
"ext-depends": [
|
||||||
|
"session"
|
||||||
|
]
|
||||||
|
},
|
||||||
"mongodb": {
|
"mongodb": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "mongodb",
|
"source": "mongodb",
|
||||||
@@ -211,12 +237,13 @@
|
|||||||
},
|
},
|
||||||
"pdo_pgsql": {
|
"pdo_pgsql": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "with",
|
"arg-type": "with-prefix",
|
||||||
"ext-depends": [
|
"ext-depends": [
|
||||||
"pdo"
|
"pdo",
|
||||||
|
"pgsql"
|
||||||
],
|
],
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"pq"
|
"postgresql"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"pdo_sqlite": {
|
"pdo_sqlite": {
|
||||||
@@ -230,6 +257,13 @@
|
|||||||
"sqlite"
|
"sqlite"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"pgsql": {
|
||||||
|
"type": "builtin",
|
||||||
|
"arg-type": "with-prefix",
|
||||||
|
"lib-depends": [
|
||||||
|
"postgresql"
|
||||||
|
]
|
||||||
|
},
|
||||||
"phar": {
|
"phar": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"ext-depends": [
|
"ext-depends": [
|
||||||
@@ -320,6 +354,7 @@
|
|||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "swoole",
|
"source": "swoole",
|
||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
|
"cpp-extension": true,
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"openssl"
|
"openssl"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -381,7 +381,19 @@
|
|||||||
"postgresql": {
|
"postgresql": {
|
||||||
"source": "postgresql",
|
"source": "postgresql",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
"libpg.a"
|
"libpq.a",
|
||||||
|
"libpgport.a",
|
||||||
|
"libpgcommon.a"
|
||||||
|
],
|
||||||
|
"lib-depends": [
|
||||||
|
"libiconv",
|
||||||
|
"libxml2",
|
||||||
|
"openssl",
|
||||||
|
"zlib",
|
||||||
|
"readline"
|
||||||
|
],
|
||||||
|
"lib-suggests": [
|
||||||
|
"icu"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"pthreads4w": {
|
"pthreads4w": {
|
||||||
@@ -450,6 +462,13 @@
|
|||||||
"zconf.h"
|
"zconf.h"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"libmemcached": {
|
||||||
|
"source": "libmemcached",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libmemcached.a",
|
||||||
|
"libmemcachedutil.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
"zstd": {
|
"zstd": {
|
||||||
"source": "zstd",
|
"source": "zstd",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
|
|||||||
@@ -16,6 +16,25 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"memcached": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/memcached",
|
||||||
|
"path": "php-src/ext/memcached",
|
||||||
|
"filename": "memcached.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libmemcached": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/crazywhalecc/libmemcached-macos.git",
|
||||||
|
"rev": "master",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "COPYING"
|
||||||
|
}
|
||||||
|
},
|
||||||
"brotli": {
|
"brotli": {
|
||||||
"type": "ghtar",
|
"type": "ghtar",
|
||||||
"repo": "google/brotli",
|
"repo": "google/brotli",
|
||||||
@@ -61,6 +80,16 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ext-memcache": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/memcache",
|
||||||
|
"path": "php-src/ext/memcache",
|
||||||
|
"filename": "memcache.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ext-ssh2": {
|
"ext-ssh2": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://pecl.php.net/get/ssh2",
|
"url": "https://pecl.php.net/get/ssh2",
|
||||||
@@ -318,7 +347,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postgresql": {
|
"postgresql": {
|
||||||
"type": "custom",
|
"type": "url",
|
||||||
|
"url": "https://ftp.postgresql.org/pub/source/v15.1/postgresql-15.1.tar.gz",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "COPYRIGHT"
|
"path": "COPYRIGHT"
|
||||||
|
|||||||
111
ext-support.md
111
ext-support.md
@@ -1,112 +1,3 @@
|
|||||||
# Extension List
|
# Extension List
|
||||||
|
|
||||||
> - yes: supported and tested
|
See: [Docs - Extensions](https://static-php-cli.zhamao.me/en/guide/extensions.html)
|
||||||
> - untested: supported, but not tested
|
|
||||||
> - empty: not supported yet
|
|
||||||
> - no with issue link: not supported yet due to issue
|
|
||||||
> - partial with issue link: supported but not perfect due to issue
|
|
||||||
|
|
||||||
| | Linux | macOS | Windows |
|
|
||||||
|-----------------|---------------------------------------------------------------------|----------------------------------------------------------------|---------|
|
|
||||||
| apcu | yes, untested | yes, untested | |
|
|
||||||
| bcmath | yes | yes | |
|
|
||||||
| bz2 | yes | yes | |
|
|
||||||
| calendar | yes | yes | |
|
|
||||||
| ctype | yes | yes | |
|
|
||||||
| curl | yes | yes | |
|
|
||||||
| dba | yes | yes | |
|
|
||||||
| dom | yes | yes | |
|
|
||||||
| enchant | | | |
|
|
||||||
| event | yes | yes | |
|
|
||||||
| exif | yes | yes | |
|
|
||||||
| ffi | | yes, [docs]() | |
|
|
||||||
| filter | yes | yes | |
|
|
||||||
| fileinfo | yes | yes | |
|
|
||||||
| ftp | yes | yes | |
|
|
||||||
| gd | yes | yes | |
|
|
||||||
| gettext | | | |
|
|
||||||
| gmp | yes | yes | |
|
|
||||||
| iconv | yes | yes | |
|
|
||||||
| imagick | yes | yes | |
|
|
||||||
| inotify | yes | yes | |
|
|
||||||
| intl | [partial](https://github.com/crazywhalecc/static-php-cli/issues/66) | yes | |
|
|
||||||
| mbstring | yes | yes | |
|
|
||||||
| mbregex | yes | yes | |
|
|
||||||
| mcrypt | | [no](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
|
||||||
| mongodb | yes | yes | |
|
|
||||||
| mysqli | yes | yes | |
|
|
||||||
| mysqlnd | yes | yes | |
|
|
||||||
| opcache | yes | yes | |
|
|
||||||
| openssl | yes | yes | |
|
|
||||||
| password-argon2 | | | |
|
|
||||||
| pcntl | yes | yes | |
|
|
||||||
| pdo | yes | yes | |
|
|
||||||
| pdo_mysql | yes | yes | |
|
|
||||||
| pdo_sqlite | yes | yes | |
|
|
||||||
| pdo_pgsql | | | |
|
|
||||||
| phar | yes | yes | |
|
|
||||||
| posix | yes | yes | |
|
|
||||||
| protobuf | yes | yes | |
|
|
||||||
| readline | yes, untested | yes, untested | |
|
|
||||||
| redis | yes | yes | |
|
|
||||||
| session | yes | yes | |
|
|
||||||
| shmop | yes | yes | |
|
|
||||||
| simplexml | yes | yes | |
|
|
||||||
| soap | yes | yes | |
|
|
||||||
| sockets | yes | yes | |
|
|
||||||
| sodium | yes | yes | |
|
|
||||||
| sqlite3 | yes | yes | |
|
|
||||||
| ssh2 | yes, untested | yes, untested | |
|
|
||||||
| swow | yes | yes | |
|
|
||||||
| swoole | [partial](https://github.com/crazywhalecc/static-php-cli/issues/51) | yes | |
|
|
||||||
| tokenizer | yes | yes | |
|
|
||||||
| xlswriter | yes | yes | |
|
|
||||||
| xml | yes | yes | |
|
|
||||||
| xmlreader | yes, untested | yes, untested | |
|
|
||||||
| xmlwriter | yes, untested | yes, untested | |
|
|
||||||
| zip | yes, untested | yes, untested | |
|
|
||||||
| zlib | yes | yes | |
|
|
||||||
| zstd | yes | yes | |
|
|
||||||
|
|
||||||
## Additional Requirements
|
|
||||||
|
|
||||||
- phpmicro requires PHP >= 8.0
|
|
||||||
- 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: `""`
|
|
||||||
|
|
||||||
Compile with all supported extensions (exclude `swow`, `swoole`, because these will change the default behavior of php):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bin/spc build --build-all bcmath,bz2,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,mbregex,mbstring,mongodb,mysqli,mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,protobuf,redis,session,shmop,simplexml,soap,sockets,sqlite3,tokenizer,xml,xmlreader,xmlwriter,yaml,zip,zlib,zstd --with-libs=libjpeg,freetype,libwebp,libavif --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
## Additional Libraries
|
|
||||||
|
|
||||||
Some extensions have soft dependencies, you can enable extra features by adding these libs using `--with-libs`.
|
|
||||||
|
|
||||||
For example, to compile with gd extension, with `libwebp, libgif, libavif, libjpeg, freetype` extra features:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bin/spc build gd --with-libs=libjpeg,freetype,libwebp,libavif --build-cli
|
|
||||||
```
|
|
||||||
|
|
||||||
> If you don't add them, your compilation will not enable these features.
|
|
||||||
|
|
||||||
## 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 and TODOs
|
|
||||||
|
|
||||||
See [#32](https://github.com/crazywhalecc/static-php-cli/issues/32).
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use Symfony\Component\Console\Command\ListCommand;
|
|||||||
*/
|
*/
|
||||||
class ConsoleApplication extends Application
|
class ConsoleApplication extends Application
|
||||||
{
|
{
|
||||||
public const VERSION = '2.0-rc2';
|
public const VERSION = '2.0-rc3';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
|
|||||||
@@ -140,6 +140,37 @@ abstract class BuilderBase
|
|||||||
return $this->exts[$name] ?? null;
|
return $this->exts[$name] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有要编译的扩展对象
|
||||||
|
*
|
||||||
|
* @return Extension[]
|
||||||
|
*/
|
||||||
|
public function getExts(): array
|
||||||
|
{
|
||||||
|
return $this->exts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查 C++ 扩展是否存在
|
||||||
|
*
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public function hasCppExtension(): bool
|
||||||
|
{
|
||||||
|
// judge cpp-extension
|
||||||
|
$exts = array_keys($this->getExts());
|
||||||
|
$cpp = false;
|
||||||
|
foreach ($exts as $ext) {
|
||||||
|
if (Config::getExt($ext, 'cpp-extension', false) === true) {
|
||||||
|
$cpp = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $cpp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置本次 Builder 是否为仅编译库的模式
|
* 设置本次 Builder 是否为仅编译库的模式
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,4 +14,9 @@ class mbregex extends Extension
|
|||||||
{
|
{
|
||||||
return 'mbstring';
|
return 'mbstring';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfigureArg(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/SPC/builder/extension/memcache.php
Normal file
17
src/SPC/builder/extension/memcache.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('memcache')]
|
||||||
|
class memcache extends Extension
|
||||||
|
{
|
||||||
|
public function getUnixConfigureArg(): string
|
||||||
|
{
|
||||||
|
return '--enable-memcache --with-zlib-dir=' . BUILD_ROOT_PATH;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/SPC/builder/extension/memcached.php
Normal file
18
src/SPC/builder/extension/memcached.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('memcached')]
|
||||||
|
class memcached extends Extension
|
||||||
|
{
|
||||||
|
public function getUnixConfigureArg(): string
|
||||||
|
{
|
||||||
|
$rootdir = BUILD_ROOT_PATH;
|
||||||
|
return "--enable-memcached --with-zlib-dir={$rootdir} --with-libmemcached-dir={$rootdir} --disable-memcached-sasl --enable-memcached-json";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ class LinuxBuilder extends BuilderBase
|
|||||||
use UnixBuilderTrait;
|
use UnixBuilderTrait;
|
||||||
|
|
||||||
/** @var string[] Linux 环境下编译依赖的命令 */
|
/** @var string[] Linux 环境下编译依赖的命令 */
|
||||||
public const REQUIRED_COMMANDS = ['make', 'bison', 'flex', 'pkg-config', 'git', 'autoconf', 'automake', 'tar', 'unzip', /* 'xz', 好像不需要 */ 'gzip', 'bzip2', 'cmake'];
|
public const REQUIRED_COMMANDS = ['make', 'bison', 'flex', 'git', 'autoconf', 'automake', 'tar', 'unzip', /* 'xz', 好像不需要 */ 'gzip', 'bzip2', 'cmake'];
|
||||||
|
|
||||||
/** @var string 使用的 libc */
|
/** @var string 使用的 libc */
|
||||||
public string $libc;
|
public string $libc;
|
||||||
@@ -139,7 +139,8 @@ class LinuxBuilder extends BuilderBase
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($this->getExt('swoole') || $this->getExt('intl')) {
|
|
||||||
|
if ($this->hasCppExtension()) {
|
||||||
$extra_libs .= ' -lstdc++';
|
$extra_libs .= ' -lstdc++';
|
||||||
}
|
}
|
||||||
if ($this->getExt('imagick')) {
|
if ($this->getExt('imagick')) {
|
||||||
|
|||||||
20
src/SPC/builder/linux/library/libmemcached.php
Normal file
20
src/SPC/builder/linux/library/libmemcached.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gmp is a template library class for unix
|
||||||
|
*/
|
||||||
|
class libmemcached extends LinuxLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'libmemcached';
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
throw new RuntimeException('libmemcached is currently not supported on Linux platform');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ class libpng extends LinuxLibraryBase
|
|||||||
|
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec('chmod +x ./configure')
|
->exec('chmod +x ./configure')
|
||||||
|
->exec('chmod +x ./install-sh')
|
||||||
->exec(
|
->exec(
|
||||||
"{$this->builder->configure_env} ./configure " .
|
"{$this->builder->configure_env} ./configure " .
|
||||||
"--host={$this->builder->gnu_arch}-unknown-linux " .
|
"--host={$this->builder->gnu_arch}-unknown-linux " .
|
||||||
|
|||||||
12
src/SPC/builder/linux/library/postgresql.php
Normal file
12
src/SPC/builder/linux/library/postgresql.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
|
class postgresql extends LinuxLibraryBase
|
||||||
|
{
|
||||||
|
use \SPC\builder\unix\library\postgresql;
|
||||||
|
|
||||||
|
public const NAME = 'postgresql';
|
||||||
|
}
|
||||||
@@ -54,7 +54,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' .
|
'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' .
|
||||||
"CC='{$this->cc}' " .
|
"CC='{$this->cc}' " .
|
||||||
"CXX='{$this->cxx}' " .
|
"CXX='{$this->cxx}' " .
|
||||||
"CFLAGS='{$this->arch_c_flags} -Wimplicit-function-declaration'";
|
"CFLAGS='{$this->arch_c_flags} -Wimplicit-function-declaration -Os'";
|
||||||
|
|
||||||
// 创立 pkg-config 和放头文件的目录
|
// 创立 pkg-config 和放头文件的目录
|
||||||
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
||||||
@@ -118,12 +118,15 @@ class MacOSBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @param int $build_target build target
|
||||||
|
* @param bool $bloat just raw add all lib files
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function buildPHP(int $build_target = BUILD_TARGET_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') || $this->getExt('intl') ? '-lc++ ' : '');
|
$extra_libs = $this->getFrameworks(true) . ' ' . ($this->hasCppExtension() ? '-lc++ ' : '');
|
||||||
if (!$bloat) {
|
if (!$bloat) {
|
||||||
$extra_libs .= implode(' ', $this->getAllStaticLibFiles());
|
$extra_libs .= implode(' ', $this->getAllStaticLibFiles());
|
||||||
} else {
|
} else {
|
||||||
@@ -209,7 +212,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
public function buildCli(string $extra_libs): void
|
public function buildCli(string $extra_libs): void
|
||||||
{
|
{
|
||||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||||
$shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli");
|
$shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli");
|
||||||
if ($this->strip) {
|
if ($this->strip) {
|
||||||
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
|
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/SPC/builder/macos/library/libmemcached.php
Normal file
31
src/SPC/builder/macos/library/libmemcached.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gmp is a template library class for unix
|
||||||
|
*/
|
||||||
|
class libmemcached extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'libmemcached';
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$rootdir = BUILD_ROOT_PATH;
|
||||||
|
|
||||||
|
shell()->cd($this->source_dir)
|
||||||
|
->exec('chmod +x configure')
|
||||||
|
->exec(
|
||||||
|
"{$this->builder->configure_env} ./configure " .
|
||||||
|
'--enable-static --disable-shared ' .
|
||||||
|
'--disable-sasl ' .
|
||||||
|
"--prefix={$rootdir}"
|
||||||
|
)
|
||||||
|
->exec('make clean')
|
||||||
|
->exec('sed -ie "s/-Werror//g" ' . $this->source_dir . '/Makefile')
|
||||||
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
|
->exec('make install');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ class libpng extends MacOSLibraryBase
|
|||||||
};
|
};
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec('chmod +x ./configure')
|
->exec('chmod +x ./configure')
|
||||||
|
->exec('chmod +x ./install-sh')
|
||||||
->exec(
|
->exec(
|
||||||
"{$this->builder->configure_env} ./configure " .
|
"{$this->builder->configure_env} ./configure " .
|
||||||
"--host={$this->builder->gnu_arch}-apple-darwin " .
|
"--host={$this->builder->gnu_arch}-apple-darwin " .
|
||||||
|
|||||||
@@ -31,18 +31,16 @@ class libxml2 extends MacOSLibraryBase
|
|||||||
'-DBUILD_SHARED_LIBS=OFF ' .
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
'-DLIBXML2_WITH_ICONV=ON ' .
|
'-DLIBXML2_WITH_ICONV=ON ' .
|
||||||
"-DLIBXML2_WITH_ZLIB={$enable_zlib} " .
|
"-DLIBXML2_WITH_ZLIB={$enable_zlib} " .
|
||||||
"-DLIBXML2_WITH_ICU={$enable_icu} " .
|
'-DLIBXML2_WITH_ICU=OFF ' .
|
||||||
"-DLIBXML2_WITH_LZMA={$enable_xz} " .
|
"-DLIBXML2_WITH_LZMA={$enable_xz} " .
|
||||||
'-DLIBXML2_WITH_PYTHON=OFF ' .
|
'-DLIBXML2_WITH_PYTHON=OFF ' .
|
||||||
'-DLIBXML2_WITH_PROGRAMS=OFF ' .
|
'-DLIBXML2_WITH_PROGRAMS=OFF ' .
|
||||||
'-DLIBXML2_WITH_TESTS=OFF ' .
|
'-DLIBXML2_WITH_TESTS=OFF ' .
|
||||||
'-DCMAKE_INSTALL_PREFIX=/ ' .
|
"-DCMAKE_INSTALL_PREFIX={$destdir} " .
|
||||||
"-DCMAKE_INSTALL_LIBDIR={$lib} " .
|
|
||||||
"-DCMAKE_INSTALL_INCLUDEDIR={$include} " .
|
|
||||||
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
'..'
|
'..'
|
||||||
)
|
)
|
||||||
->exec("cmake --build . -j {$this->builder->concurrency}")
|
->exec("cmake --build . -j {$this->builder->concurrency}")
|
||||||
->exec("make install DESTDIR={$destdir}");
|
->exec('make install');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ class openssl extends MacOSLibraryBase
|
|||||||
"{$this->builder->configure_env} ./Configure no-shared {$extra} " .
|
"{$this->builder->configure_env} ./Configure no-shared {$extra} " .
|
||||||
'--prefix=/ ' . // use prefix=/
|
'--prefix=/ ' . // use prefix=/
|
||||||
"--libdir={$lib} " .
|
"--libdir={$lib} " .
|
||||||
" darwin64-{$this->builder->arch}-cc"
|
'--openssldir=/System/Library/OpenSSL ' .
|
||||||
|
"darwin64-{$this->builder->arch}-cc"
|
||||||
)
|
)
|
||||||
->exec('make clean')
|
->exec('make clean')
|
||||||
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
||||||
|
|||||||
12
src/SPC/builder/macos/library/postgresql.php
Normal file
12
src/SPC/builder/macos/library/postgresql.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
class postgresql extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
use \SPC\builder\unix\library\postgresql;
|
||||||
|
|
||||||
|
public const NAME = 'postgresql';
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ trait libevent
|
|||||||
'-DEVENT__LIBRARY_TYPE=STATIC ' .
|
'-DEVENT__LIBRARY_TYPE=STATIC ' .
|
||||||
'-DEVENT__DISABLE_BENCHMARK=ON ' .
|
'-DEVENT__DISABLE_BENCHMARK=ON ' .
|
||||||
'-DEVENT__DISABLE_THREAD_SUPPORT=ON ' .
|
'-DEVENT__DISABLE_THREAD_SUPPORT=ON ' .
|
||||||
|
'-DEVENT__DISABLE_MBEDTLS=ON ' .
|
||||||
'-DEVENT__DISABLE_TESTS=ON ' .
|
'-DEVENT__DISABLE_TESTS=ON ' .
|
||||||
'-DEVENT__DISABLE_SAMPLES=ON ' .
|
'-DEVENT__DISABLE_SAMPLES=ON ' .
|
||||||
'..'
|
'..'
|
||||||
|
|||||||
89
src/SPC/builder/unix/library/postgresql.php
Normal file
89
src/SPC/builder/unix/library/postgresql.php
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
trait postgresql
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build()
|
||||||
|
{
|
||||||
|
$builddir = BUILD_ROOT_PATH;
|
||||||
|
$env = $this->builder->configure_env;
|
||||||
|
$envs = $env;
|
||||||
|
$packages = 'openssl zlib readline libxml-2.0'; // icu-uc icu-io icu-i18n libzstd
|
||||||
|
|
||||||
|
$pkgconfig_executable = $builddir . '/bin/pkg-config';
|
||||||
|
$output = shell()->execWithResult($env . " {$pkgconfig_executable} --cflags-only-I --static " . $packages);
|
||||||
|
if (!empty($output[1][0])) {
|
||||||
|
$cppflags = $output[1][0];
|
||||||
|
$envs .= " CPPFLAGS=\"{$cppflags}\"";
|
||||||
|
}
|
||||||
|
$output = shell()->execWithResult($env . " {$pkgconfig_executable} --libs-only-L --static " . $packages);
|
||||||
|
if (!empty($output[1][0])) {
|
||||||
|
$ldflags = $output[1][0];
|
||||||
|
$envs .= $this instanceof MacOSLibraryBase ? " LDFLAGS=\"{$ldflags}\" " : " LDFLAGS=\"{$ldflags} -static\" ";
|
||||||
|
}
|
||||||
|
$output = shell()->execWithResult($env . " {$pkgconfig_executable} --libs-only-l --static " . $packages);
|
||||||
|
if (!empty($output[1][0])) {
|
||||||
|
$libs = $output[1][0];
|
||||||
|
$envs .= " LIBS=\"{$libs}\" ";
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
|
|
||||||
|
# 有静态链接配置 参考文件: src/interfaces/libpq/Makefile
|
||||||
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
->exec('sed -i.backup "s/invokes exit\'; exit 1;/invokes exit\';/" ../src/interfaces/libpq/Makefile')
|
||||||
|
->exec(' sed -i.backup "293 s/^/#$/" ../src/Makefile.shlib')
|
||||||
|
->exec('sed -i.backup "441 s/^/#$/" ../src/Makefile.shlib');
|
||||||
|
|
||||||
|
// configure
|
||||||
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
->exec(
|
||||||
|
"{$envs} ../configure " .
|
||||||
|
"--prefix={$builddir} " .
|
||||||
|
'--disable-thread-safety ' .
|
||||||
|
'--enable-coverage=no ' .
|
||||||
|
'--with-ssl=openssl ' .
|
||||||
|
'--with-readline ' .
|
||||||
|
'--with-libxml ' .
|
||||||
|
($this->builder->getLib('icu') ? '--with-icu ' : '--without-icu ') .
|
||||||
|
'--without-ldap ' .
|
||||||
|
'--without-libxslt ' .
|
||||||
|
'--without-lz4 ' .
|
||||||
|
'--without-zstd ' .
|
||||||
|
'--without-perl ' .
|
||||||
|
'--without-python ' .
|
||||||
|
'--without-pam ' .
|
||||||
|
'--without-ldap ' .
|
||||||
|
'--without-bonjour ' .
|
||||||
|
'--without-tcl '
|
||||||
|
);
|
||||||
|
|
||||||
|
// build
|
||||||
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
->exec($envs . ' make -C src/bin/pg_config install')
|
||||||
|
->exec($envs . ' make -C src/include install')
|
||||||
|
->exec($envs . ' make -C src/common install')
|
||||||
|
->exec($envs . ' make -C src/backend/port install')
|
||||||
|
->exec($envs . ' make -C src/port install')
|
||||||
|
->exec($envs . ' make -C src/backend/libpq install')
|
||||||
|
->exec($envs . ' make -C src/interfaces/libpq install');
|
||||||
|
|
||||||
|
// remove dynamic libs
|
||||||
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
->exec("rm -rf {$builddir}/lib/*.so.*")
|
||||||
|
->exec("rm -rf {$builddir}/lib/*.so")
|
||||||
|
->exec("rm -rf {$builddir}/lib/*.dylib");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,7 +71,7 @@ class BuildCliCommand extends BuildCommand
|
|||||||
// 执行扩展检测
|
// 执行扩展检测
|
||||||
$builder->proveExts($extensions);
|
$builder->proveExts($extensions);
|
||||||
// strip
|
// strip
|
||||||
$builder->setStrip(false);
|
$builder->setStrip(!$this->getOption('no-strip'));
|
||||||
// 构建
|
// 构建
|
||||||
$builder->buildPHP($rule, $this->getOption('bloat'));
|
$builder->buildPHP($rule, $this->getOption('bloat'));
|
||||||
// 统计时间
|
// 统计时间
|
||||||
|
|||||||
@@ -10,11 +10,16 @@ use Symfony\Component\Console\Attribute\AsCommand;
|
|||||||
#[AsCommand('doctor', 'Diagnose whether the current environment can compile normally')]
|
#[AsCommand('doctor', 'Diagnose whether the current environment can compile normally')]
|
||||||
class DoctorCommand extends BaseCommand
|
class DoctorCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
$this->addOption('auto-fix', null, null, 'Automatically fix failed items (if possible)');
|
||||||
|
}
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$checker = new CheckListHandler($this->input, $this->output);
|
$checker = new CheckListHandler($this->input, $this->output);
|
||||||
$checker->runCheck(FIX_POLICY_PROMPT);
|
$checker->runCheck($this->input->getOption('auto-fix') ? FIX_POLICY_AUTOFIX : FIX_POLICY_PROMPT);
|
||||||
$this->output->writeln('<info>Doctor check complete !</info>');
|
$this->output->writeln('<info>Doctor check complete !</info>');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->output->writeln('<error>' . $e->getMessage() . '</error>');
|
$this->output->writeln('<error>' . $e->getMessage() . '</error>');
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\command;
|
namespace SPC\command;
|
||||||
|
|
||||||
|
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||||
use SPC\exception\DownloaderException;
|
use SPC\exception\DownloaderException;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
@@ -18,6 +19,8 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
#[AsCommand('download', 'Download required sources', ['fetch'])]
|
#[AsCommand('download', 'Download required sources', ['fetch'])]
|
||||||
class DownloadCommand extends BaseCommand
|
class DownloadCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
|
use UnixSystemUtilTrait;
|
||||||
|
|
||||||
protected string $php_major_ver;
|
protected string $php_major_ver;
|
||||||
|
|
||||||
public function configure()
|
public function configure()
|
||||||
@@ -28,12 +31,13 @@ class DownloadCommand extends BaseCommand
|
|||||||
$this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format like 8.1', '8.1');
|
$this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format like 8.1', '8.1');
|
||||||
$this->addOption('clean', null, null, 'Clean old download cache and source before fetch');
|
$this->addOption('clean', null, null, 'Clean old download cache and source before fetch');
|
||||||
$this->addOption('all', 'A', null, 'Fetch all sources that static-php-cli needed');
|
$this->addOption('all', 'A', null, 'Fetch all sources that static-php-cli needed');
|
||||||
|
$this->addOption('from-zip', 'Z', InputOption::VALUE_REQUIRED, 'Fetch from zip archive');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initialize(InputInterface $input, OutputInterface $output)
|
public function initialize(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
// --all 等于 "" "",也就是所有东西都要下载
|
// --all 等于 "" "",也就是所有东西都要下载
|
||||||
if ($input->getOption('all') || $input->getOption('clean')) {
|
if ($input->getOption('all') || $input->getOption('clean') || $input->getOption('from-zip')) {
|
||||||
$input->setArgument('sources', '');
|
$input->setArgument('sources', '');
|
||||||
}
|
}
|
||||||
parent::initialize($input, $output);
|
parent::initialize($input, $output);
|
||||||
@@ -66,6 +70,44 @@ class DownloadCommand extends BaseCommand
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --from-zip
|
||||||
|
if ($path = $this->getOption('from-zip')) {
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
logger()->critical('File ' . $path . ' not exist or not a zip archive.');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// remove old download files first
|
||||||
|
if (is_dir(DOWNLOAD_PATH)) {
|
||||||
|
logger()->warning('You are doing some operations that not recoverable: removing directories below');
|
||||||
|
logger()->warning(DOWNLOAD_PATH);
|
||||||
|
logger()->alert('I will remove these dir after 5 seconds !');
|
||||||
|
sleep(5);
|
||||||
|
f_passthru((PHP_OS_FAMILY === 'Windows' ? 'rmdir /s /q ' : 'rm -rf ') . DOWNLOAD_PATH);
|
||||||
|
}
|
||||||
|
// unzip command check
|
||||||
|
if (PHP_OS_FAMILY !== 'Windows' && !$this->findCommand('unzip')) {
|
||||||
|
logger()->critical('Missing unzip command, you need to install it first !');
|
||||||
|
logger()->critical('You can use "bin/spc doctor" command to check and install required tools');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// create downloads
|
||||||
|
try {
|
||||||
|
if (PHP_OS_FAMILY !== 'Windows') {
|
||||||
|
f_passthru('mkdir ' . DOWNLOAD_PATH . ' && cd ' . DOWNLOAD_PATH . ' && unzip ' . escapeshellarg($path));
|
||||||
|
}
|
||||||
|
// Windows TODO
|
||||||
|
|
||||||
|
if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) {
|
||||||
|
throw new RuntimeException('.lock.json not exist in "downloads/"');
|
||||||
|
}
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
logger()->critical('Extract failed: ' . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
logger()->info('Extract success');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Define PHP major version
|
// Define PHP major version
|
||||||
$ver = $this->php_major_ver = $this->getOption('with-php') ?? '8.1';
|
$ver = $this->php_major_ver = $this->getOption('with-php') ?? '8.1';
|
||||||
define('SPC_BUILD_PHP_VERSION', $ver);
|
define('SPC_BUILD_PHP_VERSION', $ver);
|
||||||
|
|||||||
116
src/SPC/command/MicroCombineCommand.php
Normal file
116
src/SPC/command/MicroCombineCommand.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
#[AsCommand('micro:combine', 'Combine micro.sfx and php code together')]
|
||||||
|
class MicroCombineCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
$this->addArgument('file', InputArgument::REQUIRED, 'The php or phar file to be combined');
|
||||||
|
$this->addOption('with-micro', 'M', InputOption::VALUE_REQUIRED, 'Customize your micro.sfx file');
|
||||||
|
$this->addOption('with-ini-set', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'ini to inject into micro.sfx when combining');
|
||||||
|
$this->addOption('with-ini-file', 'N', InputOption::VALUE_REQUIRED, 'ini file to inject into micro.sfx when combining');
|
||||||
|
$this->addOption('output', 'O', InputOption::VALUE_REQUIRED, 'Customize your output binary file name');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
// 0. Initialize path variables
|
||||||
|
$internal = FileSystem::convertPath(BUILD_ROOT_PATH . '/bin/micro.sfx');
|
||||||
|
$micro_file = $this->input->getOption('with-micro');
|
||||||
|
$file = $this->getArgument('file');
|
||||||
|
$ini_set = $this->input->getOption('with-ini-set');
|
||||||
|
$ini_file = $this->input->getOption('with-ini-file');
|
||||||
|
$target_ini = [];
|
||||||
|
$output = $this->input->getOption('output') ?? 'my-app';
|
||||||
|
$ini_part = '';
|
||||||
|
// 1. Make sure specified micro.sfx file exists
|
||||||
|
if ($micro_file !== null && !file_exists($micro_file)) {
|
||||||
|
$this->output->writeln('<error>The micro.sfx file you specified is incorrect or does not exist!</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// 2. Make sure buildroot/bin/micro.sfx exists
|
||||||
|
if ($micro_file === null && !file_exists($internal)) {
|
||||||
|
$this->output->writeln('<error>You haven\'t compiled micro.sfx yet, please use "build" command and "--build-micro" to compile phpmicro first!</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// 3. Use buildroot/bin/micro.sfx
|
||||||
|
if ($micro_file === null) {
|
||||||
|
$micro_file = $internal;
|
||||||
|
}
|
||||||
|
// 4. Make sure php or phar file exists
|
||||||
|
if (!is_file(FileSystem::convertPath($file))) {
|
||||||
|
$this->output->writeln('<error>The file to combine does not exist!</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// 5. Confirm ini files (ini-set has higher priority)
|
||||||
|
if ($ini_file !== null) {
|
||||||
|
// Check file exist first
|
||||||
|
if (!file_exists($ini_file)) {
|
||||||
|
$this->output->writeln('<error>The ini file to combine does not exist! (' . $ini_file . ')</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
$arr = parse_ini_file($ini_file);
|
||||||
|
if ($arr === false) {
|
||||||
|
$this->output->writeln('<error>Cannot parse ini file</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
$target_ini = array_merge($target_ini, $arr);
|
||||||
|
}
|
||||||
|
// 6. Confirm ini sets
|
||||||
|
if ($ini_set !== []) {
|
||||||
|
foreach ($ini_set as $item) {
|
||||||
|
$arr = parse_ini_string($item);
|
||||||
|
if ($arr === false) {
|
||||||
|
$this->output->writeln('<error>--with-ini-set parse failed</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
$target_ini = array_merge($target_ini, $arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 7. Generate ini injection parts
|
||||||
|
if (!empty($target_ini)) {
|
||||||
|
$ini_str = $this->encodeINI($target_ini);
|
||||||
|
logger()->debug('Injecting ini parts: ' . PHP_EOL . $ini_str);
|
||||||
|
$ini_part = "\xfd\xf6\x69\xe6";
|
||||||
|
$ini_part .= pack('N', strlen($ini_str));
|
||||||
|
$ini_part .= $ini_str;
|
||||||
|
}
|
||||||
|
// 8. Combine !
|
||||||
|
$output = FileSystem::isRelativePath($output) ? (WORKING_DIR . '/' . $output) : $output;
|
||||||
|
$file_target = file_get_contents($micro_file) . $ini_part . file_get_contents($file);
|
||||||
|
$result = file_put_contents($output, $file_target);
|
||||||
|
if ($result === false) {
|
||||||
|
$this->output->writeln('<error>Combine failed.</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// 9. chmod +x
|
||||||
|
chmod($output, 0755);
|
||||||
|
$this->output->writeln('<info>Combine success! Binary file: ' . $output . '</info>');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function encodeINI(array $array): string
|
||||||
|
{
|
||||||
|
$res = [];
|
||||||
|
foreach ($array as $key => $val) {
|
||||||
|
if (is_array($val)) {
|
||||||
|
$res[] = "[{$key}]";
|
||||||
|
foreach ($val as $skey => $sval) {
|
||||||
|
$res[] = "{$skey}=" . (is_numeric($sval) ? $sval : '"' . $sval . '"');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$res[] = "{$key}=" . (is_numeric($val) ? $val : '"' . $val . '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implode("\n", $res);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/SPC/command/dev/AllExtCommand.php
Normal file
24
src/SPC/command/dev/AllExtCommand.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command\dev;
|
||||||
|
|
||||||
|
use SPC\command\BaseCommand;
|
||||||
|
use SPC\store\Config;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
|
||||||
|
#[AsCommand('dev:ext-all', 'Dev command')]
|
||||||
|
class AllExtCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$this->output->writeln(implode(',', array_keys(Config::getExts())));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/SPC/command/dev/ExtInfoCommand.php
Normal file
43
src/SPC/command/dev/ExtInfoCommand.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command\dev;
|
||||||
|
|
||||||
|
use SPC\command\BaseCommand;
|
||||||
|
use SPC\store\Config;
|
||||||
|
use SPC\util\DependencyUtil;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
|
||||||
|
#[AsCommand('dev:ext-info', 'Dev command')]
|
||||||
|
class ExtInfoCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
$this->addArgument('extensions', InputArgument::REQUIRED, 'The extension name you need to get info');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions'))));
|
||||||
|
|
||||||
|
// 根据提供的扩展列表获取依赖库列表并编译
|
||||||
|
foreach ($extensions as $extension) {
|
||||||
|
$this->output->writeln('<comment>[ ' . $extension . ' ]</comment>');
|
||||||
|
[, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps([$extension]);
|
||||||
|
$lib_suggests = Config::getExt($extension, 'lib-suggests', []);
|
||||||
|
$ext_suggests = Config::getExt($extension, 'ext-suggests', []);
|
||||||
|
$this->output->writeln("<info>lib-depends:\t" . implode(', ', $libraries) . '</info>');
|
||||||
|
$this->output->writeln("<info>lib-suggests:\t" . implode(', ', $lib_suggests) . '</info>');
|
||||||
|
$this->output->writeln("<info>ext-depends:\t" . implode(',', $not_included) . '</info>');
|
||||||
|
$this->output->writeln("<info>ext-suggests:\t" . implode(', ', $ext_suggests) . '</info>');
|
||||||
|
if (Config::getExt($extension, 'unix-only', false)) {
|
||||||
|
$this->output->writeln("<info>Unix only:\ttrue</info>");
|
||||||
|
}
|
||||||
|
$this->output->writeln('');
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/SPC/command/dev/PhpVerCommand.php
Normal file
33
src/SPC/command/dev/PhpVerCommand.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command\dev;
|
||||||
|
|
||||||
|
use SPC\command\BaseCommand;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
#[AsCommand('dev:php-ver', 'Dev command')]
|
||||||
|
class PhpVerCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
public function initialize(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$this->no_motd = true;
|
||||||
|
parent::initialize($input, $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
// Find php from source/php-src
|
||||||
|
$file = SOURCE_PATH . '/php-src/main/php_version.h';
|
||||||
|
$result = preg_match('/#define PHP_VERSION "(\d+\.\d+\.\d+)"/', file_get_contents($file), $match);
|
||||||
|
if ($result === false) {
|
||||||
|
$this->output->writeln('<error>PHP source not found, maybe you need to extract first ?</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
$this->output->writeln('<info>' . $match[1] . '</info>');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
90
src/SPC/doctor/item/LinuxToolCheckList.php
Normal file
90
src/SPC/doctor/item/LinuxToolCheckList.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\doctor\item;
|
||||||
|
|
||||||
|
use SPC\builder\linux\SystemUtil;
|
||||||
|
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||||
|
use SPC\doctor\AsCheckItem;
|
||||||
|
use SPC\doctor\AsFixItem;
|
||||||
|
use SPC\doctor\CheckResult;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
|
class LinuxToolCheckList
|
||||||
|
{
|
||||||
|
use UnixSystemUtilTrait;
|
||||||
|
|
||||||
|
public const TOOLS_ALPINE = [
|
||||||
|
'make', 'bison', 'flex',
|
||||||
|
'git', 'autoconf', 'automake',
|
||||||
|
'tar', 'unzip', 'gzip',
|
||||||
|
'bzip2', 'cmake', 'gcc',
|
||||||
|
'g++', 'patch',
|
||||||
|
];
|
||||||
|
|
||||||
|
public const TOOLS_DEBIAN = [
|
||||||
|
'make', 'bison', 'flex',
|
||||||
|
'git', 'autoconf', 'automake',
|
||||||
|
'tar', 'unzip', 'gzip',
|
||||||
|
'bzip2', 'cmake', 'patch',
|
||||||
|
];
|
||||||
|
|
||||||
|
#[AsCheckItem('if necessary tools are installed', limit_os: 'Linux')]
|
||||||
|
public function checkCliTools(): ?CheckResult
|
||||||
|
{
|
||||||
|
$distro = SystemUtil::getOSRelease();
|
||||||
|
|
||||||
|
$required = match ($distro['dist']) {
|
||||||
|
'alpine' => self::TOOLS_ALPINE,
|
||||||
|
default => self::TOOLS_DEBIAN,
|
||||||
|
};
|
||||||
|
$missing = [];
|
||||||
|
foreach ($required as $cmd) {
|
||||||
|
if ($this->findCommand($cmd) === null) {
|
||||||
|
$missing[] = $cmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($missing)) {
|
||||||
|
return match ($distro['dist']) {
|
||||||
|
'ubuntu', 'alpine', 'debian' => CheckResult::fail(implode(', ', $missing) . ' not installed on your system', 'install-linux-tools', [$distro, $missing]),
|
||||||
|
default => CheckResult::fail(implode(', ', $missing) . ' not installed on your system'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return CheckResult::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[AsCheckItem('if necessary packages are installed', limit_os: 'Linux')]
|
||||||
|
public function checkSystemOSPackages(): ?CheckResult
|
||||||
|
{
|
||||||
|
$distro = SystemUtil::getOSRelease();
|
||||||
|
if ($distro['dist'] === 'alpine') {
|
||||||
|
// check linux-headers installation
|
||||||
|
if (!file_exists('/usr/include/linux/mman.h')) {
|
||||||
|
return CheckResult::fail('linux-headers not installed on your system', 'install-linux-tools', [$distro, ['linux-headers']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CheckResult::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[AsFixItem('install-linux-tools')]
|
||||||
|
public function fixBuildTools(array $distro, array $missing): bool
|
||||||
|
{
|
||||||
|
$install_cmd = match ($distro['dist']) {
|
||||||
|
'ubuntu', 'debian' => 'apt install -y',
|
||||||
|
'alpine' => 'apk add',
|
||||||
|
default => throw new RuntimeException('Current linux distro is not supported for auto-install musl packages'),
|
||||||
|
};
|
||||||
|
$prefix = '';
|
||||||
|
if (get_current_user() !== 'root') {
|
||||||
|
$prefix = 'sudo ';
|
||||||
|
logger()->warning('Current user is not root, using sudo for running command');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
shell(true)->exec($prefix . $install_cmd . ' ' . implode(' ', $missing));
|
||||||
|
} catch (RuntimeException) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -439,6 +439,20 @@ class FileSystem
|
|||||||
self::$_extract_hook[$name][] = $callback;
|
self::$_extract_hook[$name][] = $callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the path is a relative path (judging according to whether the first character is "/")
|
||||||
|
*
|
||||||
|
* @param string $path Path
|
||||||
|
*/
|
||||||
|
public static function isRelativePath(string $path): bool
|
||||||
|
{
|
||||||
|
// 适配 Windows 的多盘符目录形式
|
||||||
|
if (DIRECTORY_SEPARATOR === '\\') {
|
||||||
|
return !(strlen($path) > 2 && ctype_alpha($path[0]) && $path[1] === ':');
|
||||||
|
}
|
||||||
|
return strlen($path) > 0 && $path[0] !== '/';
|
||||||
|
}
|
||||||
|
|
||||||
private static function emitSourceExtractHook(string $name)
|
private static function emitSourceExtractHook(string $name)
|
||||||
{
|
{
|
||||||
foreach ((self::$_extract_hook[$name] ?? []) as $hook) {
|
foreach ((self::$_extract_hook[$name] ?? []) as $hook) {
|
||||||
|
|||||||
@@ -48,9 +48,33 @@ class SourcePatcher
|
|||||||
file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2);
|
file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ($builder->getExt('pdo_sqlite')) {
|
if ($builder->getExt('memcache')) {
|
||||||
// FileSystem::replaceFile()
|
FileSystem::replaceFile(
|
||||||
// }
|
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
|
||||||
|
REPLACE_FILE_STR,
|
||||||
|
'if test -d $abs_srcdir/src ; then',
|
||||||
|
'if test -d $abs_srcdir/main ; then'
|
||||||
|
);
|
||||||
|
FileSystem::replaceFile(
|
||||||
|
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
|
||||||
|
REPLACE_FILE_STR,
|
||||||
|
'export CPPFLAGS="$CPPFLAGS $INCLUDES"',
|
||||||
|
'export CPPFLAGS="$CPPFLAGS $INCLUDES -I$abs_srcdir/main"'
|
||||||
|
);
|
||||||
|
// add for in-tree building
|
||||||
|
file_put_contents(
|
||||||
|
SOURCE_PATH . '/php-src/ext/memcache/php_memcache.h',
|
||||||
|
<<<'EOF'
|
||||||
|
#ifndef PHP_MEMCACHE_H
|
||||||
|
#define PHP_MEMCACHE_H
|
||||||
|
|
||||||
|
extern zend_module_entry memcache_module_entry;
|
||||||
|
#define phpext_memcache_ptr &memcache_module_entry
|
||||||
|
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function patchSwow(): bool
|
public static function patchSwow(): bool
|
||||||
@@ -88,6 +112,9 @@ class SourcePatcher
|
|||||||
if ($ssh2 = $builder->getExt('ssh2')) {
|
if ($ssh2 = $builder->getExt('ssh2')) {
|
||||||
$patch[] = ['ssh2 patch', '/-lssh2/', $ssh2->getLibFilesString()];
|
$patch[] = ['ssh2 patch', '/-lssh2/', $ssh2->getLibFilesString()];
|
||||||
}
|
}
|
||||||
|
if ($pgsql = $builder->getExt('pgsql')) {
|
||||||
|
$patch[] = ['pgsql patch', '/-lpq/', $pgsql->getLibFilesString()];
|
||||||
|
}
|
||||||
$patch[] = ['disable capstone', '/have_capstone="yes"/', 'have_capstone="no"'];
|
$patch[] = ['disable capstone', '/have_capstone="yes"/', 'have_capstone="no"'];
|
||||||
foreach ($patch as $item) {
|
foreach ($patch as $item) {
|
||||||
logger()->info('Patching configure: ' . $item[0]);
|
logger()->info('Patching configure: ' . $item[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user