mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-17 05:45:35 +08:00
Compare commits
136 Commits
2.0-rc1
...
3e7ef49bde
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e7ef49bde | ||
|
|
100d31791a | ||
|
|
15905c063a | ||
|
|
4c46f6a762 | ||
|
|
f4327c8c81 | ||
|
|
4a4b0e209c | ||
|
|
60e06737d7 | ||
|
|
d326154241 | ||
|
|
4766ae146f | ||
|
|
21a4ba7478 | ||
|
|
dfdeab70f1 | ||
|
|
c8fa767576 | ||
|
|
9c57ed6439 | ||
|
|
585826b438 | ||
|
|
cf22949f3b | ||
|
|
a00f8945ba | ||
|
|
2bc02bdaac | ||
|
|
b97327d6d7 | ||
|
|
61d1507a4d | ||
|
|
a6f07051c3 | ||
|
|
75417d15b7 | ||
|
|
4bab7ecfab | ||
|
|
7298e2441b | ||
|
|
1ed104d2f6 | ||
|
|
cf6125b9cc | ||
|
|
f2cfe33cdd | ||
|
|
a1e4125ded | ||
|
|
7a1433a994 | ||
|
|
460238a6b0 | ||
|
|
2a197487d5 | ||
|
|
51ce2befd8 | ||
|
|
e909dd15b0 | ||
|
|
aaf712be3c | ||
|
|
725e6b25dc | ||
|
|
ea322c0d3b | ||
|
|
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 | ||
|
|
f2e483540b | ||
|
|
7d31c371e0 | ||
|
|
bc750733d5 | ||
|
|
a66e22d9ed | ||
|
|
cc5974d07d | ||
|
|
085437e925 | ||
|
|
fa17a48483 | ||
|
|
78c1484570 | ||
|
|
9c2ea79bec | ||
|
|
b7ffe3fd1f | ||
|
|
dac14ae16e | ||
|
|
4872ff58bb | ||
|
|
755246cb6a | ||
|
|
9806422279 | ||
|
|
d5aea9f7d6 | ||
|
|
b852471596 | ||
|
|
fdf36ad726 | ||
|
|
c49e6ba0a2 | ||
|
|
74a34362c3 | ||
|
|
0e33380df5 | ||
|
|
3db9c70e1b | ||
|
|
b2f3ffcc00 | ||
|
|
aa9ec6e50e | ||
|
|
dcb3d91610 | ||
|
|
9e71a98eda | ||
|
|
f2ef783b13 | ||
|
|
874e104570 | ||
|
|
1398086c38 | ||
|
|
db1586e2ec | ||
|
|
1158931d91 | ||
|
|
ee1b03b060 | ||
|
|
b99378ea38 | ||
|
|
c9692d502c | ||
|
|
3f6e659c6a | ||
|
|
37556c9e02 | ||
|
|
34cd9d7cc1 | ||
|
|
030ac531a6 | ||
|
|
e19bd39fea | ||
|
|
0fe432dd8e | ||
|
|
c5b24ab136 | ||
|
|
fb06cc1e1a | ||
|
|
71e4ea166c | ||
|
|
fdf8834163 | ||
|
|
1fd70c9a99 | ||
|
|
7c3826f4a4 | ||
|
|
7fb3d05b2c | ||
|
|
f831b4d61d | ||
|
|
56b5c1b138 | ||
|
|
1cca826e8a | ||
|
|
41aa129b97 | ||
|
|
09ba11affb | ||
|
|
2767ac524f |
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
|
patreon: # Replace with a single Patreon username
|
||||||
|
open_collective: # Replace with a single Open Collective username
|
||||||
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||||
|
custom: 'https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md' # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||||
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/
|
|
||||||
|
|||||||
40
.github/workflows/download-cache.yml
vendored
Normal file
40
.github/workflows/download-cache.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: archive download sources weekly
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "* 14 * * 5"
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
download:
|
||||||
|
name: cache download sources
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php-version: [ "8.0", "8.1", "8.2" ]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Cache composer dependencies
|
||||||
|
- id: cache-composer-deps
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: vendor
|
||||||
|
key: composer-dependencies
|
||||||
|
|
||||||
|
# If there's no Composer cache, install dependencies
|
||||||
|
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
|
||||||
|
run: composer update --no-dev
|
||||||
|
|
||||||
|
# If there's no dependencies cache, fetch sources, with or without debug
|
||||||
|
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||||
|
run: ./bin/spc download --with-php=${{ matrix.php-version }} --all --debug
|
||||||
|
|
||||||
|
# Upload downloaded files
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: download-files-${{ matrix.php-version }}
|
||||||
|
path: downloads/
|
||||||
57
README-en.md
57
README-en.md
@@ -11,20 +11,20 @@ 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">
|
||||||
|
|
||||||
> This branch is new version, if you are looking for old bash version of static-php-cli, see [bash-version](https://github.com/crazywhalecc/static-php-cli/tree/bash-version).
|
[]()
|
||||||
|
|
||||||
[]()
|
|
||||||
[]()
|
[]()
|
||||||
[](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.
|
||||||
But static-php-cli runtime only requires an environment above PHP 8.0 and `tokenizer`, `iconv` extension.
|
But static-php-cli runtime only requires an environment above PHP 8.1 and `mbstring`, `pcntl` extension.
|
||||||
|
|
||||||
Here is the architecture support status, where `CI` represents support for GitHub Action builds,
|
Here is the architecture support status, where `CI` represents support for GitHub Action builds,
|
||||||
`Local` represents support for local builds, and blank represents not currently supported.
|
`Local` represents support for local builds, and blank represents not currently supported.
|
||||||
@@ -37,9 +37,13 @@ Here is the architecture support status, where `CI` represents support for GitHu
|
|||||||
|
|
||||||
> macOS-arm64 is not supported for GitHub Actions, if you are going to build on arm, you can build it manually on your own machine.
|
> macOS-arm64 is not supported for GitHub Actions, if you are going to build on arm, you can build it manually on your own machine.
|
||||||
|
|
||||||
Currently supported PHP versions for compilation are: `7.4`, `8.0`, `8.1`, `8.2`.
|
Currently supported PHP versions for compilation are: `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`.
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
@@ -51,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.
|
||||||
|
|
||||||
@@ -78,13 +82,15 @@ Clone repo first:
|
|||||||
git clone https://github.com/crazywhalecc/static-php-cli.git
|
git clone https://github.com/crazywhalecc/static-php-cli.git
|
||||||
```
|
```
|
||||||
|
|
||||||
If you have not installed php on your system, you can download single-file php binary and composer first.
|
If you have not installed php on your system, you can use package management to install PHP (such as brew, apt, yum, apk etc.).
|
||||||
|
|
||||||
|
And you can also download single-file php binary and composer using command `bin/setup-runtime`.
|
||||||
The PHP runtime for static-php-cli itself will be downloaded at `bin/php`, and composer is at `bin/composer`.
|
The PHP runtime for static-php-cli itself will be downloaded at `bin/php`, and composer is at `bin/composer`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd static-php-cli
|
cd static-php-cli
|
||||||
chmod +x bin/setup-runtime
|
chmod +x bin/setup-runtime
|
||||||
|
# It will download php-cli from self-hosted server and composer from getcomposer.org
|
||||||
./bin/setup-runtime
|
./bin/setup-runtime
|
||||||
|
|
||||||
# Use this php runtime to run static-php-cli compiler
|
# Use this php runtime to run static-php-cli compiler
|
||||||
@@ -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
|
||||||
@@ -111,7 +117,7 @@ chmod +x bin/spc
|
|||||||
You can also use the parameter `--with-php=x.y` to specify the downloaded PHP version, currently supports 7.4 ~ 8.2:
|
You can also use the parameter `--with-php=x.y` to specify the downloaded PHP version, currently supports 7.4 ~ 8.2:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Using PHP >= 8.0 is recommended, because 7.4 cannot use phpmicro
|
# Using PHP >= 8.0 is recommended, because PHP7 cannot use phpmicro
|
||||||
./bin/spc fetch --with-php=8.2 --all
|
./bin/spc fetch --with-php=8.2 --all
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -129,6 +135,14 @@ If anything goes wrong, use `--debug` option to display full terminal output:
|
|||||||
./bin/spc fetch --all --debug
|
./bin/spc fetch --all --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
|
In addition, we build NTS by default. If you are going to build ZTS version, just add `--enable-zts` option.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./bin/spc build openssl,pcntl --build-all --enable-zts
|
||||||
|
```
|
||||||
|
|
||||||
|
Adding option `--no-strip` can produce binaries with debug symbols, in order to debug (using gdb). Disabling strip will increase the size of static binary.
|
||||||
|
|
||||||
### php-cli Usage
|
### php-cli Usage
|
||||||
|
|
||||||
> php-cli is a single static binary, you can use it like normal php installed on your system.
|
> php-cli is a single static binary, you can use it like normal php installed on your system.
|
||||||
@@ -148,7 +162,7 @@ cd buildroot/bin/
|
|||||||
|
|
||||||
### micro.sfx Usage
|
### micro.sfx Usage
|
||||||
|
|
||||||
> phpmicro is a Self-Extracted Executable SAPI module,
|
> phpmicro is a SelF-extracted eXecutable SAPI module,
|
||||||
> provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro).
|
> provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro).
|
||||||
> It can put php runtime and your source code together.
|
> It can put php runtime and your source code together.
|
||||||
|
|
||||||
@@ -209,6 +223,17 @@ 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
|
||||||
|
|
||||||
|
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
|
||||||
|
|
||||||
## Open-Source License
|
## Open-Source License
|
||||||
|
|
||||||
This project is based on the tradition of using the MIT License for old versions,
|
This project is based on the tradition of using the MIT License for old versions,
|
||||||
@@ -221,11 +246,11 @@ Due to the special nature of this project,
|
|||||||
many other open source projects such as curl and protobuf will be used during the project compilation process,
|
many other open source projects such as curl and protobuf will be used during the project compilation process,
|
||||||
and they all have their own open source licenses.
|
and they all have their own open source licenses.
|
||||||
|
|
||||||
Please use the `dump-license`(TODO) command to export the open source licenses used in the project after compilation,
|
Please use the `bin/spc dump-license` command to export the open source licenses used in the project after compilation,
|
||||||
and comply with the corresponding project's LICENSE.
|
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)
|
||||||
|
|||||||
50
README.md
50
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,19 +12,19 @@ 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">
|
||||||
|
|
||||||
> 此分支为重构的新版,如果你在找纯 Bash 编写的旧版本,请到 [bash-version 分支](https://github.com/crazywhalecc/static-php-cli/tree/bash-version)。
|
[]()
|
||||||
|
|
||||||
[]()
|
|
||||||
[]()
|
[]()
|
||||||
[](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 环境,比较滑稽。
|
||||||
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 tokenizer 扩展和 PHP 版本大于等于 8.0 即可。
|
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
|
||||||
|
|
||||||
下面是架构支持情况,`CI` 代表支持 GitHub Action 构建,`Local` 代表支持本地构建,空 代表暂不支持。
|
下面是架构支持情况,`CI` 代表支持 GitHub Action 构建,`Local` 代表支持本地构建,空 代表暂不支持。
|
||||||
|
|
||||||
@@ -36,7 +36,11 @@ If you are using English, see [English README](README-en.md).
|
|||||||
|
|
||||||
> macOS-arm64 因 GitHub 暂未提供 arm runner,如果要构建 arm 二进制,可以使用手动构建。
|
> macOS-arm64 因 GitHub 暂未提供 arm runner,如果要构建 arm 二进制,可以使用手动构建。
|
||||||
|
|
||||||
目前支持编译的 PHP 版本为:`7.4`,`8.0`,`8.1`,`8.2`。
|
目前支持编译的 PHP 版本为:`7.3`,`7.4`,`8.0`,`8.1`,`8.2`,`8.3`。
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
点击这里查看文档:<https://static-php-cli.zhamao.me>。
|
||||||
|
|
||||||
## 使用
|
## 使用
|
||||||
|
|
||||||
@@ -50,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。
|
||||||
|
|
||||||
@@ -73,9 +77,9 @@ If you are using English, see [English README](README-en.md).
|
|||||||
git clone https://github.com/crazywhalecc/static-php-cli.git
|
git clone https://github.com/crazywhalecc/static-php-cli.git
|
||||||
```
|
```
|
||||||
|
|
||||||
如果你本机没有安装 PHP,你可以通过命令下载静态编译好的 php-cli 和 Composer。
|
如果你本机没有安装 PHP,你需要先使用包管理(例如 brew、apt、yum、apk 等)安装 php。
|
||||||
|
|
||||||
下载的 php 和 Composer 将保存为 `bin/php` 和 `bin/composer`。
|
你也可以通过 `bin/setup-runtime` 命令下载静态编译好的 php-cli 和 Composer。下载的 php 和 Composer 将保存为 `bin/php` 和 `bin/composer`。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd static-php-cli
|
cd static-php-cli
|
||||||
@@ -96,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
|
||||||
@@ -104,10 +108,10 @@ chmod +x bin/spc
|
|||||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
|
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
|
||||||
```
|
```
|
||||||
|
|
||||||
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.4 ~ 8.2:
|
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.3 ~ 8.3:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 优先考虑使用 >= 8.0 的 PHP 版本
|
# 优先考虑使用 >= 8.0 的 PHP 版本,因为 phpmicro 不支持在 PHP7 中构建
|
||||||
./bin/spc fetch --with-php=8.2 --all
|
./bin/spc fetch --with-php=8.2 --all
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -125,6 +129,14 @@ chmod +x bin/spc
|
|||||||
./bin/spc fetch --all --debug
|
./bin/spc fetch --all --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
|
此外,默认编译的 PHP 为 NTS 版本。如需编译线程安全版本(ZTS),只需添加参数 `--enable-zts` 即可。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./bin/spc build openssl,pcntl --build-all --enable-zts
|
||||||
|
```
|
||||||
|
|
||||||
|
同时,你也可以使用参数 `--no-strip` 来关闭裁剪,关闭裁剪后可以使用 gdb 等工具调试,但这样会让静态二进制体积变大。
|
||||||
|
|
||||||
### 使用 php-cli
|
### 使用 php-cli
|
||||||
|
|
||||||
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
|
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
|
||||||
@@ -194,6 +206,12 @@ 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) 支持我和我的项目。
|
||||||
|
|
||||||
## 开源协议
|
## 开源协议
|
||||||
|
|
||||||
本项目依据旧版本惯例采用 MIT License 开源,自身的部分代码引用或修改自以下项目:
|
本项目依据旧版本惯例采用 MIT License 开源,自身的部分代码引用或修改自以下项目:
|
||||||
@@ -202,10 +220,8 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
|||||||
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)(Apache 2.0 LICENSE、SWOOLE-CLI LICENSE)
|
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)(Apache 2.0 LICENSE、SWOOLE-CLI LICENSE)
|
||||||
|
|
||||||
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
|
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
|
||||||
请在编译完成后,使用命令 `dump-license`(TODO) 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
|
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
|
||||||
|
|
||||||
## 进阶
|
## 进阶
|
||||||
|
|
||||||
本项目重构分支为模块化编写。
|
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php-cli.zhamao.me) 贡献代码或文档。(TODO)
|
||||||
|
|
||||||
TODO:这部分将在基础功能完成后编写完成。
|
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ esac
|
|||||||
|
|
||||||
# set project dir
|
# set project dir
|
||||||
__DIR__=$(cd "$(dirname "$0")" && pwd)
|
__DIR__=$(cd "$(dirname "$0")" && pwd)
|
||||||
__PROJECT__=$(cd ${__DIR__}/../ && pwd)
|
__PROJECT__=$(cd "${__DIR__}"/../ && pwd)
|
||||||
|
|
||||||
# set download dir
|
# set download dir
|
||||||
__PHP_RUNTIME_URL__="https://dl.zhamao.xin/static-php-cli/php-8.2.5-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
|
__PHP_RUNTIME_URL__="https://dl.zhamao.xin/static-php-cli/php-8.2.6-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
|
||||||
__COMPOSER_URL__="https://getcomposer.org/download/latest-stable/composer.phar"
|
__COMPOSER_URL__="https://getcomposer.org/download/latest-stable/composer.phar"
|
||||||
|
|
||||||
# use china mirror
|
# use china mirror
|
||||||
@@ -46,23 +46,23 @@ done
|
|||||||
|
|
||||||
case "$mirror" in
|
case "$mirror" in
|
||||||
china)
|
china)
|
||||||
__PHP_RUNTIME_URL__="https://dl.zhamao.xin/static-php-cli/php-8.2.5-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
|
__PHP_RUNTIME_URL__="https://dl.zhamao.xin/static-php-cli/php-8.2.6-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
|
||||||
__COMPOSER_URL__="https://mirrors.aliyun.com/composer/composer.phar"
|
__COMPOSER_URL__="https://mirrors.aliyun.com/composer/composer.phar"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
test -d ${__PROJECT__}/downloads || mkdir ${__PROJECT__}/downloads
|
test -d "${__PROJECT__}"/downloads || mkdir "${__PROJECT__}"/downloads
|
||||||
# download static php binary
|
# download static php binary
|
||||||
test -f ${__PROJECT__}/downloads/runtime.tar.gz || { echo "Downloading $__PHP_RUNTIME_URL__ ..." && curl -#fSL -o ${__PROJECT__}/downloads/runtime.tar.gz "$__PHP_RUNTIME_URL__" ; }
|
test -f "${__PROJECT__}"/downloads/runtime.tar.gz || { echo "Downloading $__PHP_RUNTIME_URL__ ..." && curl -#fSL -o "${__PROJECT__}"/downloads/runtime.tar.gz "$__PHP_RUNTIME_URL__" ; }
|
||||||
test -f ${__DIR__}/php || { tar -xf ${__PROJECT__}/downloads/runtime.tar.gz -C ${__DIR__}/ ; }
|
test -f "${__DIR__}"/php || { tar -xf "${__PROJECT__}"/downloads/runtime.tar.gz -C "${__DIR__}"/ ; }
|
||||||
chmod +x ${__DIR__}/php
|
chmod +x "${__DIR__}"/php
|
||||||
# download composer
|
# download composer
|
||||||
test -f ${__DIR__}/composer || curl -#fSL -o ${__DIR__}/composer "$__COMPOSER_URL__"
|
test -f "${__DIR__}"/composer || curl -#fSL -o "${__DIR__}"/composer "$__COMPOSER_URL__"
|
||||||
chmod +x ${__DIR__}/composer
|
chmod +x "${__DIR__}"/composer
|
||||||
# sanity check for php and composer
|
# sanity check for php and composer
|
||||||
${__DIR__}/php -v >/dev/null || { echo "Failed to run php" && exit 1; }
|
"${__DIR__}"/php -v >/dev/null || { echo "Failed to run php" && exit 1; }
|
||||||
${__DIR__}/php ${__DIR__}/composer --version >/dev/null || { echo "Failed to run composer" && exit 1; }
|
"${__DIR__}"/php "${__DIR__}"/composer --version >/dev/null || { echo "Failed to run composer" && exit 1; }
|
||||||
|
|
||||||
echo "Setup runtime OK!"
|
echo "Setup runtime OK!"
|
||||||
echo "runtime bin path needs to add manually by command below:"
|
echo "runtime bin path needs to add manually by command below:"
|
||||||
|
|||||||
8
bin/spc
8
bin/spc
@@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use SPC\ConsoleApplication;
|
||||||
|
use SPC\exception\ExceptionHandler;
|
||||||
|
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
// 防止 Micro 打包状态下不支持中文的显示(虽然这个项目目前好像没输出过中文?)
|
// 防止 Micro 打包状态下不支持中文的显示(虽然这个项目目前好像没输出过中文?)
|
||||||
@@ -8,9 +11,8 @@ if (PHP_OS_FAMILY === 'Windows' && Phar::running()) {
|
|||||||
exec('CHCP 65001');
|
exec('CHCP 65001');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跑,反正一条命令跑就对了
|
|
||||||
try {
|
try {
|
||||||
(new \SPC\ConsoleApplication())->run();
|
(new ConsoleApplication())->run();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
\SPC\exception\ExceptionHandler::getInstance()->handle($e);
|
ExceptionHandler::getInstance()->handle($e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,18 @@
|
|||||||
|
|
||||||
# This file is using docker to run commands
|
# This file is using docker to run commands
|
||||||
|
|
||||||
self_dir=$(cd "$(dirname "$0")";pwd)
|
|
||||||
|
|
||||||
# Detect docker can run
|
# Detect docker can run
|
||||||
if ! which docker >/dev/null; then
|
if ! which docker >/dev/null; then
|
||||||
echo "Docker is not installed, please install docker first !"
|
echo "Docker is not installed, please install docker first !"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
DOCKER_EXECUTABLE="docker"
|
DOCKER_EXECUTABLE="docker"
|
||||||
|
# shellcheck disable=SC2046
|
||||||
if [ $(id -u) -ne 0 ]; then
|
if [ $(id -u) -ne 0 ]; then
|
||||||
if ! docker info > /dev/null 2>&1; then
|
if ! docker info > /dev/null 2>&1; then
|
||||||
if [ "$SPC_USE_SUDO" != "yes" ]; then
|
if [ "$SPC_USE_SUDO" != "yes" ]; then
|
||||||
echo "Docker command requires sudo"
|
echo "Docker command requires sudo"
|
||||||
|
# shellcheck disable=SC2039
|
||||||
echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
|
echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -33,6 +33,7 @@ x86_64)
|
|||||||
;;
|
;;
|
||||||
aarch64)
|
aarch64)
|
||||||
ALPINE_FROM=multiarch/alpine:aarch64-edge
|
ALPINE_FROM=multiarch/alpine:aarch64-edge
|
||||||
|
# shellcheck disable=SC2039
|
||||||
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
|
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
|
||||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
|
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
|
||||||
;;
|
;;
|
||||||
@@ -65,10 +66,10 @@ ADD ./bin /app/bin
|
|||||||
RUN composer update --no-dev
|
RUN composer update --no-dev
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
echo "$ALPINE_DOCKERFILE" > $(pwd)/Dockerfile
|
echo "$ALPINE_DOCKERFILE" > "$(pwd)"/Dockerfile
|
||||||
|
|
||||||
$DOCKER_EXECUTABLE build -t cwcc-spc-$SPC_USE_ARCH .
|
$DOCKER_EXECUTABLE build -t cwcc-spc-$SPC_USE_ARCH .
|
||||||
rm $(pwd)/Dockerfile
|
rm "$(pwd)"/Dockerfile
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if in ci (local terminal can execute with -it)
|
# Check if in ci (local terminal can execute with -it)
|
||||||
@@ -79,4 +80,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Run docker
|
# Run docker
|
||||||
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT=$(pwd) -v $(pwd)/config:/app/config -v $(pwd)/src:/app/src -v $(pwd)/buildroot:/app/buildroot -v $(pwd)/source:/app/source -v $(pwd)/downloads:/app/downloads cwcc-spc-$SPC_USE_ARCH bin/spc $@
|
# shellcheck disable=SC2068
|
||||||
|
$DOCKER_EXECUTABLE run --rm "$INTERACT" -e SPC_FIX_DEPLOY_ROOT="$(pwd)" -v "$(pwd)"/config:/app/config -v "$(pwd)"/src:/app/src -v "$(pwd)"/buildroot:/app/buildroot -v "$(pwd)"/source:/app/source -v "$(pwd)"/downloads:/app/downloads cwcc-spc-$SPC_USE_ARCH bin/spc $@
|
||||||
|
|||||||
@@ -9,16 +9,15 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">= 8.0",
|
"php": ">= 8.1",
|
||||||
"ext-tokenizer": "*",
|
"ext-mbstring": "*",
|
||||||
"ext-iconv": "*",
|
"ext-pcntl": "*",
|
||||||
|
"laravel/prompts": "^0.1.3",
|
||||||
"symfony/console": "^6 || ^5 || ^4",
|
"symfony/console": "^6 || ^5 || ^4",
|
||||||
"zhamao/logger": "^1.0",
|
"zhamao/logger": "^1.0"
|
||||||
"crazywhalecc/cli-helper": "^0.1.0",
|
|
||||||
"nunomaduro/collision": "*",
|
|
||||||
"ext-pcntl": "*"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"nunomaduro/collision": "*",
|
||||||
"friendsofphp/php-cs-fixer": "^3.2 != 3.7.0",
|
"friendsofphp/php-cs-fixer": "^3.2 != 3.7.0",
|
||||||
"phpstan/phpstan": "^1.1",
|
"phpstan/phpstan": "^1.1",
|
||||||
"captainhook/captainhook": "^5.10",
|
"captainhook/captainhook": "^5.10",
|
||||||
|
|||||||
@@ -100,6 +100,14 @@
|
|||||||
"gettext"
|
"gettext"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"glfw": {
|
||||||
|
"type": "external",
|
||||||
|
"arg-type": "custom",
|
||||||
|
"source": "ext-glfw",
|
||||||
|
"lib-depends": [
|
||||||
|
"glfw"
|
||||||
|
]
|
||||||
|
},
|
||||||
"gmp": {
|
"gmp": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "with-prefix",
|
"arg-type": "with-prefix",
|
||||||
@@ -138,6 +146,7 @@
|
|||||||
},
|
},
|
||||||
"intl": {
|
"intl": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
|
"cpp-extension": true,
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"icu"
|
"icu"
|
||||||
]
|
]
|
||||||
@@ -151,8 +160,9 @@
|
|||||||
},
|
},
|
||||||
"mbregex": {
|
"mbregex": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"lib-depends": [
|
"arg-type": "custom",
|
||||||
"onig"
|
"ext-depends": [
|
||||||
|
"mbstring"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mbstring": {
|
"mbstring": {
|
||||||
@@ -162,10 +172,40 @@
|
|||||||
"onig"
|
"onig"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"memcache": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "ext-memcache",
|
||||||
|
"arg-type": "custom",
|
||||||
|
"lib-depends": [
|
||||||
|
"zlib"
|
||||||
|
],
|
||||||
|
"ext-depends": [
|
||||||
|
"session"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"memcached": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "memcached",
|
||||||
|
"arg-type": "custom",
|
||||||
|
"cpp-extension": true,
|
||||||
|
"lib-depends": [
|
||||||
|
"libmemcached"
|
||||||
|
],
|
||||||
|
"ext-depends": [
|
||||||
|
"session",
|
||||||
|
"zlib"
|
||||||
|
]
|
||||||
|
},
|
||||||
"mongodb": {
|
"mongodb": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "mongodb",
|
"source": "mongodb",
|
||||||
"arg-type": "custom"
|
"arg-type": "custom",
|
||||||
|
"lib-suggests": [
|
||||||
|
"icu",
|
||||||
|
"openssl",
|
||||||
|
"zstd",
|
||||||
|
"zlib"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"mysqli": {
|
"mysqli": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
@@ -176,7 +216,10 @@
|
|||||||
},
|
},
|
||||||
"mysqlnd": {
|
"mysqlnd": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type-windows": "with"
|
"arg-type-windows": "with",
|
||||||
|
"lib-depends": [
|
||||||
|
"zlib"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"opcache": {
|
"opcache": {
|
||||||
"type": "builtin"
|
"type": "builtin"
|
||||||
@@ -205,12 +248,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": {
|
||||||
@@ -224,6 +268,13 @@
|
|||||||
"sqlite"
|
"sqlite"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"pgsql": {
|
||||||
|
"type": "builtin",
|
||||||
|
"arg-type": "with-prefix",
|
||||||
|
"lib-depends": [
|
||||||
|
"postgresql"
|
||||||
|
]
|
||||||
|
},
|
||||||
"phar": {
|
"phar": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"ext-depends": [
|
"ext-depends": [
|
||||||
@@ -255,7 +306,10 @@
|
|||||||
"redis": {
|
"redis": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "redis",
|
"source": "redis",
|
||||||
"arg-type": "custom"
|
"arg-type": "custom",
|
||||||
|
"ext-suggests": [
|
||||||
|
"session"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"session": {
|
"session": {
|
||||||
"type": "builtin"
|
"type": "builtin"
|
||||||
@@ -314,6 +368,7 @@
|
|||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "swoole",
|
"source": "swoole",
|
||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
|
"cpp-extension": true,
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"openssl"
|
"openssl"
|
||||||
],
|
],
|
||||||
@@ -321,7 +376,8 @@
|
|||||||
"openssl"
|
"openssl"
|
||||||
],
|
],
|
||||||
"ext-suggests": [
|
"ext-suggests": [
|
||||||
"curl"
|
"curl",
|
||||||
|
"pgsql"
|
||||||
],
|
],
|
||||||
"unix-only": true
|
"unix-only": true
|
||||||
},
|
},
|
||||||
@@ -360,6 +416,15 @@
|
|||||||
"tokenizer": {
|
"tokenizer": {
|
||||||
"type": "builtin"
|
"type": "builtin"
|
||||||
},
|
},
|
||||||
|
"xlswriter": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "xlswriter",
|
||||||
|
"arg-type": "custom",
|
||||||
|
"ext-depends": [
|
||||||
|
"zlib",
|
||||||
|
"zip"
|
||||||
|
]
|
||||||
|
},
|
||||||
"xml": {
|
"xml": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
|
|||||||
@@ -84,6 +84,18 @@
|
|||||||
"brotli"
|
"brotli"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"glfw": {
|
||||||
|
"source": "ext-glfw",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libglfw3.a"
|
||||||
|
],
|
||||||
|
"frameworks": [
|
||||||
|
"CoreVideo",
|
||||||
|
"OpenGL",
|
||||||
|
"Cocoa",
|
||||||
|
"IOKit"
|
||||||
|
]
|
||||||
|
},
|
||||||
"gmp": {
|
"gmp": {
|
||||||
"source": "gmp",
|
"source": "gmp",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -96,6 +108,15 @@
|
|||||||
"gmp.h"
|
"gmp.h"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"icu": {
|
||||||
|
"source": "icu",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libicui18n.a",
|
||||||
|
"libicuio.a",
|
||||||
|
"libicuuc.a",
|
||||||
|
"libicudata.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
"imagemagick": {
|
"imagemagick": {
|
||||||
"source": "imagemagick",
|
"source": "imagemagick",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -179,6 +200,13 @@
|
|||||||
"libmcrypt.a"
|
"libmcrypt.a"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"libmemcached": {
|
||||||
|
"source": "libmemcached",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libmemcached.a",
|
||||||
|
"libmemcachedutil.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
"libpng": {
|
"libpng": {
|
||||||
"source": "libpng",
|
"source": "libpng",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -200,6 +228,12 @@
|
|||||||
"zlib"
|
"zlib"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"libsodium": {
|
||||||
|
"source": "libsodium",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libsodium.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
"libssh2": {
|
"libssh2": {
|
||||||
"source": "libssh2",
|
"source": "libssh2",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -249,7 +283,8 @@
|
|||||||
],
|
],
|
||||||
"lib-suggests": [
|
"lib-suggests": [
|
||||||
"xz",
|
"xz",
|
||||||
"zlib"
|
"zlib",
|
||||||
|
"icu"
|
||||||
],
|
],
|
||||||
"lib-suggests-windows": [
|
"lib-suggests-windows": [
|
||||||
"icu",
|
"icu",
|
||||||
@@ -365,7 +400,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": {
|
||||||
@@ -454,11 +501,5 @@
|
|||||||
"zstd.h",
|
"zstd.h",
|
||||||
"zstd_errors.h"
|
"zstd_errors.h"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"libsodium": {
|
|
||||||
"source": "libsodium",
|
|
||||||
"static-libs-unix": [
|
|
||||||
"libsodium.a"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"apcu": {
|
"apcu": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "http://pecl.php.net/get/APCu",
|
"url": "https://pecl.php.net/get/APCu",
|
||||||
"path": "php-src/ext/apcu",
|
"path": "php-src/ext/apcu",
|
||||||
"filename": "apcu.tgz",
|
"filename": "apcu.tgz",
|
||||||
"license": {
|
"license": {
|
||||||
@@ -51,6 +51,15 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ext-glfw": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/mario-deluna/php-glfw",
|
||||||
|
"rev": "master",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ext-imagick": {
|
"ext-imagick": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://pecl.php.net/get/imagick",
|
"url": "https://pecl.php.net/get/imagick",
|
||||||
@@ -61,9 +70,19 @@
|
|||||||
"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": "http://pecl.php.net/get/ssh2",
|
"url": "https://pecl.php.net/get/ssh2",
|
||||||
"path": "php-src/ext/ssh2",
|
"path": "php-src/ext/ssh2",
|
||||||
"filename": "ssh2.tgz",
|
"filename": "ssh2.tgz",
|
||||||
"license": {
|
"license": {
|
||||||
@@ -91,14 +110,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gmp": {
|
"gmp": {
|
||||||
"type": "filelist",
|
"type": "ghtagtar",
|
||||||
"url": "https://gmplib.org/download/gmp/",
|
"repo": "alisw/GMP",
|
||||||
"regex": "/href=\"(?<file>gmp-(?<version>[^\"]+)\\.tar\\.xz)\"/",
|
|
||||||
"license": {
|
"license": {
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"text": "Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2. These licenses make the library free to use, share, and improve, and allow you to pass on the result. The GNU licenses give freedoms, but also set firm restrictions on the use with non-free programs."
|
"text": "Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2. These licenses make the library free to use, share, and improve, and allow you to pass on the result. The GNU licenses give freedoms, but also set firm restrictions on the use with non-free programs."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"icu": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://github.com/unicode-org/icu/releases/download/release-73-1/icu4c-73_1-src.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"imagemagick": {
|
"imagemagick": {
|
||||||
"type": "ghtar",
|
"type": "ghtar",
|
||||||
"repo": "ImageMagick/ImageMagick",
|
"repo": "ImageMagick/ImageMagick",
|
||||||
@@ -109,7 +135,7 @@
|
|||||||
},
|
},
|
||||||
"inotify": {
|
"inotify": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "http://pecl.php.net/get/inotify",
|
"url": "https://pecl.php.net/get/inotify",
|
||||||
"path": "php-src/ext/inotify",
|
"path": "php-src/ext/inotify",
|
||||||
"filename": "inotify.tgz",
|
"filename": "inotify.tgz",
|
||||||
"license": {
|
"license": {
|
||||||
@@ -168,6 +194,15 @@
|
|||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libmemcached": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/crazywhalecc/libmemcached-macos.git",
|
||||||
|
"rev": "master",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "COPYING"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libpng": {
|
"libpng": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.code.sf.net/p/libpng/code",
|
"url": "https://git.code.sf.net/p/libpng/code",
|
||||||
@@ -186,6 +221,14 @@
|
|||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libsodium": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libssh2": {
|
"libssh2": {
|
||||||
"type": "ghrel",
|
"type": "ghrel",
|
||||||
"repo": "libssh2/libssh2",
|
"repo": "libssh2/libssh2",
|
||||||
@@ -196,8 +239,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"libwebp": {
|
"libwebp": {
|
||||||
"type": "ghtagtar",
|
"type": "url",
|
||||||
"repo": "webmproject/libwebp",
|
"url": "https://github.com/webmproject/libwebp/archive/refs/tags/v1.3.0.tar.gz",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
@@ -237,6 +280,16 @@
|
|||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"memcached": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/memcached",
|
||||||
|
"path": "php-src/ext/memcached",
|
||||||
|
"filename": "memcached.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"micro": {
|
"micro": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"path": "php-src/sapi/micro",
|
"path": "php-src/sapi/micro",
|
||||||
@@ -251,7 +304,7 @@
|
|||||||
"type": "ghrel",
|
"type": "ghrel",
|
||||||
"repo": "mongodb/mongo-php-driver",
|
"repo": "mongodb/mongo-php-driver",
|
||||||
"path": "php-src/ext/mongodb",
|
"path": "php-src/ext/mongodb",
|
||||||
"match": "mongodb.+\\.tgz",
|
"match": "mongodb.+\\.zip",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
@@ -303,7 +356,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"
|
||||||
@@ -311,7 +365,7 @@
|
|||||||
},
|
},
|
||||||
"protobuf": {
|
"protobuf": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "http://pecl.php.net/get/protobuf",
|
"url": "https://pecl.php.net/get/protobuf",
|
||||||
"path": "php-src/ext/protobuf",
|
"path": "php-src/ext/protobuf",
|
||||||
"filename": "protobuf.tgz",
|
"filename": "protobuf.tgz",
|
||||||
"license": {
|
"license": {
|
||||||
@@ -375,6 +429,16 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"xlswriter": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/xlswriter",
|
||||||
|
"path": "php-src/ext/xlswriter",
|
||||||
|
"filename": "xlswriter.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"xz": {
|
"xz": {
|
||||||
"type": "filelist",
|
"type": "filelist",
|
||||||
"url": "https://tukaani.org/xz/",
|
"url": "https://tukaani.org/xz/",
|
||||||
@@ -411,13 +475,5 @@
|
|||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"libsodium": {
|
|
||||||
"type": "url",
|
|
||||||
"url": "https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gz",
|
|
||||||
"license": {
|
|
||||||
"type": "file",
|
|
||||||
"path": "LICENSE"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
107
ext-support.md
107
ext-support.md
@@ -1,108 +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 | |
|
|
||||||
| 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 | |
|
|
||||||
| openssl | yes | yes | |
|
|
||||||
| 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 | |
|
|
||||||
| 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` due to c++ extension):
|
|
||||||
|
|
||||||
```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).
|
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
# 快速启动容器环境
|
|
||||||
|
|
||||||
> 提供了 debian 11 构建 和 alpine 构建环境
|
|
||||||
> 任意选一个就可以
|
|
||||||
|
|
||||||
## debian 11 构建环境
|
|
||||||
|
|
||||||
```bash
|
|
||||||
|
|
||||||
# 启动 debian 11 容器环境
|
|
||||||
sh quickstart/linux/x86_64/run-debian-11-container.sh
|
|
||||||
|
|
||||||
# 进入容器
|
|
||||||
sh quickstart/linux/x86_64/connection-static-php-cli.sh
|
|
||||||
|
|
||||||
# 准备构建基础软件
|
|
||||||
sh quickstart/linux/x86_64/debian-11-init.sh
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## aline 构建环境
|
|
||||||
|
|
||||||
```bash
|
|
||||||
|
|
||||||
# 启动 alpine 容器环境
|
|
||||||
sh quickstart/linux/x86_64/run-alpine-3.16-container.sh
|
|
||||||
|
|
||||||
# 进入容器
|
|
||||||
sh sh quickstart/linux/x86_64/connection-static-php-cli.sh
|
|
||||||
|
|
||||||
# 准备构建基础软件
|
|
||||||
sh quickstart/linux/x86_64/alpine-3.16-init.sh
|
|
||||||
|
|
||||||
```
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -exu
|
|
||||||
__DIR__=$(
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
cd ${__DIR__}
|
|
||||||
|
|
||||||
|
|
||||||
# use china mirror
|
|
||||||
# bash quickstart/linux/x86_64/alpine-3.16-init.sh --mirror china
|
|
||||||
mirror=''
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
--mirror)
|
|
||||||
mirror="$2"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--*)
|
|
||||||
echo "Illegal option $1"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift $(( $# > 0 ? 1 : 0 ))
|
|
||||||
done
|
|
||||||
|
|
||||||
case "$mirror" in
|
|
||||||
china)
|
|
||||||
test -f /etc/apk/repositories.save || cp /etc/apk/repositories /etc/apk/repositories.save
|
|
||||||
sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
|
|
||||||
;;
|
|
||||||
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
apk update
|
|
||||||
|
|
||||||
apk add vim alpine-sdk xz autoconf automake linux-headers clang-dev clang lld libtool cmake bison re2c gettext coreutils
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -exu
|
|
||||||
__DIR__=$(
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
|
|
||||||
cd ${__DIR__}
|
|
||||||
|
|
||||||
docker exec -it static-php-cli-dev-1 sh
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -exu
|
|
||||||
__DIR__=$(
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
cd ${__DIR__}
|
|
||||||
|
|
||||||
# use china mirror
|
|
||||||
# bash quickstart/linux/x86_64/debian-11-init.sh --mirror china
|
|
||||||
mirror=''
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
--mirror)
|
|
||||||
mirror="$2"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--*)
|
|
||||||
echo "Illegal option $1"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift $(( $# > 0 ? 1 : 0 ))
|
|
||||||
done
|
|
||||||
|
|
||||||
case "$mirror" in
|
|
||||||
china)
|
|
||||||
test -f /etc/apt/sources.list.save || cp /etc/apt/sources.list /etc/apt/sources.list.save
|
|
||||||
sed -i "s@deb.debian.org@mirrors.ustc.edu.cn@g" /etc/apt/sources.list && \
|
|
||||||
sed -i "s@security.debian.org@mirrors.ustc.edu.cn@g" /etc/apt/sources.list
|
|
||||||
;;
|
|
||||||
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
apt update -y
|
|
||||||
apt install -y git curl wget ca-certificates
|
|
||||||
apt install -y xz-utils autoconf automake lld libtool cmake bison re2c gettext coreutils lzip zip unzip
|
|
||||||
apt install -y pkg-config bzip2 flex
|
|
||||||
apt install -y musl-tools g++
|
|
||||||
apt install -y clang
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -exu
|
|
||||||
__DIR__=$(
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
__PROJECT__=$(
|
|
||||||
cd ${__DIR__}/../../../
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
cd ${__PROJECT__}
|
|
||||||
|
|
||||||
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
|
|
||||||
|
|
||||||
chmod +x bin/spc
|
|
||||||
|
|
||||||
./bin/spc fetch --all --debug
|
|
||||||
|
|
||||||
./bin/spc list-ext
|
|
||||||
|
|
||||||
|
|
||||||
#./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo,pdo_sqlite,ftp,curl" --cc=gcc --cxx=g++ --debug
|
|
||||||
|
|
||||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo,pdo_sqlite,ftp,curl" --cc=clang --cxx=clang++ --debug
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -exu
|
|
||||||
__DIR__=$(
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
__PROJECT__=$(
|
|
||||||
cd ${__DIR__}/../../../
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
cd ${__DIR__}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
docker stop static-php-cli-dev-1
|
|
||||||
} || {
|
|
||||||
echo $?
|
|
||||||
}
|
|
||||||
cd ${__DIR__}
|
|
||||||
IMAGE=alpine:3.16
|
|
||||||
|
|
||||||
cd ${__DIR__}
|
|
||||||
docker run --rm --name static-php-cli-dev-1 -d -v ${__PROJECT__}:/work -w /work $IMAGE tail -f /dev/null
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -exu
|
|
||||||
__DIR__=$(
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
__PROJECT__=$(
|
|
||||||
cd ${__DIR__}/../../../
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
cd ${__DIR__}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
docker stop static-php-cli-dev-1
|
|
||||||
} || {
|
|
||||||
echo $?
|
|
||||||
}
|
|
||||||
cd ${__DIR__}
|
|
||||||
IMAGE=debian:11
|
|
||||||
|
|
||||||
cd ${__DIR__}
|
|
||||||
docker run --rm --name static-php-cli-dev-1 -d -v ${__PROJECT__}:/work -w /work $IMAGE tail -f /dev/null
|
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -exu
|
|
||||||
__DIR__=$(
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
__PROJECT__=$(
|
|
||||||
cd ${__DIR__}/../../../
|
|
||||||
pwd
|
|
||||||
)
|
|
||||||
cd ${__PROJECT__}
|
|
||||||
|
|
||||||
export PATH=${__PROJECT__}/bin/runtime:$PATH
|
|
||||||
|
|
||||||
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
|
|
||||||
|
|
||||||
chmod +x bin/spc
|
|
||||||
|
|
||||||
./bin/spc fetch --all --debug
|
|
||||||
|
|
||||||
./bin/spc list-ext
|
|
||||||
|
|
||||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo,pdo_sqlite,ftp,curl" --cc=clang --cxx=clang++ --debug
|
|
||||||
@@ -4,19 +4,17 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC;
|
namespace SPC;
|
||||||
|
|
||||||
use SPC\command\DeployCommand;
|
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
use Symfony\Component\Console\Command\HelpCommand;
|
use Symfony\Component\Console\Command\HelpCommand;
|
||||||
use Symfony\Component\Console\Command\ListCommand;
|
use Symfony\Component\Console\Command\ListCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spc 应用究级入口
|
* static-php-cli console app entry
|
||||||
*/
|
*/
|
||||||
class ConsoleApplication extends Application
|
class ConsoleApplication extends Application
|
||||||
{
|
{
|
||||||
public const VERSION = '2.0-rc1';
|
public const VERSION = '2.0.0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
@@ -28,23 +26,26 @@ class ConsoleApplication extends Application
|
|||||||
|
|
||||||
global $argv;
|
global $argv;
|
||||||
|
|
||||||
// 生产环境不显示详细的调试错误,只使用 symfony console 自带的错误显示
|
// Detailed debugging errors are not displayed in the production environment. Only the error display provided by Symfony console is used.
|
||||||
$this->setCatchExceptions(file_exists(ROOT_DIR . '/.prod') || !in_array('--debug', $argv));
|
$this->setCatchExceptions(file_exists(ROOT_DIR . '/.prod') || !in_array('--debug', $argv));
|
||||||
|
|
||||||
// 通过扫描目录 src/static-php-cli/command/ 添加子命令
|
// Add subcommands by scanning the directory src/static-php-cli/command/
|
||||||
$commands = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/command', 'SPC\\command');
|
$commands = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/command', 'SPC\\command');
|
||||||
$this->addCommands(array_map(function ($x) { return new $x(); }, array_filter($commands, function ($y) {
|
$phar = class_exists('\\Phar') && \Phar::running() || !class_exists('\\Phar');
|
||||||
if (is_a($y, DeployCommand::class, true) && (class_exists('\\Phar') && \Phar::running() || !class_exists('\\Phar'))) {
|
$commands = array_filter($commands, function ($y) use ($phar) {
|
||||||
|
$archive_blacklist = [
|
||||||
|
'SPC\command\dev\SortConfigCommand',
|
||||||
|
'SPC\command\DeployCommand',
|
||||||
|
];
|
||||||
|
if ($phar && in_array($y, $archive_blacklist)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$reflection = new \ReflectionClass($y);
|
$reflection = new \ReflectionClass($y);
|
||||||
return !$reflection->isAbstract() && !$reflection->isInterface();
|
return !$reflection->isAbstract() && !$reflection->isInterface();
|
||||||
})));
|
});
|
||||||
|
$this->addCommands(array_map(function ($x) { return new $x(); }, $commands));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 重载以去除一些不必要的默认命令
|
|
||||||
*/
|
|
||||||
protected function getDefaultCommands(): array
|
protected function getDefaultCommands(): array
|
||||||
{
|
{
|
||||||
return [new HelpCommand(), new ListCommand()];
|
return [new HelpCommand(), new ListCommand()];
|
||||||
|
|||||||
@@ -9,48 +9,38 @@ use SPC\exception\RuntimeException;
|
|||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\store\SourceExtractor;
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
use SPC\util\DependencyUtil;
|
use SPC\util\DependencyUtil;
|
||||||
|
|
||||||
abstract class BuilderBase
|
abstract class BuilderBase
|
||||||
{
|
{
|
||||||
/** @var bool 是否启用 ZTS 线程安全 */
|
/** @var int Concurrency */
|
||||||
public bool $zts = false;
|
|
||||||
|
|
||||||
/** @var string 编译目标架构 */
|
|
||||||
public string $arch;
|
|
||||||
|
|
||||||
/** @var string GNU 格式的编译目标架构 */
|
|
||||||
public string $gnu_arch;
|
|
||||||
|
|
||||||
/** @var int 编译进程数 */
|
|
||||||
public int $concurrency = 1;
|
public int $concurrency = 1;
|
||||||
|
|
||||||
/** @var array<string, LibraryBase> 要编译的 libs 列表 */
|
/** @var array<string, LibraryBase> libraries */
|
||||||
protected array $libs = [];
|
protected array $libs = [];
|
||||||
|
|
||||||
/** @var array<string, Extension> 要编译的扩展列表 */
|
/** @var array<string, Extension> extensions */
|
||||||
protected array $exts = [];
|
protected array $exts = [];
|
||||||
|
|
||||||
/** @var array<int, string> 要编译的扩展列表(仅名字列表,用于最后生成编译的扩展列表给 micro) */
|
/** @var bool compile libs only (just mark it) */
|
||||||
protected array $plain_extensions = [];
|
|
||||||
|
|
||||||
/** @var bool 本次编译是否只编译 libs,不编译 PHP */
|
|
||||||
protected bool $libs_only = false;
|
protected bool $libs_only = false;
|
||||||
|
|
||||||
/** @var bool 是否 strip 最终的二进制 */
|
/** @var array<string, mixed> compile options */
|
||||||
protected bool $strip = true;
|
protected array $options = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建指定列表的 libs
|
* Build libraries
|
||||||
*
|
*
|
||||||
|
* @param array<string> $libraries Libraries to build
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function buildLibs(array $libraries): void
|
public function buildLibs(array $libraries): void
|
||||||
{
|
{
|
||||||
// 通过扫描目录查找 lib
|
// search all supported libs
|
||||||
$support_lib_list = [];
|
$support_lib_list = [];
|
||||||
$classes = FileSystem::getClassesPsr4(
|
$classes = FileSystem::getClassesPsr4(
|
||||||
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
|
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
|
||||||
@@ -62,19 +52,22 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果传入了空,则默认检查和安置所有支持的lib,libraries为要build的,support_lib_list为支持的列表
|
// if no libs specified, compile all supported libs
|
||||||
if ($libraries === [] && $this->isLibsOnly()) {
|
if ($libraries === [] && $this->isLibsOnly()) {
|
||||||
$libraries = array_keys($support_lib_list);
|
$libraries = array_keys($support_lib_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pkg-config must be compiled first, whether it is specified or not
|
||||||
if (!in_array('pkg-config', $libraries)) {
|
if (!in_array('pkg-config', $libraries)) {
|
||||||
array_unshift($libraries, 'pkg-config');
|
array_unshift($libraries, 'pkg-config');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 排序 libs,根据依赖计算一个新的列表出来
|
// append dependencies
|
||||||
$libraries = DependencyUtil::getLibsByDeps($libraries);
|
$libraries = DependencyUtil::getLibsByDeps($libraries);
|
||||||
|
|
||||||
// 过滤不支持的库后添加
|
// add lib object for builder
|
||||||
foreach ($libraries as $library) {
|
foreach ($libraries as $library) {
|
||||||
|
// if some libs are not supported (but in config "lib.json", throw exception)
|
||||||
if (!isset($support_lib_list[$library])) {
|
if (!isset($support_lib_list[$library])) {
|
||||||
throw new RuntimeException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
|
throw new RuntimeException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
|
||||||
}
|
}
|
||||||
@@ -82,14 +75,15 @@ abstract class BuilderBase
|
|||||||
$this->addLib($lib);
|
$this->addLib($lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算依赖,经过这里的遍历,如果没有抛出异常,说明依赖符合要求,可以继续下面的
|
// calculate and check dependencies
|
||||||
foreach ($this->libs as $lib) {
|
foreach ($this->libs as $lib) {
|
||||||
$lib->calcDependency();
|
$lib->calcDependency();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->initSource(libs: $libraries);
|
// extract sources
|
||||||
|
SourceExtractor::initSource(libs: $libraries);
|
||||||
|
|
||||||
// 构建库
|
// build all libs
|
||||||
foreach ($this->libs as $lib) {
|
foreach ($this->libs as $lib) {
|
||||||
match ($lib->tryBuild()) {
|
match ($lib->tryBuild()) {
|
||||||
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
|
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
|
||||||
@@ -101,9 +95,9 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加要编译的 Lib 库
|
* Add library to build.
|
||||||
*
|
*
|
||||||
* @param LibraryBase $library Lib 库对象
|
* @param LibraryBase $library Library object
|
||||||
*/
|
*/
|
||||||
public function addLib(LibraryBase $library): void
|
public function addLib(LibraryBase $library): void
|
||||||
{
|
{
|
||||||
@@ -111,9 +105,7 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取要编译的 Lib 库对象
|
* Get library object by name.
|
||||||
*
|
|
||||||
* @param string $name 库名称
|
|
||||||
*/
|
*/
|
||||||
public function getLib(string $name): ?LibraryBase
|
public function getLib(string $name): ?LibraryBase
|
||||||
{
|
{
|
||||||
@@ -121,9 +113,7 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加要编译的扩展
|
* Add extension to build.
|
||||||
*
|
|
||||||
* @param Extension $extension 扩展对象
|
|
||||||
*/
|
*/
|
||||||
public function addExt(Extension $extension): void
|
public function addExt(Extension $extension): void
|
||||||
{
|
{
|
||||||
@@ -131,9 +121,7 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取要编译的扩展对象
|
* Get extension object by name.
|
||||||
*
|
|
||||||
* @param string $name 扩展名称
|
|
||||||
*/
|
*/
|
||||||
public function getExt(string $name): ?Extension
|
public function getExt(string $name): ?Extension
|
||||||
{
|
{
|
||||||
@@ -141,7 +129,37 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置本次 Builder 是否为仅编译库的模式
|
* Get all extension objects.
|
||||||
|
*
|
||||||
|
* @return Extension[]
|
||||||
|
*/
|
||||||
|
public function getExts(): array
|
||||||
|
{
|
||||||
|
return $this->exts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there is a cpp extension.
|
||||||
|
*
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set libs only mode.
|
||||||
*/
|
*/
|
||||||
public function setLibsOnly(bool $status = true): void
|
public function setLibsOnly(bool $status = true): void
|
||||||
{
|
{
|
||||||
@@ -149,19 +167,21 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检验 ext 扩展列表是否合理,并声明 Extension 对象,检查扩展的依赖
|
* Verify the list of "ext" extensions for validity and declare an Extension object to check the dependencies of the extensions.
|
||||||
*
|
*
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws \ReflectionException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function proveExts(array $extensions): void
|
public function proveExts(array $extensions): void
|
||||||
{
|
{
|
||||||
CustomExt::loadCustomExt();
|
CustomExt::loadCustomExt();
|
||||||
$this->initSource(sources: ['php-src']);
|
SourceExtractor::initSource(sources: ['php-src']);
|
||||||
if ($this->getPHPVersionID() >= 80000) {
|
if ($this->getPHPVersionID() >= 80000) {
|
||||||
$this->initSource(sources: ['micro']);
|
SourceExtractor::initSource(sources: ['micro']);
|
||||||
}
|
}
|
||||||
$this->initSource(exts: $extensions);
|
SourceExtractor::initSource(exts: $extensions);
|
||||||
foreach ($extensions as $extension) {
|
foreach ($extensions as $extension) {
|
||||||
$class = CustomExt::getExtClass($extension);
|
$class = CustomExt::getExtClass($extension);
|
||||||
$ext = new $class($extension, $this);
|
$ext = new $class($extension, $this);
|
||||||
@@ -169,27 +189,23 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->exts as $ext) {
|
foreach ($this->exts as $ext) {
|
||||||
// 检查下依赖就行了,作用是导入依赖给 Extension 对象,今后可以对库依赖进行选择性处理
|
|
||||||
$ext->checkDependency();
|
$ext->checkDependency();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->plain_extensions = $extensions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始构建 PHP
|
* Start to build PHP
|
||||||
*
|
*
|
||||||
* @param int $build_target 规则
|
* @param int $build_target Build target, see BUILD_TARGET_*
|
||||||
* @param bool $bloat 保留
|
|
||||||
*/
|
*/
|
||||||
abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = false);
|
abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成依赖的扩展编译启用参数
|
* Generate extension enable arguments for configure.
|
||||||
* 例如 --enable-mbstring 等
|
* e.g. --enable-mbstring
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function makeExtensionArgs(): string
|
public function makeExtensionArgs(): string
|
||||||
{
|
{
|
||||||
@@ -202,7 +218,7 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回是否只编译 libs 的模式
|
* Get libs only mode.
|
||||||
*/
|
*/
|
||||||
public function isLibsOnly(): bool
|
public function isLibsOnly(): bool
|
||||||
{
|
{
|
||||||
@@ -210,7 +226,7 @@ abstract class BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前即将编译的 PHP 的版本 ID,五位数那个
|
* Get PHP Version ID from php-src/main/php_version.h
|
||||||
*/
|
*/
|
||||||
public function getPHPVersionID(): int
|
public function getPHPVersionID(): int
|
||||||
{
|
{
|
||||||
@@ -219,6 +235,11 @@ abstract class BuilderBase
|
|||||||
return intval($match[1]);
|
return intval($match[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get build type name string to display.
|
||||||
|
*
|
||||||
|
* @param int $type Build target type
|
||||||
|
*/
|
||||||
public function getBuildTypeName(int $type): string
|
public function getBuildTypeName(int $type): string
|
||||||
{
|
{
|
||||||
$ls = [];
|
$ls = [];
|
||||||
@@ -234,13 +255,46 @@ abstract class BuilderBase
|
|||||||
return implode(', ', $ls);
|
return implode(', ', $ls);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setStrip(bool $strip): void
|
/**
|
||||||
|
* Get builder options (maybe changed by user)
|
||||||
|
*
|
||||||
|
* @param string $key Option key
|
||||||
|
* @param mixed $default If not exists, return this value
|
||||||
|
*/
|
||||||
|
public function getOption(string $key, mixed $default = null): mixed
|
||||||
{
|
{
|
||||||
$this->strip = $strip;
|
return $this->options[$key] ?? $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否存在 lib 库对应的源码,如果不存在,则抛出异常
|
* Get all builder options
|
||||||
|
*/
|
||||||
|
public function getOptions(): array
|
||||||
|
{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set builder options if not exists.
|
||||||
|
*/
|
||||||
|
public function setOptionIfNotExist(string $key, mixed $value): void
|
||||||
|
{
|
||||||
|
if (!isset($this->options[$key])) {
|
||||||
|
$this->options[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set builder options.
|
||||||
|
*/
|
||||||
|
public function setOption(string $key, mixed $value): void
|
||||||
|
{
|
||||||
|
$this->options[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all libs are downloaded.
|
||||||
|
* If not, throw exception.
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
@@ -261,52 +315,4 @@ abstract class BuilderBase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initSource(?array $sources = null, ?array $libs = null, ?array $exts = null): void
|
|
||||||
{
|
|
||||||
if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) {
|
|
||||||
throw new WrongUsageException('Download lock file "downloads/.lock.json" not found, maybe you need to download sources first ?');
|
|
||||||
}
|
|
||||||
$lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true);
|
|
||||||
|
|
||||||
$sources_extracted = [];
|
|
||||||
// source check exist
|
|
||||||
if (is_array($sources)) {
|
|
||||||
foreach ($sources as $source) {
|
|
||||||
$sources_extracted[$source] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// lib check source exist
|
|
||||||
if (is_array($libs)) {
|
|
||||||
foreach ($libs as $lib) {
|
|
||||||
// get source name for lib
|
|
||||||
$source = Config::getLib($lib, 'source');
|
|
||||||
$sources_extracted[$source] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ext check source exist
|
|
||||||
if (is_array($exts)) {
|
|
||||||
foreach ($exts as $ext) {
|
|
||||||
// get source name for ext
|
|
||||||
if (Config::getExt($ext, 'type') !== 'external') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$source = Config::getExt($ext, 'source');
|
|
||||||
$sources_extracted[$source] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// start check
|
|
||||||
foreach ($sources_extracted as $source => $item) {
|
|
||||||
if (!isset($lock[$source])) {
|
|
||||||
throw new WrongUsageException('Source [' . $source . '] not downloaded, you should download it first !');
|
|
||||||
}
|
|
||||||
|
|
||||||
// check source dir exist
|
|
||||||
$check = $lock[$source]['move_path'] === null ? SOURCE_PATH . '/' . $source : SOURCE_PATH . '/' . $lock[$source]['move_path'];
|
|
||||||
if (!is_dir($check)) {
|
|
||||||
FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), $lock[$source]['move_path']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace SPC\builder;
|
|||||||
|
|
||||||
use SPC\builder\linux\LinuxBuilder;
|
use SPC\builder\linux\LinuxBuilder;
|
||||||
use SPC\builder\macos\MacOSBuilder;
|
use SPC\builder\macos\MacOSBuilder;
|
||||||
use SPC\builder\windows\WindowsBuilder;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
@@ -17,7 +17,9 @@ use Symfony\Component\Console\Input\InputInterface;
|
|||||||
class BuilderProvider
|
class BuilderProvider
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public static function makeBuilderByInput(InputInterface $input): BuilderBase
|
public static function makeBuilderByInput(InputInterface $input): BuilderBase
|
||||||
{
|
{
|
||||||
@@ -27,18 +29,8 @@ class BuilderProvider
|
|||||||
// vs_ver: $input->getOption('vs-ver'),
|
// vs_ver: $input->getOption('vs-ver'),
|
||||||
// arch: $input->getOption('arch'),
|
// arch: $input->getOption('arch'),
|
||||||
// ),
|
// ),
|
||||||
'Darwin' => new MacOSBuilder(
|
'Darwin' => new MacOSBuilder($input->getOptions()),
|
||||||
cc: $input->getOption('cc'),
|
'Linux' => new LinuxBuilder($input->getOptions()),
|
||||||
cxx: $input->getOption('cxx'),
|
|
||||||
arch: $input->getOption('arch'),
|
|
||||||
zts: $input->getOption('enable-zts'),
|
|
||||||
),
|
|
||||||
'Linux' => new LinuxBuilder(
|
|
||||||
cc: $input->getOption('cc'),
|
|
||||||
cxx: $input->getOption('cxx'),
|
|
||||||
arch: $input->getOption('arch'),
|
|
||||||
zts: $input->getOption('enable-zts'),
|
|
||||||
),
|
|
||||||
default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'),
|
default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class Extension
|
|||||||
/**
|
/**
|
||||||
* 获取开启该扩展的 PHP 编译添加的参数
|
* 获取开启该扩展的 PHP 编译添加的参数
|
||||||
*
|
*
|
||||||
* @throws FileSystemException|RuntimeException
|
* @throws FileSystemException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function getConfigureArg(): string
|
public function getConfigureArg(): string
|
||||||
@@ -56,7 +56,6 @@ class Extension
|
|||||||
* 根据 ext 的 arg-type 获取对应开启的参数,一般都是 --enable-xxx 和 --with-xxx
|
* 根据 ext 的 arg-type 获取对应开启的参数,一般都是 --enable-xxx 和 --with-xxx
|
||||||
*
|
*
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function getEnableArg(): string
|
public function getEnableArg(): string
|
||||||
@@ -136,6 +135,33 @@ class Extension
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch code before ./buildconf
|
||||||
|
* If you need to patch some code, overwrite this and return true
|
||||||
|
*/
|
||||||
|
public function patchBeforeBuildconf(): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch code before ./configure
|
||||||
|
* If you need to patch some code, overwrite this and return true
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch code before make
|
||||||
|
* If you need to patch some code, overwrite this and return true
|
||||||
|
*/
|
||||||
|
public function patchBeforeMake(): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,20 +7,16 @@ namespace SPC\builder;
|
|||||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
|
|
||||||
/**
|
|
||||||
* Lib 库的基类操作对象
|
|
||||||
*/
|
|
||||||
abstract class LibraryBase
|
abstract class LibraryBase
|
||||||
{
|
{
|
||||||
/** @var string lib 依赖名称,必须重写 */
|
/** @var string */
|
||||||
public const NAME = 'unknown';
|
public const NAME = 'unknown';
|
||||||
|
|
||||||
/** @var string lib 依赖的根目录 */
|
|
||||||
protected string $source_dir;
|
protected string $source_dir;
|
||||||
|
|
||||||
/** @var array 依赖列表 */
|
|
||||||
protected array $dependencies = [];
|
protected array $dependencies = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,7 +31,7 @@ abstract class LibraryBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 lib 库的根目录
|
* Get current lib source root dir.
|
||||||
*/
|
*/
|
||||||
public function getSourceDir(): string
|
public function getSourceDir(): string
|
||||||
{
|
{
|
||||||
@@ -43,10 +39,9 @@ abstract class LibraryBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 lib 库的所有依赖列表
|
* Get current lib dependencies.
|
||||||
*
|
*
|
||||||
* @param bool $recursive 是否递归获取(默认为 False)
|
* @return array<string, LibraryBase>
|
||||||
* @return array<string, LibraryBase> 依赖的 Map
|
|
||||||
*/
|
*/
|
||||||
public function getDependencies(bool $recursive = false): array
|
public function getDependencies(bool $recursive = false): array
|
||||||
{
|
{
|
||||||
@@ -55,7 +50,6 @@ abstract class LibraryBase
|
|||||||
return $this->dependencies;
|
return $this->dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下面为递归获取依赖列表,根据依赖顺序
|
|
||||||
$deps = [];
|
$deps = [];
|
||||||
|
|
||||||
$added = 1;
|
$added = 1;
|
||||||
@@ -78,20 +72,21 @@ abstract class LibraryBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算依赖列表,不符合依赖将抛出异常
|
* Calculate dependencies for current library.
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function calcDependency(): void
|
public function calcDependency(): void
|
||||||
{
|
{
|
||||||
// 先从配置文件添加依赖,这里根据不同的操作系统分别选择不同的元信息
|
// Add dependencies from the configuration file. Here, choose different metadata based on the operating system.
|
||||||
/*
|
/*
|
||||||
选择规则:
|
Rules:
|
||||||
如果是 Windows 系统,则依次尝试有无 lib-depends-windows、lib-depends-win、lib-depends。
|
If it is a Windows system, try the following dependencies in order: lib-depends-windows, lib-depends-win, lib-depends.
|
||||||
如果是 macOS 系统,则依次尝试 lib-depends-darwin、lib-depends-unix、lib-depends。
|
If it is a macOS system, try the following dependencies in order: lib-depends-darwin, lib-depends-unix, lib-depends.
|
||||||
如果是 Linux 系统,则依次尝试 lib-depends-linux、lib-depends-unix、lib-depends。
|
If it is a Linux system, try the following dependencies in order: lib-depends-linux, lib-depends-unix, lib-depends.
|
||||||
*/
|
*/
|
||||||
foreach (Config::getLib(static::NAME, 'lib-depends', []) as $dep_name) {
|
foreach (Config::getLib(static::NAME, 'lib-depends', []) as $dep_name) {
|
||||||
$this->addLibraryDependency($dep_name);
|
$this->addLibraryDependency($dep_name);
|
||||||
}
|
}
|
||||||
@@ -101,11 +96,10 @@ abstract class LibraryBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前库编译出来获取到的静态库文件列表
|
* Get config static libs.
|
||||||
*
|
*
|
||||||
* @return string[] 获取编译出来后的需要的静态库文件列表
|
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function getStaticLibs(): array
|
public function getStaticLibs(): array
|
||||||
{
|
{
|
||||||
@@ -113,11 +107,10 @@ abstract class LibraryBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 lib 编译出来的 C Header 文件列表
|
* Get config headers.
|
||||||
*
|
*
|
||||||
* @return string[] 获取编译出来后需要的 C Header 文件列表
|
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function getHeaders(): array
|
public function getHeaders(): array
|
||||||
{
|
{
|
||||||
@@ -125,73 +118,84 @@ abstract class LibraryBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 证明该库是否已编译好且就绪,如果没有就绪,内部会调用 build 来进行构建该库
|
* Try to build this library, before build, we check first.
|
||||||
|
*
|
||||||
|
* BUILD_STATUS_OK if build success
|
||||||
|
* BUILD_STATUS_ALREADY if already built
|
||||||
|
* BUILD_STATUS_FAILED if build failed
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function tryBuild(bool $force_build = false): int
|
public function tryBuild(bool $force_build = false): int
|
||||||
{
|
{
|
||||||
// 传入 true,表明直接编译
|
// force means just build
|
||||||
if ($force_build) {
|
if ($force_build) {
|
||||||
logger()->info('Building required library [' . static::NAME . ']');
|
logger()->info('Building required library [' . static::NAME . ']');
|
||||||
|
$this->patchBeforeBuild();
|
||||||
$this->build();
|
$this->build();
|
||||||
return BUILD_STATUS_OK;
|
return BUILD_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 看看这些库是不是存在,如果不存在,则调用编译并返回结果状态
|
// check if these libraries exist, if not, invoke compilation and return the result status
|
||||||
foreach ($this->getStaticLibs() as $name) {
|
foreach ($this->getStaticLibs() as $name) {
|
||||||
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
||||||
$this->tryBuild(true);
|
$this->tryBuild(true);
|
||||||
return BUILD_STATUS_OK;
|
return BUILD_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 头文件同理
|
// header files the same
|
||||||
foreach ($this->getHeaders() as $name) {
|
foreach ($this->getHeaders() as $name) {
|
||||||
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
||||||
$this->tryBuild(true);
|
$this->tryBuild(true);
|
||||||
return BUILD_STATUS_OK;
|
return BUILD_STATUS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// pkg-config 做特殊处理,如果是 pkg-config 就检查有没有 pkg-config 二进制
|
// pkg-config is treated specially. If it is pkg-config, check if the pkg-config binary exists
|
||||||
if ($this instanceof MacOSLibraryBase && static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
|
if ($this instanceof MacOSLibraryBase && static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
|
||||||
$this->tryBuild(true);
|
$this->tryBuild(true);
|
||||||
return BUILD_STATUS_OK;
|
return BUILD_STATUS_OK;
|
||||||
}
|
}
|
||||||
// 到这里说明所有的文件都存在,就跳过编译
|
// if all the files exist at this point, skip the compilation process
|
||||||
return BUILD_STATUS_ALREADY;
|
return BUILD_STATUS_ALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取构建当前 lib 的 Builder 对象
|
* Patch before build, overwrite this and return true to patch libs.
|
||||||
|
*/
|
||||||
|
public function patchBeforeBuild(): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current builder object.
|
||||||
*/
|
*/
|
||||||
abstract public function getBuilder(): BuilderBase;
|
abstract public function getBuilder(): BuilderBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建该库需要调用的命令和操作
|
* Build this library.
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
abstract protected function build();
|
abstract protected function build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加 lib 库的依赖库
|
* Add lib dependency
|
||||||
*
|
*
|
||||||
* @param string $name 依赖名称
|
|
||||||
* @param bool $optional 是否是可选依赖(默认为 False)
|
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
protected function addLibraryDependency(string $name, bool $optional = false): void
|
protected function addLibraryDependency(string $name, bool $optional = false): void
|
||||||
{
|
{
|
||||||
// Log::i("add $name as dep of {$this->name}");
|
|
||||||
$dep_lib = $this->getBuilder()->getLib($name);
|
$dep_lib = $this->getBuilder()->getLib($name);
|
||||||
if (!$dep_lib) {
|
if ($dep_lib) {
|
||||||
if (!$optional) {
|
|
||||||
throw new RuntimeException(static::NAME . " requires library {$name}");
|
|
||||||
}
|
|
||||||
logger()->debug('enabling ' . static::NAME . " without {$name}");
|
|
||||||
} else {
|
|
||||||
$this->dependencies[$name] = $dep_lib;
|
$this->dependencies[$name] = $dep_lib;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (!$optional) {
|
||||||
|
throw new RuntimeException(static::NAME . " requires library {$name}");
|
||||||
|
}
|
||||||
|
logger()->debug('enabling ' . static::NAME . " without {$name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/SPC/builder/extension/bz2.php
Normal file
27
src/SPC/builder/extension/bz2.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\builder\macos\MacOSBuilder;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('bz2')]
|
||||||
|
class bz2 extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
|
||||||
|
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-lbz2/', $this->getLibFilesString() . $frameworks);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
57
src/SPC/builder/extension/curl.php
Normal file
57
src/SPC/builder/extension/curl.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\builder\macos\MacOSBuilder;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('curl')]
|
||||||
|
class curl extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeBuildconf(): bool
|
||||||
|
{
|
||||||
|
logger()->info('patching before-configure for curl checks');
|
||||||
|
$file1 = "AC_DEFUN([PHP_CHECK_LIBRARY], [\n $3\n])";
|
||||||
|
$files = FileSystem::readFile(SOURCE_PATH . '/php-src/ext/curl/config.m4');
|
||||||
|
$file2 = 'AC_DEFUN([PHP_CHECK_LIBRARY], [
|
||||||
|
save_old_LDFLAGS=$LDFLAGS
|
||||||
|
ac_stuff="$5"
|
||||||
|
|
||||||
|
save_ext_shared=$ext_shared
|
||||||
|
ext_shared=yes
|
||||||
|
PHP_EVAL_LIBLINE([$]ac_stuff, LDFLAGS)
|
||||||
|
AC_CHECK_LIB([$1],[$2],[
|
||||||
|
LDFLAGS=$save_old_LDFLAGS
|
||||||
|
ext_shared=$save_ext_shared
|
||||||
|
$3
|
||||||
|
],[
|
||||||
|
LDFLAGS=$save_old_LDFLAGS
|
||||||
|
ext_shared=$save_ext_shared
|
||||||
|
unset ac_cv_lib_$1[]_$2
|
||||||
|
$4
|
||||||
|
])dnl
|
||||||
|
])';
|
||||||
|
file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
|
||||||
|
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-lcurl/', $this->getLibFilesString() . $frameworks);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ declare(strict_types=1);
|
|||||||
namespace SPC\builder\extension;
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
use SPC\builder\Extension;
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
#[CustomExt('event')]
|
#[CustomExt('event')]
|
||||||
@@ -23,4 +25,13 @@ class event extends Extension
|
|||||||
}
|
}
|
||||||
return $arg;
|
return $arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-levent_openssl/', $this->getLibFilesString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/SPC/builder/extension/glfw.php
Normal file
28
src/SPC/builder/extension/glfw.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('glfw')]
|
||||||
|
class glfw extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
public function patchBeforeBuildconf(): bool
|
||||||
|
{
|
||||||
|
FileSystem::copyDir(SOURCE_PATH . '/ext-glfw', SOURCE_PATH . '/php-src/ext/glfw');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUnixConfigureArg(): string
|
||||||
|
{
|
||||||
|
return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/SPC/builder/extension/iconv.php
Normal file
23
src/SPC/builder/extension/iconv.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('iconv')]
|
||||||
|
class iconv extends Extension
|
||||||
|
{
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
// macOS need to link iconv dynamically, we add it to extra-libs
|
||||||
|
$extra_libs = $this->builder->getOption('extra-libs', '');
|
||||||
|
if (!str_contains($extra_libs, '-liconv')) {
|
||||||
|
$extra_libs .= ' -liconv';
|
||||||
|
}
|
||||||
|
$this->builder->setOption('extra-libs', $extra_libs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,17 @@ use SPC\util\CustomExt;
|
|||||||
#[CustomExt('imagick')]
|
#[CustomExt('imagick')]
|
||||||
class imagick extends Extension
|
class imagick extends Extension
|
||||||
{
|
{
|
||||||
|
public function patchBeforeBuildconf(): bool
|
||||||
|
{
|
||||||
|
// linux need to link library manually, we add it to extra-libs
|
||||||
|
$extra_libs = $this->builder->getOption('extra-libs', '');
|
||||||
|
if (!str_contains($extra_libs, 'libMagickCore')) {
|
||||||
|
$extra_libs .= ' /usr/lib/libMagick++-7.Q16HDRI.a /usr/lib/libMagickCore-7.Q16HDRI.a /usr/lib/libMagickWand-7.Q16HDRI.a';
|
||||||
|
}
|
||||||
|
$this->builder->setOption('extra-libs', $extra_libs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function getUnixConfigureArg(): string
|
public function getUnixConfigureArg(): string
|
||||||
{
|
{
|
||||||
return '--with-imagick=' . BUILD_ROOT_PATH;
|
return '--with-imagick=' . BUILD_ROOT_PATH;
|
||||||
|
|||||||
@@ -14,4 +14,9 @@ class mbregex extends Extension
|
|||||||
{
|
{
|
||||||
return 'mbstring';
|
return 'mbstring';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfigureArg(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
src/SPC/builder/extension/memcache.php
Normal file
50
src/SPC/builder/extension/memcache.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('memcache')]
|
||||||
|
class memcache extends Extension
|
||||||
|
{
|
||||||
|
public function getUnixConfigureArg(): string
|
||||||
|
{
|
||||||
|
return '--enable-memcache --with-zlib-dir=' . BUILD_ROOT_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeBuildconf(): bool
|
||||||
|
{
|
||||||
|
FileSystem::replaceFileStr(
|
||||||
|
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
|
||||||
|
'if test -d $abs_srcdir/src ; then',
|
||||||
|
'if test -d $abs_srcdir/main ; then'
|
||||||
|
);
|
||||||
|
FileSystem::replaceFileStr(
|
||||||
|
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
|
||||||
|
'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
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,16 @@ class mongodb extends Extension
|
|||||||
{
|
{
|
||||||
public function getUnixConfigureArg(): string
|
public function getUnixConfigureArg(): string
|
||||||
{
|
{
|
||||||
return '--enable-mongodb --without-mongodb-sasl';
|
$arg = ' --enable-mongodb ';
|
||||||
|
$arg .= ' --with-mongodb-system-libs=no --with-mongodb-client-side-encryption=no ';
|
||||||
|
$arg .= ' --with-mongodb-sasl=no ';
|
||||||
|
if ($this->builder->getLib('openssl')) {
|
||||||
|
$arg .= '--with-mongodb-ssl=openssl';
|
||||||
|
}
|
||||||
|
$arg .= $this->builder->getLib('icu') ? ' --with-mongodb-icu=yes ' : ' --with-mongodb-icu=no ';
|
||||||
|
$arg .= $this->builder->getLib('zstd') ? ' --with-mongodb-zstd=yes ' : ' --with-mongodb-zstd=no ';
|
||||||
|
// $arg .= $this->builder->getLib('snappy') ? ' --with-mongodb-snappy=yes ' : ' --with-mongodb-snappy=no ';
|
||||||
|
$arg .= $this->builder->getLib('zlib') ? ' --with-mongodb-zlib=yes ' : ' --with-mongodb-zlib=bundled ';
|
||||||
|
return $arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/SPC/builder/extension/openssl.php
Normal file
25
src/SPC/builder/extension/openssl.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
use SPC\util\Util;
|
||||||
|
|
||||||
|
#[CustomExt('openssl')]
|
||||||
|
class openssl extends Extension
|
||||||
|
{
|
||||||
|
public function patchBeforeMake(): bool
|
||||||
|
{
|
||||||
|
// patch openssl3 with php8.0 bug
|
||||||
|
if (file_exists(SOURCE_PATH . '/openssl/VERSION.dat') && Util::getPHPVersionID() < 80100) {
|
||||||
|
$openssl_c = file_get_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c');
|
||||||
|
$openssl_c = preg_replace('/REGISTER_LONG_CONSTANT\s*\(\s*"OPENSSL_SSLV23_PADDING"\s*.+;/', '', $openssl_c);
|
||||||
|
file_put_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c', $openssl_c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/SPC/builder/extension/pdo_sqlite.php
Normal file
27
src/SPC/builder/extension/pdo_sqlite.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('pdo_sqlite')]
|
||||||
|
class pdo_sqlite extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
FileSystem::replaceFileRegex(
|
||||||
|
SOURCE_PATH . '/php-src/configure',
|
||||||
|
'/sqlite3_column_table_name=yes/',
|
||||||
|
'sqlite3_column_table_name=no'
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/SPC/builder/extension/pgsql.php
Normal file
27
src/SPC/builder/extension/pgsql.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('pgsql')]
|
||||||
|
class pgsql extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
FileSystem::replaceFileRegex(
|
||||||
|
SOURCE_PATH . '/php-src/configure',
|
||||||
|
'/-lpq/',
|
||||||
|
$this->getLibFilesString()
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/SPC/builder/extension/readline.php
Normal file
27
src/SPC/builder/extension/readline.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('readline')]
|
||||||
|
class readline extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
FileSystem::replaceFileRegex(
|
||||||
|
SOURCE_PATH . '/php-src/configure',
|
||||||
|
'/-lncurses/',
|
||||||
|
$this->getLibFilesString()
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,12 @@ class redis extends Extension
|
|||||||
{
|
{
|
||||||
public function getUnixConfigureArg(): string
|
public function getUnixConfigureArg(): string
|
||||||
{
|
{
|
||||||
$arg = '--enable-redis --disable-redis-session';
|
$arg = '--enable-redis';
|
||||||
|
if (!$this->builder->getExt('session')) {
|
||||||
|
$arg .= ' --disable-redis-session';
|
||||||
|
} else {
|
||||||
|
$arg .= ' --enable-redis-session';
|
||||||
|
}
|
||||||
if ($this->builder->getLib('zstd')) {
|
if ($this->builder->getLib('zstd')) {
|
||||||
$arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"';
|
$arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"';
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/SPC/builder/extension/ssh2.php
Normal file
27
src/SPC/builder/extension/ssh2.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('ssh2')]
|
||||||
|
class ssh2 extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeConfigure(): bool
|
||||||
|
{
|
||||||
|
FileSystem::replaceFileRegex(
|
||||||
|
SOURCE_PATH . '/php-src/configure',
|
||||||
|
'/-lssh2/',
|
||||||
|
$this->getLibFilesString()
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ class swoole extends Extension
|
|||||||
public function getUnixConfigureArg(): string
|
public function getUnixConfigureArg(): string
|
||||||
{
|
{
|
||||||
$arg = '--enable-swoole';
|
$arg = '--enable-swoole';
|
||||||
|
$arg .= $this->builder->getExt('pgsql') ? ' --enable-swoole-pgsql' : ' --disable-swoole-pgsql';
|
||||||
$arg .= $this->builder->getLib('openssl') ? ' --enable-openssl' : ' --disable-openssl --without-openssl';
|
$arg .= $this->builder->getLib('openssl') ? ' --enable-openssl' : ' --disable-openssl --without-openssl';
|
||||||
$arg .= $this->builder->getLib('brotli') ? (' --enable-brotli --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
|
$arg .= $this->builder->getLib('brotli') ? (' --enable-brotli --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
|
||||||
// curl hook is buggy for static php
|
// curl hook is buggy for static php
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ declare(strict_types=1);
|
|||||||
namespace SPC\builder\extension;
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
use SPC\builder\Extension;
|
use SPC\builder\Extension;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
|
use SPC\util\Util;
|
||||||
|
|
||||||
#[CustomExt('swow')]
|
#[CustomExt('swow')]
|
||||||
class swow extends Extension
|
class swow extends Extension
|
||||||
@@ -17,4 +19,20 @@ class swow extends Extension
|
|||||||
$arg .= $this->builder->getLib('curl') ? ' --enable-swow-curl' : ' --disable-swow-curl';
|
$arg .= $this->builder->getLib('curl') ? ' --enable-swow-curl' : ' --disable-swow-curl';
|
||||||
return $arg;
|
return $arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
public function patchBeforeBuildconf(): bool
|
||||||
|
{
|
||||||
|
if (Util::getPHPVersionID() >= 80000 && !is_link(SOURCE_PATH . '/php-src/ext/swow')) {
|
||||||
|
if (PHP_OS_FAMILY === 'Windows') {
|
||||||
|
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D swow swow-src\ext');
|
||||||
|
} else {
|
||||||
|
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && ln -s swow-src/ext swow');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/SPC/builder/extension/xlswriter.php
Normal file
17
src/SPC/builder/extension/xlswriter.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('xlswriter')]
|
||||||
|
class xlswriter extends Extension
|
||||||
|
{
|
||||||
|
public function getUnixConfigureArg(): string
|
||||||
|
{
|
||||||
|
return '--with-xlswriter --enable-reader';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,94 +12,91 @@ use SPC\exception\RuntimeException;
|
|||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
|
|
||||||
/**
|
|
||||||
* Linux 系统环境下的构建器
|
|
||||||
*/
|
|
||||||
class LinuxBuilder extends BuilderBase
|
class LinuxBuilder extends BuilderBase
|
||||||
{
|
{
|
||||||
/** 编译的 Unix 工具集 */
|
/** Unix compatible builder methods */
|
||||||
use UnixBuilderTrait;
|
use UnixBuilderTrait;
|
||||||
|
|
||||||
/** @var string[] Linux 环境下编译依赖的命令 */
|
/** @var string Using libc [musl,glibc] */
|
||||||
public const REQUIRED_COMMANDS = ['make', 'bison', 'flex', 'pkg-config', 'git', 'autoconf', 'automake', 'tar', 'unzip', /* 'xz', 好像不需要 */ 'gzip', 'bzip2', 'cmake'];
|
|
||||||
|
|
||||||
/** @var string 使用的 libc */
|
|
||||||
public string $libc;
|
public string $libc;
|
||||||
|
|
||||||
/** @var array 特殊架构下的 cflags */
|
/** @var array Tune cflags */
|
||||||
public array $tune_c_flags;
|
public array $tune_c_flags;
|
||||||
|
|
||||||
/** @var string pkg-config 环境变量 */
|
/** @var string pkg-config env, including PKG_CONFIG_PATH, PKG_CONFIG */
|
||||||
public string $pkgconf_env;
|
public string $pkgconf_env;
|
||||||
|
|
||||||
/** @var string 交叉编译变量 */
|
/** @var bool Micro patch phar flag */
|
||||||
public string $cross_compile_prefix = '';
|
|
||||||
|
|
||||||
public string $note_section = "Je pense, donc je suis\0";
|
|
||||||
|
|
||||||
private bool $phar_patched = false;
|
private bool $phar_patched = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function __construct(?string $cc = null, ?string $cxx = null, ?string $arch = null, bool $zts = false)
|
public function __construct(array $options = [])
|
||||||
{
|
{
|
||||||
// 初始化一些默认参数
|
$this->options = $options;
|
||||||
$this->cc = $cc ?? match (SystemUtil::getOSRelease()['dist']) {
|
|
||||||
|
// ---------- set necessary options ----------
|
||||||
|
// set C Compiler (default: alpine: gcc, others: musl-gcc)
|
||||||
|
$this->setOptionIfNotExist('cc', match (SystemUtil::getOSRelease()['dist']) {
|
||||||
'alpine' => 'gcc',
|
'alpine' => 'gcc',
|
||||||
default => 'musl-gcc'
|
default => 'musl-gcc'
|
||||||
};
|
});
|
||||||
$this->cxx = $cxx ?? 'g++';
|
// set C++ Compiler (default: g++)
|
||||||
$this->arch = $arch ?? php_uname('m');
|
$this->setOptionIfNotExist('cxx', 'g++');
|
||||||
$this->gnu_arch = arch2gnu($this->arch);
|
// set arch (default: current)
|
||||||
$this->zts = $zts;
|
$this->setOptionIfNotExist('arch', php_uname('m'));
|
||||||
$this->libc = 'musl'; // SystemUtil::selectLibc($this->cc);
|
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
|
||||||
|
|
||||||
// 根据 CPU 线程数设置编译进程数
|
// ---------- set necessary compile environments ----------
|
||||||
|
// set libc
|
||||||
|
$this->libc = 'musl'; // SystemUtil::selectLibc($this->cc);
|
||||||
|
// concurrency
|
||||||
$this->concurrency = SystemUtil::getCpuCount();
|
$this->concurrency = SystemUtil::getCpuCount();
|
||||||
// 设置 cflags
|
// cflags
|
||||||
$this->arch_c_flags = SystemUtil::getArchCFlags($this->cc, $this->arch);
|
$this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('cc'), $this->getOption('arch'));
|
||||||
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->cxx, $this->arch);
|
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('cxx'), $this->getOption('arch'));
|
||||||
$this->tune_c_flags = SystemUtil::checkCCFlags(SystemUtil::getTuneCFlags($this->arch), $this->cc);
|
$this->tune_c_flags = SystemUtil::checkCCFlags(SystemUtil::getTuneCFlags($this->getOption('arch')), $this->getOption('cc'));
|
||||||
// 设置 cmake
|
// cmake toolchain
|
||||||
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile(
|
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile(
|
||||||
os: 'Linux',
|
'Linux',
|
||||||
target_arch: $this->arch,
|
$this->getOption('arch'),
|
||||||
cflags: $this->arch_c_flags,
|
$this->arch_c_flags,
|
||||||
cc: $this->cc,
|
$this->getOption('cc'),
|
||||||
cxx: $this->cxx
|
$this->getOption('cxx'),
|
||||||
);
|
);
|
||||||
// 设置 pkgconfig
|
// pkg-config
|
||||||
$this->pkgconf_env = 'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig"';
|
$vars = [
|
||||||
// 设置 configure 依赖的环境变量
|
'PKG_CONFIG' => BUILD_ROOT_PATH . '/bin/pkg-config',
|
||||||
$this->configure_env =
|
'PKG_CONFIG_PATH' => BUILD_LIB_PATH . '/pkgconfig',
|
||||||
$this->pkgconf_env . ' ' .
|
];
|
||||||
"CC='{$this->cc}' " .
|
$this->pkgconf_env = SystemUtil::makeEnvVarString($vars);
|
||||||
"CXX='{$this->cxx}' " .
|
// configure environment
|
||||||
(php_uname('m') === $this->arch ? '' : "CFLAGS='{$this->arch_c_flags}'");
|
$this->configure_env = SystemUtil::makeEnvVarString([
|
||||||
// 交叉编译依赖的,TODO
|
...$vars,
|
||||||
if (php_uname('m') !== $this->arch) {
|
'CC' => $this->getOption('cc'),
|
||||||
|
'CXX' => $this->getOption('cxx'),
|
||||||
|
'PATH' => BUILD_ROOT_PATH . '/bin:' . getenv('PATH'),
|
||||||
|
]);
|
||||||
|
// cross-compile does not support yet
|
||||||
|
/*if (php_uname('m') !== $this->arch) {
|
||||||
$this->cross_compile_prefix = SystemUtil::getCrossCompilePrefix($this->cc, $this->arch);
|
$this->cross_compile_prefix = SystemUtil::getCrossCompilePrefix($this->cc, $this->arch);
|
||||||
logger()->info('using cross compile prefix: ' . $this->cross_compile_prefix);
|
logger()->info('using cross compile prefix: ' . $this->cross_compile_prefix);
|
||||||
$this->configure_env .= " CROSS_COMPILE='{$this->cross_compile_prefix}'";
|
$this->configure_env .= " CROSS_COMPILE='{$this->cross_compile_prefix}'";
|
||||||
}
|
}*/
|
||||||
|
|
||||||
$missing = [];
|
// create pkgconfig and include dir (some libs cannot create them automatically)
|
||||||
foreach (self::REQUIRED_COMMANDS as $cmd) {
|
|
||||||
if (SystemUtil::findCommand($cmd) === null) {
|
|
||||||
$missing[] = $cmd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!empty($missing)) {
|
|
||||||
throw new WrongUsageException('missing system commands: ' . implode(', ', $missing));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创立 pkg-config 和放头文件的目录
|
|
||||||
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
||||||
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
|
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
public function makeAutoconfArgs(string $name, array $libSpecs): string
|
public function makeAutoconfArgs(string $name, array $libSpecs): string
|
||||||
{
|
{
|
||||||
$ret = '';
|
$ret = '';
|
||||||
@@ -124,31 +121,22 @@ class LinuxBuilder extends BuilderBase
|
|||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean = false, bool $bloat = false)
|
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||||
{
|
{
|
||||||
if (!$bloat) {
|
// ---------- Update extra-libs ----------
|
||||||
$extra_libs = implode(' ', $this->getAllStaticLibFiles());
|
$extra_libs = $this->getOption('extra-libs', '');
|
||||||
|
// non-bloat linking
|
||||||
|
if (!$this->getOption('bloat', false)) {
|
||||||
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
|
||||||
} else {
|
} else {
|
||||||
logger()->info('bloat linking');
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", array_filter($this->getAllStaticLibFiles())));
|
||||||
$extra_libs = implode(
|
|
||||||
' ',
|
|
||||||
array_map(
|
|
||||||
fn ($x) => "-Xcompiler {$x}",
|
|
||||||
array_filter($this->getAllStaticLibFiles())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ($this->getExt('swoole')) {
|
|
||||||
$extra_libs .= ' -lstdc++';
|
|
||||||
}
|
|
||||||
if ($this->getExt('imagick')) {
|
|
||||||
$extra_libs .= ' /usr/lib/libMagick++-7.Q16HDRI.a /usr/lib/libMagickCore-7.Q16HDRI.a /usr/lib/libMagickWand-7.Q16HDRI.a';
|
|
||||||
}
|
}
|
||||||
|
// add libstdc++, some extensions or libraries need it (C++ cannot be linked statically)
|
||||||
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCppExtension() ? '-lstdc++ ' : '');
|
||||||
|
$this->setOption('extra-libs', $extra_libs);
|
||||||
|
|
||||||
$envs = $this->pkgconf_env . ' ' .
|
|
||||||
"CC='{$this->cc}' " .
|
|
||||||
"CXX='{$this->cxx}' ";
|
|
||||||
$cflags = $this->arch_c_flags;
|
$cflags = $this->arch_c_flags;
|
||||||
$use_lld = '';
|
$use_lld = '';
|
||||||
|
|
||||||
@@ -158,7 +146,7 @@ class LinuxBuilder extends BuilderBase
|
|||||||
$cflags .= ' -static-libgcc -I"' . BUILD_INCLUDE_PATH . '"';
|
$cflags .= ' -static-libgcc -I"' . BUILD_INCLUDE_PATH . '"';
|
||||||
break;
|
break;
|
||||||
case 'musl':
|
case 'musl':
|
||||||
if (str_ends_with($this->cc, 'clang') && SystemUtil::findCommand('lld')) {
|
if (str_ends_with($this->getOption('cc'), 'clang') && SystemUtil::findCommand('lld')) {
|
||||||
$use_lld = '-Xcompiler -fuse-ld=lld';
|
$use_lld = '-Xcompiler -fuse-ld=lld';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -166,18 +154,29 @@ class LinuxBuilder extends BuilderBase
|
|||||||
throw new WrongUsageException('libc ' . $this->libc . ' is not implemented yet');
|
throw new WrongUsageException('libc ' . $this->libc . ' is not implemented yet');
|
||||||
}
|
}
|
||||||
|
|
||||||
$envs = "{$envs} CFLAGS='{$cflags}' LIBS='-ldl -lpthread'";
|
$envs = $this->pkgconf_env . ' ' . SystemUtil::makeEnvVarString([
|
||||||
|
'CC' => $this->getOption('cc'),
|
||||||
|
'CXX' => $this->getOption('cxx'),
|
||||||
|
'CFLAGS' => $cflags,
|
||||||
|
'LIBS' => '-ldl -lpthread',
|
||||||
|
'PATH' => BUILD_ROOT_PATH . '/bin:' . getenv('PATH'),
|
||||||
|
]);
|
||||||
|
|
||||||
SourcePatcher::patchPHPBuildconf($this);
|
SourcePatcher::patchBeforeBuildconf($this);
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||||
|
|
||||||
SourcePatcher::patchPHPConfigure($this);
|
SourcePatcher::patchBeforeConfigure($this);
|
||||||
|
|
||||||
if ($this->getPHPVersionID() < 80000) {
|
$phpVersionID = $this->getPHPVersionID();
|
||||||
$json_74 = '--enable-json ';
|
$json_74 = $phpVersionID < 80000 ? '--enable-json ' : '';
|
||||||
|
|
||||||
|
if ($this->getOption('enable-zts', false)) {
|
||||||
|
$maxExecutionTimers = $phpVersionID >= 80100 ? '--enable-zend-max-execution-timers ' : '';
|
||||||
|
$zts = '--enable-zts --disable-zend-signals ';
|
||||||
} else {
|
} else {
|
||||||
$json_74 = '';
|
$maxExecutionTimers = '';
|
||||||
|
$zts = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
@@ -193,24 +192,17 @@ class LinuxBuilder extends BuilderBase
|
|||||||
'--enable-cli ' .
|
'--enable-cli ' .
|
||||||
'--enable-fpm ' .
|
'--enable-fpm ' .
|
||||||
$json_74 .
|
$json_74 .
|
||||||
|
$zts .
|
||||||
|
$maxExecutionTimers .
|
||||||
'--enable-micro=all-static ' .
|
'--enable-micro=all-static ' .
|
||||||
($this->zts ? '--enable-zts' : '') . ' ' .
|
|
||||||
$this->makeExtensionArgs() . ' ' .
|
$this->makeExtensionArgs() . ' ' .
|
||||||
$envs
|
$envs
|
||||||
);
|
);
|
||||||
|
|
||||||
SourcePatcher::patchPHPAfterConfigure($this);
|
SourcePatcher::patchBeforeMake($this);
|
||||||
|
|
||||||
file_put_contents('/tmp/comment', $this->note_section);
|
|
||||||
|
|
||||||
// 清理
|
|
||||||
$this->cleanMake();
|
$this->cleanMake();
|
||||||
|
|
||||||
if ($bloat) {
|
|
||||||
logger()->info('bloat linking');
|
|
||||||
$extra_libs = "-Wl,--whole-archive {$extra_libs} -Wl,--no-whole-archive";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||||
logger()->info('building cli');
|
logger()->info('building cli');
|
||||||
$this->buildCli($extra_libs, $use_lld);
|
$this->buildCli($extra_libs, $use_lld);
|
||||||
@@ -224,7 +216,7 @@ class LinuxBuilder extends BuilderBase
|
|||||||
$this->buildMicro($extra_libs, $use_lld, $cflags);
|
$this->buildMicro($extra_libs, $use_lld, $cflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (php_uname('m') === $this->arch) {
|
if (php_uname('m') === $this->getOption('arch')) {
|
||||||
$this->sanityCheck($build_target);
|
$this->sanityCheck($build_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,30 +226,34 @@ class LinuxBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Build cli sapi
|
||||||
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildCli(string $extra_libs, string $use_lld): void
|
public function buildCli(string $extra_libs, string $use_lld): void
|
||||||
{
|
{
|
||||||
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
|
'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",
|
||||||
|
]);
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec(
|
->exec("make -j{$this->concurrency} {$vars} cli");
|
||||||
'make -j' . $this->concurrency .
|
|
||||||
' EXTRA_CFLAGS="-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . '" ' .
|
if (!$this->getOption('no-strip', false)) {
|
||||||
"EXTRA_LIBS=\"{$extra_libs}\" " .
|
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')->exec('strip --strip-all php');
|
||||||
"EXTRA_LDFLAGS_PROGRAM='{$use_lld} -all-static' " .
|
}
|
||||||
'cli'
|
|
||||||
);
|
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')
|
|
||||||
->exec("{$this->cross_compile_prefix}objcopy --only-keep-debug php php.debug")
|
|
||||||
->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_TARGET_CLI);
|
$this->deployBinary(BUILD_TARGET_CLI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Build phpmicro sapi
|
||||||
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildMicro(string $extra_libs, string $use_lld, string $cflags): void
|
public function buildMicro(string $extra_libs, string $use_lld, string $cflags): void
|
||||||
{
|
{
|
||||||
@@ -269,43 +265,45 @@ class LinuxBuilder extends BuilderBase
|
|||||||
SourcePatcher::patchMicro(['phar']);
|
SourcePatcher::patchMicro(['phar']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||||
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
|
'EXTRA_CFLAGS' => '-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . $enable_fake_cli,
|
||||||
|
'EXTRA_LIBS' => $extra_libs,
|
||||||
|
'EXTRA_LDFLAGS_PROGRAM' => "{$cflags} {$use_lld} -all-static",
|
||||||
|
]);
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec(
|
->exec("make -j{$this->concurrency} {$vars} micro");
|
||||||
"make -j{$this->concurrency} " .
|
|
||||||
'EXTRA_CFLAGS=' . quote('-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags))) . ' ' .
|
|
||||||
'EXTRA_LIBS=' . quote($extra_libs) . ' ' .
|
|
||||||
'EXTRA_LDFLAGS_PROGRAM=' . quote("{$cflags} {$use_lld}" . ' -all-static', "'") . ' ' .
|
|
||||||
'micro'
|
|
||||||
);
|
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec("{$this->cross_compile_prefix}strip --strip-all micro.sfx");
|
if (!$this->getOption('no-strip', false)) {
|
||||||
|
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec('strip --strip-all micro.sfx');
|
||||||
|
}
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建 fpm
|
* Build fpm sapi
|
||||||
*
|
*
|
||||||
* @throws FileSystemException|RuntimeException
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public function buildFpm(string $extra_libs, string $use_lld): void
|
public function buildFpm(string $extra_libs, string $use_lld): void
|
||||||
{
|
{
|
||||||
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
|
'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",
|
||||||
|
]);
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec(
|
->exec("make -j{$this->concurrency} {$vars} fpm");
|
||||||
'make -j' . $this->concurrency .
|
|
||||||
' EXTRA_CFLAGS="-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . '" ' .
|
if (!$this->getOption('no-strip', false)) {
|
||||||
"EXTRA_LIBS=\"{$extra_libs}\" " .
|
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-all php-fpm');
|
||||||
"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);
|
$this->deployBinary(BUILD_TARGET_FPM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\linux;
|
namespace SPC\builder\linux;
|
||||||
|
|
||||||
use JetBrains\PhpStorm\ArrayShape;
|
|
||||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
@@ -13,7 +12,7 @@ class SystemUtil
|
|||||||
{
|
{
|
||||||
use UnixSystemUtilTrait;
|
use UnixSystemUtilTrait;
|
||||||
|
|
||||||
#[ArrayShape(['dist' => 'mixed|string', 'ver' => 'mixed|string'])]
|
/** @noinspection PhpMissingBreakStatementInspection */
|
||||||
public static function getOSRelease(): array
|
public static function getOSRelease(): array
|
||||||
{
|
{
|
||||||
$ret = [
|
$ret = [
|
||||||
@@ -81,6 +80,8 @@ class SystemUtil
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public static function getArchCFlags(string $cc, string $arch): string
|
public static function getArchCFlags(string $cc, string $arch): string
|
||||||
{
|
{
|
||||||
@@ -129,6 +130,7 @@ class SystemUtil
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @noinspection PhpUnused
|
||||||
*/
|
*/
|
||||||
public static function getCrossCompilePrefix(string $cc, string $arch): string
|
public static function getCrossCompilePrefix(string $cc, string $arch): string
|
||||||
{
|
{
|
||||||
@@ -159,6 +161,7 @@ class SystemUtil
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpUnused */
|
||||||
public static function findStaticLibs(array $names): ?array
|
public static function findStaticLibs(array $names): ?array
|
||||||
{
|
{
|
||||||
$ret = [];
|
$ret = [];
|
||||||
@@ -187,6 +190,7 @@ class SystemUtil
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpUnused */
|
||||||
public static function findHeaders(array $names): ?array
|
public static function findHeaders(array $names): ?array
|
||||||
{
|
{
|
||||||
$ret = [];
|
$ret = [];
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ use SPC\builder\BuilderBase;
|
|||||||
use SPC\builder\LibraryBase;
|
use SPC\builder\LibraryBase;
|
||||||
use SPC\builder\linux\LinuxBuilder;
|
use SPC\builder\linux\LinuxBuilder;
|
||||||
use SPC\builder\traits\UnixLibraryTrait;
|
use SPC\builder\traits\UnixLibraryTrait;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
|
||||||
abstract class LinuxLibraryBase extends LibraryBase
|
abstract class LinuxLibraryBase extends LibraryBase
|
||||||
{
|
{
|
||||||
@@ -37,12 +39,15 @@ abstract class LinuxLibraryBase extends LibraryBase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function tryBuild(bool $force_build = false): int
|
public function tryBuild(bool $force_build = false): int
|
||||||
{
|
{
|
||||||
// 传入 true,表明直接编译
|
// 传入 true,表明直接编译
|
||||||
if ($force_build) {
|
if ($force_build) {
|
||||||
logger()->info('Building required library [' . static::NAME . ']');
|
logger()->info('Building required library [' . static::NAME . ']');
|
||||||
|
$this->patchBeforeBuild();
|
||||||
$this->build();
|
$this->build();
|
||||||
return BUILD_STATUS_OK;
|
return BUILD_STATUS_OK;
|
||||||
}
|
}
|
||||||
@@ -70,7 +75,7 @@ abstract class LinuxLibraryBase extends LibraryBase
|
|||||||
return BUILD_STATUS_ALREADY;
|
return BUILD_STATUS_ALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function makeFakePkgconfs()
|
protected function makeFakePkgconfs(): void
|
||||||
{
|
{
|
||||||
$workspace = BUILD_ROOT_PATH;
|
$workspace = BUILD_ROOT_PATH;
|
||||||
if ($workspace === '/') {
|
if ($workspace === '/') {
|
||||||
|
|||||||
34
src/SPC/builder/linux/library/icu.php
Normal file
34
src/SPC/builder/linux/library/icu.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
|
class icu extends LinuxLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'icu';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
$root = BUILD_ROOT_PATH;
|
||||||
|
$cppflag = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1"';
|
||||||
|
shell()->cd($this->source_dir . '/source')
|
||||||
|
->exec(
|
||||||
|
"{$this->builder->configure_env} {$cppflag} ./runConfigureICU Linux " .
|
||||||
|
'--enable-static ' .
|
||||||
|
'--disable-shared ' .
|
||||||
|
'--with-data-packaging=static ' .
|
||||||
|
'--enable-release=yes ' .
|
||||||
|
'--enable-extras=yes ' .
|
||||||
|
'--enable-icuio=yes ' .
|
||||||
|
'--enable-dyload=no ' .
|
||||||
|
'--enable-tools=yes ' .
|
||||||
|
'--enable-tests=no ' .
|
||||||
|
'--enable-samples=no ' .
|
||||||
|
"--prefix={$root}"
|
||||||
|
)
|
||||||
|
->exec('make clean')
|
||||||
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
|
->exec('make install');
|
||||||
|
}
|
||||||
|
}
|
||||||
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,34 +20,54 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\linux\library;
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
|
use SPC\builder\linux\SystemUtil;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
class libpng extends LinuxLibraryBase
|
class libpng extends LinuxLibraryBase
|
||||||
{
|
{
|
||||||
public const NAME = 'libpng';
|
public const NAME = 'libpng';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function build()
|
public function patchBeforeBuild(): bool
|
||||||
{
|
{
|
||||||
$optimizations = match ($this->builder->arch) {
|
FileSystem::replaceFileStr(
|
||||||
|
SOURCE_PATH . '/libpng/configure',
|
||||||
|
'-lz',
|
||||||
|
BUILD_LIB_PATH . '/libz.a'
|
||||||
|
);
|
||||||
|
if (SystemUtil::getOSRelease()['dist'] === 'alpine') {
|
||||||
|
FileSystem::replaceFileStr(
|
||||||
|
SOURCE_PATH . '/libpng/configure',
|
||||||
|
'-lm',
|
||||||
|
'/usr/lib/libm.a'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public function build(): void
|
||||||
|
{
|
||||||
|
$optimizations = match ($this->builder->getOption('arch')) {
|
||||||
'x86_64' => '--enable-intel-sse ',
|
'x86_64' => '--enable-intel-sse ',
|
||||||
'arm64' => '--enable-arm-neon ',
|
'arm64' => '--enable-arm-neon ',
|
||||||
default => '',
|
default => '',
|
||||||
};
|
};
|
||||||
|
|
||||||
// patch configure
|
|
||||||
SourcePatcher::patchUnixLibpng();
|
|
||||||
|
|
||||||
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->getOption('gnu-arch')}-unknown-linux " .
|
||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
'--enable-hardware-optimizations ' .
|
'--enable-hardware-optimizations ' .
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\linux\library;
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
@@ -13,14 +14,15 @@ class libxml2 extends LinuxLibraryBase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function build()
|
public function build(): void
|
||||||
{
|
{
|
||||||
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
|
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
|
||||||
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
|
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
|
||||||
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
||||||
|
|
||||||
[$lib, $include, $destdir] = SEPARATED_PATH;
|
[, , $destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
FileSystem::resetDir($this->source_dir . '/build');
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
shell()->cd($this->source_dir . '/build')
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
|||||||
@@ -20,11 +20,20 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\linux\library;
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
|
||||||
class nghttp2 extends LinuxLibraryBase
|
class nghttp2 extends LinuxLibraryBase
|
||||||
{
|
{
|
||||||
public const NAME = 'nghttp2';
|
public const NAME = 'nghttp2';
|
||||||
|
|
||||||
public function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public function build(): void
|
||||||
{
|
{
|
||||||
$args = $this->builder->makeAutoconfArgs(static::NAME, [
|
$args = $this->builder->makeAutoconfArgs(static::NAME, [
|
||||||
'zlib' => null,
|
'zlib' => null,
|
||||||
@@ -49,7 +58,7 @@ class nghttp2 extends LinuxLibraryBase
|
|||||||
"{$this->builder->configure_env} ./configure " .
|
"{$this->builder->configure_env} ./configure " .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
"--host={$this->builder->gnu_arch}-unknown-linux " .
|
"--host={$this->builder->getOption('gnu-arch')}-unknown-linux " .
|
||||||
'--enable-lib-only ' .
|
'--enable-lib-only ' .
|
||||||
'--with-boost=no ' .
|
'--with-boost=no ' .
|
||||||
$args . ' ' .
|
$args . ' ' .
|
||||||
|
|||||||
@@ -23,26 +23,28 @@ namespace SPC\builder\linux\library;
|
|||||||
use SPC\builder\linux\SystemUtil;
|
use SPC\builder\linux\SystemUtil;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
|
||||||
class openssl extends LinuxLibraryBase
|
class openssl extends LinuxLibraryBase
|
||||||
{
|
{
|
||||||
public const NAME = 'openssl';
|
public const NAME = 'openssl';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function build()
|
public function build(): void
|
||||||
{
|
{
|
||||||
[$lib,$include,$destdir] = SEPARATED_PATH;
|
[,,$destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
$extra = '';
|
$extra = '';
|
||||||
$ex_lib = '-ldl -pthread';
|
$ex_lib = '-ldl -pthread';
|
||||||
|
|
||||||
$env = $this->builder->pkgconf_env . " CFLAGS='{$this->builder->arch_c_flags}'";
|
$env = $this->builder->pkgconf_env . " CFLAGS='{$this->builder->arch_c_flags}'";
|
||||||
$env .= " CC='{$this->builder->cc} -static -idirafter " . BUILD_INCLUDE_PATH .
|
$env .= " CC='{$this->builder->getOption('cc')} -static -idirafter " . BUILD_INCLUDE_PATH .
|
||||||
' -idirafter /usr/include/ ' .
|
' -idirafter /usr/include/ ' .
|
||||||
' -idirafter /usr/include/' . $this->builder->arch . '-linux-gnu/ ' .
|
' -idirafter /usr/include/' . $this->builder->getOption('arch') . '-linux-gnu/ ' .
|
||||||
"' ";
|
"' ";
|
||||||
// lib:zlib
|
// lib:zlib
|
||||||
$zlib = $this->builder->getLib('zlib');
|
$zlib = $this->builder->getLib('zlib');
|
||||||
@@ -58,7 +60,7 @@ class openssl extends LinuxLibraryBase
|
|||||||
|
|
||||||
$ex_lib = trim($ex_lib);
|
$ex_lib = trim($ex_lib);
|
||||||
|
|
||||||
$clang_postfix = SystemUtil::getCCType($this->builder->cc) === 'clang' ? '-clang' : '';
|
$clang_postfix = SystemUtil::getCCType($this->builder->getOption('cc')) === 'clang' ? '-clang' : '';
|
||||||
|
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec(
|
->exec(
|
||||||
@@ -68,7 +70,7 @@ class openssl extends LinuxLibraryBase
|
|||||||
'-static ' .
|
'-static ' .
|
||||||
"{$zlib_extra}" .
|
"{$zlib_extra}" .
|
||||||
'no-legacy ' .
|
'no-legacy ' .
|
||||||
"linux-{$this->builder->arch}{$clang_postfix}"
|
"linux-{$this->builder->getOption('arch')}{$clang_postfix}"
|
||||||
)
|
)
|
||||||
->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/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';
|
||||||
|
}
|
||||||
@@ -12,57 +12,57 @@ use SPC\exception\RuntimeException;
|
|||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
|
|
||||||
/**
|
|
||||||
* macOS 系统环境下的构建器
|
|
||||||
* 源于 Config,但因为感觉叫 Config 不太合适,就换成了 Builder
|
|
||||||
*/
|
|
||||||
class MacOSBuilder extends BuilderBase
|
class MacOSBuilder extends BuilderBase
|
||||||
{
|
{
|
||||||
/** 编译的 Unix 工具集 */
|
/** Unix compatible builder methods */
|
||||||
use UnixBuilderTrait;
|
use UnixBuilderTrait;
|
||||||
|
|
||||||
/** @var bool 标记是否 patch 了 phar */
|
/** @var bool Micro patch phar flag */
|
||||||
private bool $phar_patched = false;
|
private bool $phar_patched = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param null|string $cc C编译器名称,如果不传入则默认使用clang
|
|
||||||
* @param null|string $cxx C++编译器名称,如果不传入则默认使用clang++
|
|
||||||
* @param null|string $arch 当前架构,如果不传入则默认使用当前系统架构
|
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function __construct(?string $cc = null, ?string $cxx = null, ?string $arch = null, bool $zts = false)
|
public function __construct(array $options = [])
|
||||||
{
|
{
|
||||||
// 如果是 Debug 模式,才使用 set -x 显示每条执行的命令
|
$this->options = $options;
|
||||||
$this->set_x = defined('DEBUG_MODE') ? 'set -x' : 'true';
|
|
||||||
// 初始化一些默认参数
|
|
||||||
$this->cc = $cc ?? 'clang';
|
|
||||||
$this->cxx = $cxx ?? 'clang++';
|
|
||||||
$this->arch = $arch ?? php_uname('m');
|
|
||||||
$this->gnu_arch = arch2gnu($this->arch);
|
|
||||||
$this->zts = $zts;
|
|
||||||
// 根据 CPU 线程数设置编译进程数
|
|
||||||
$this->concurrency = SystemUtil::getCpuCount();
|
|
||||||
// 设置 cflags
|
|
||||||
$this->arch_c_flags = SystemUtil::getArchCFlags($this->arch);
|
|
||||||
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->arch);
|
|
||||||
// 设置 cmake
|
|
||||||
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->arch, $this->arch_c_flags);
|
|
||||||
// 设置 configure 依赖的环境变量
|
|
||||||
$this->configure_env =
|
|
||||||
'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" ' .
|
|
||||||
'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' .
|
|
||||||
"CC='{$this->cc}' " .
|
|
||||||
"CXX='{$this->cxx}' " .
|
|
||||||
"CFLAGS='{$this->arch_c_flags} -Wimplicit-function-declaration'";
|
|
||||||
|
|
||||||
// 创立 pkg-config 和放头文件的目录
|
// ---------- set necessary options ----------
|
||||||
|
// set C Compiler (default: clang)
|
||||||
|
$this->setOptionIfNotExist('cc', 'clang');
|
||||||
|
// set C++ Composer (default: clang++)
|
||||||
|
$this->setOptionIfNotExist('cxx', 'clang++');
|
||||||
|
// set arch (default: current)
|
||||||
|
$this->setOptionIfNotExist('arch', php_uname('m'));
|
||||||
|
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
|
||||||
|
|
||||||
|
// ---------- set necessary compile environments ----------
|
||||||
|
// concurrency
|
||||||
|
$this->concurrency = SystemUtil::getCpuCount();
|
||||||
|
// cflags
|
||||||
|
$this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
|
||||||
|
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
|
||||||
|
// cmake toolchain
|
||||||
|
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch'), $this->arch_c_flags);
|
||||||
|
// configure environment
|
||||||
|
$this->configure_env = SystemUtil::makeEnvVarString([
|
||||||
|
'PKG_CONFIG' => BUILD_ROOT_PATH . '/bin/pkg-config',
|
||||||
|
'PKG_CONFIG_PATH' => BUILD_LIB_PATH . '/pkgconfig/',
|
||||||
|
'CC' => $this->getOption('cc'),
|
||||||
|
'CXX' => $this->getOption('cxx'),
|
||||||
|
'CFLAGS' => "{$this->arch_c_flags} -Wimplicit-function-declaration -Os",
|
||||||
|
'PATH' => BUILD_ROOT_PATH . '/bin:' . getenv('PATH'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// create pkgconfig and include dir (some libs cannot create them automatically)
|
||||||
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
||||||
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
|
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成库构建采用的 autoconf 参数列表
|
* [deprecated] 生成库构建采用的 autoconf 参数列表
|
||||||
*
|
*
|
||||||
* @param string $name 要构建的 lib 库名,传入仅供输出日志
|
* @param string $name 要构建的 lib 库名,传入仅供输出日志
|
||||||
* @param array $lib_specs 依赖的 lib 库的 autoconf 文件
|
* @param array $lib_specs 依赖的 lib 库的 autoconf 文件
|
||||||
@@ -76,7 +76,6 @@ class MacOSBuilder extends BuilderBase
|
|||||||
$arr = $arr ?? [];
|
$arr = $arr ?? [];
|
||||||
|
|
||||||
$disableArgs = $arr[0] ?? null;
|
$disableArgs = $arr[0] ?? null;
|
||||||
$prefix = $arr[1] ?? null;
|
|
||||||
if ($lib instanceof MacOSLibraryBase) {
|
if ($lib instanceof MacOSLibraryBase) {
|
||||||
logger()->info("{$name} \033[32;1mwith\033[0;1m {$libName} support");
|
logger()->info("{$name} \033[32;1mwith\033[0;1m {$libName} support");
|
||||||
$ret .= '--with-' . $libName . '=yes ';
|
$ret .= '--with-' . $libName . '=yes ';
|
||||||
@@ -89,9 +88,11 @@ class MacOSBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回 macOS 系统依赖的框架列表
|
* Get dynamically linked macOS frameworks
|
||||||
*
|
*
|
||||||
* @param bool $asString 是否以字符串形式返回(默认为 False)
|
* @param bool $asString If true, return as string
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function getFrameworks(bool $asString = false): array|string
|
public function getFrameworks(bool $asString = false): array|string
|
||||||
{
|
{
|
||||||
@@ -118,47 +119,43 @@ class MacOSBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* Just start to build statically linked php binary
|
||||||
|
*
|
||||||
|
* @param int $build_target build target
|
||||||
* @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): void
|
||||||
{
|
{
|
||||||
$extra_libs = $this->getFrameworks(true) . ' ' . ($this->getExt('swoole') ? '-lc++ ' : '');
|
// ---------- Update extra-libs ----------
|
||||||
if (!$bloat) {
|
$extra_libs = $this->getOption('extra-libs', '');
|
||||||
$extra_libs .= implode(' ', $this->getAllStaticLibFiles());
|
// add macOS frameworks
|
||||||
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . $this->getFrameworks(true);
|
||||||
|
// add libc++, some extensions or libraries need it (C++ cannot be linked statically)
|
||||||
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCppExtension() ? '-lc++ ' : '');
|
||||||
|
if (!$this->getOption('bloat', false)) {
|
||||||
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
|
||||||
} else {
|
} else {
|
||||||
logger()->info('bloat linking');
|
logger()->info('bloat linking');
|
||||||
$extra_libs .= implode(
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles())));
|
||||||
' ',
|
|
||||||
array_map(
|
|
||||||
fn ($x) => "-Wl,-force_load,{$x}",
|
|
||||||
array_filter($this->getAllStaticLibFiles())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
$this->setOption('extra-libs', $extra_libs);
|
||||||
|
|
||||||
// patch before configure
|
SourcePatcher::patchBeforeBuildconf($this);
|
||||||
SourcePatcher::patchPHPBuildconf($this);
|
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||||
|
|
||||||
SourcePatcher::patchPHPConfigure($this);
|
SourcePatcher::patchBeforeConfigure($this);
|
||||||
|
|
||||||
if ($this->getLib('libxml2') || $this->getExt('iconv')) {
|
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
||||||
$extra_libs .= ' -liconv';
|
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getPHPVersionID() < 80000) {
|
|
||||||
$json_74 = '--enable-json ';
|
|
||||||
} else {
|
|
||||||
$json_74 = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec(
|
->exec(
|
||||||
'./configure ' .
|
'./configure ' .
|
||||||
'--prefix= ' .
|
'--prefix= ' .
|
||||||
'--with-valgrind=no ' . // 不检测内存泄漏
|
'--with-valgrind=no ' . // Not detect memory leak
|
||||||
'--enable-shared=no ' .
|
'--enable-shared=no ' .
|
||||||
'--enable-static=yes ' .
|
'--enable-static=yes ' .
|
||||||
"CFLAGS='{$this->arch_c_flags} -Werror=unknown-warning-option' " .
|
"CFLAGS='{$this->arch_c_flags} -Werror=unknown-warning-option' " .
|
||||||
@@ -167,31 +164,31 @@ class MacOSBuilder extends BuilderBase
|
|||||||
'--disable-phpdbg ' .
|
'--disable-phpdbg ' .
|
||||||
'--enable-cli ' .
|
'--enable-cli ' .
|
||||||
'--enable-fpm ' .
|
'--enable-fpm ' .
|
||||||
$json_74 .
|
|
||||||
'--enable-micro ' .
|
'--enable-micro ' .
|
||||||
($this->zts ? '--enable-zts' : '') . ' ' .
|
$json_74 .
|
||||||
|
$zts .
|
||||||
$this->makeExtensionArgs() . ' ' .
|
$this->makeExtensionArgs() . ' ' .
|
||||||
$this->configure_env
|
$this->configure_env
|
||||||
);
|
);
|
||||||
|
|
||||||
SourcePatcher::patchPHPAfterConfigure($this);
|
SourcePatcher::patchBeforeMake($this);
|
||||||
|
|
||||||
$this->cleanMake();
|
$this->cleanMake();
|
||||||
|
|
||||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||||
logger()->info('building cli');
|
logger()->info('building cli');
|
||||||
$this->buildCli($extra_libs);
|
$this->buildCli();
|
||||||
}
|
}
|
||||||
if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
||||||
logger()->info('building fpm');
|
logger()->info('building fpm');
|
||||||
$this->buildFpm($extra_libs);
|
$this->buildFpm();
|
||||||
}
|
}
|
||||||
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||||
logger()->info('building micro');
|
logger()->info('building micro');
|
||||||
$this->buildMicro($extra_libs);
|
$this->buildMicro();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (php_uname('m') === $this->arch) {
|
if (php_uname('m') === $this->getOption('arch')) {
|
||||||
$this->sanityCheck($build_target);
|
$this->sanityCheck($build_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,27 +198,32 @@ class MacOSBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建 cli
|
* Build cli sapi
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildCli(string $extra_libs): void
|
public function buildCli(): void
|
||||||
{
|
{
|
||||||
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
|
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||||
|
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv", // link resolv library (macOS need it)
|
||||||
|
]);
|
||||||
|
|
||||||
$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} {$vars} cli");
|
||||||
if ($this->strip) {
|
if (!$this->getOption('no-strip', false)) {
|
||||||
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
|
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
|
||||||
}
|
}
|
||||||
$this->deployBinary(BUILD_TARGET_CLI);
|
$this->deployBinary(BUILD_TARGET_CLI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建 phpmicro
|
* Build phpmicro sapi
|
||||||
*
|
*
|
||||||
* @throws FileSystemException|RuntimeException
|
* @throws FileSystemException|RuntimeException
|
||||||
*/
|
*/
|
||||||
public function buildMicro(string $extra_libs): void
|
public function buildMicro(): void
|
||||||
{
|
{
|
||||||
if ($this->getPHPVersionID() < 80000) {
|
if ($this->getPHPVersionID() < 80000) {
|
||||||
throw new RuntimeException('phpmicro only support PHP >= 8.0!');
|
throw new RuntimeException('phpmicro only support PHP >= 8.0!');
|
||||||
@@ -231,22 +233,39 @@ class MacOSBuilder extends BuilderBase
|
|||||||
SourcePatcher::patchMicro(['phar']);
|
SourcePatcher::patchMicro(['phar']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||||
|
$vars = [
|
||||||
|
// with debug information, optimize for size, remove identifiers, patch fake cli for micro
|
||||||
|
'EXTRA_CFLAGS' => '-g -Os -fno-ident' . $enable_fake_cli,
|
||||||
|
// link resolv library (macOS need it)
|
||||||
|
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv",
|
||||||
|
];
|
||||||
|
if (!$this->getOption('no-strip', false)) {
|
||||||
|
$vars['STRIP'] = 'dsymutil -f ';
|
||||||
|
}
|
||||||
|
$vars = SystemUtil::makeEnvVarString($vars);
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" " . ($this->strip ? 'STRIP="dsymutil -f " ' : '') . 'micro');
|
->exec("make -j{$this->concurrency} {$vars} micro");
|
||||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建 fpm
|
* Build fpm sapi
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildFpm(string $extra_libs): void
|
public function buildFpm(): void
|
||||||
{
|
{
|
||||||
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
|
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||||
|
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv", // link resolv library (macOS need it)
|
||||||
|
]);
|
||||||
|
|
||||||
$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\" fpm");
|
$shell->exec("make -j{$this->concurrency} {$vars} fpm");
|
||||||
if ($this->strip) {
|
if (!$this->getOption('no-strip', false)) {
|
||||||
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm');
|
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm');
|
||||||
}
|
}
|
||||||
$this->deployBinary(BUILD_TARGET_FPM);
|
$this->deployBinary(BUILD_TARGET_FPM);
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ use SPC\exception\WrongUsageException;
|
|||||||
|
|
||||||
class SystemUtil
|
class SystemUtil
|
||||||
{
|
{
|
||||||
/** macOS 兼容 unix 的系统工具 */
|
/** Unix System Util Compatible */
|
||||||
use UnixSystemUtilTrait;
|
use UnixSystemUtilTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统 CPU 逻辑内核数
|
* Get Logic CPU Count for macOS
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
@@ -29,9 +29,10 @@ class SystemUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取不同架构对应的 cflags 参数
|
* Get Target Arch CFlags
|
||||||
*
|
*
|
||||||
* @param string $arch 架构名称
|
* @param string $arch Arch Name
|
||||||
|
* @return string return Arch CFlags string
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public static function getArchCFlags(string $arch): string
|
public static function getArchCFlags(string $arch): string
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ use SPC\builder\BuilderBase;
|
|||||||
use SPC\builder\LibraryBase;
|
use SPC\builder\LibraryBase;
|
||||||
use SPC\builder\macos\MacOSBuilder;
|
use SPC\builder\macos\MacOSBuilder;
|
||||||
use SPC\builder\traits\UnixLibraryTrait;
|
use SPC\builder\traits\UnixLibraryTrait;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
|
|
||||||
abstract class MacOSLibraryBase extends LibraryBase
|
abstract class MacOSLibraryBase extends LibraryBase
|
||||||
@@ -27,7 +29,8 @@ abstract class MacOSLibraryBase extends LibraryBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 lib 库依赖的 macOS framework
|
* @throws WrongUsageException
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function getFrameworks(): array
|
public function getFrameworks(): array
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,19 +20,30 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\macos\library;
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
class curl extends MacOSLibraryBase
|
class curl extends MacOSLibraryBase
|
||||||
{
|
{
|
||||||
use \SPC\builder\unix\library\curl {
|
use \SPC\builder\unix\library\curl;
|
||||||
build as unixBuild;
|
|
||||||
}
|
|
||||||
|
|
||||||
public const NAME = 'curl';
|
public const NAME = 'curl';
|
||||||
|
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function patchBeforeBuild(): bool
|
||||||
{
|
{
|
||||||
SourcePatcher::patchCurlMacOS();
|
FileSystem::replaceFileRegex(
|
||||||
$this->unixBuild();
|
SOURCE_PATH . '/curl/CMakeLists.txt',
|
||||||
|
'/NOT COREFOUNDATION_FRAMEWORK/m',
|
||||||
|
'FALSE'
|
||||||
|
);
|
||||||
|
FileSystem::replaceFileRegex(
|
||||||
|
SOURCE_PATH . '/curl/CMakeLists.txt',
|
||||||
|
'/NOT SYSTEMCONFIGURATION_FRAMEWORK/m',
|
||||||
|
'FALSE'
|
||||||
|
);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/SPC/builder/macos/library/glfw.php
Normal file
28
src/SPC/builder/macos/library/glfw.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
|
class glfw extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'glfw';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
// compile!
|
||||||
|
shell()->cd(SOURCE_PATH . '/ext-glfw/vendor/glfw')
|
||||||
|
->exec("{$this->builder->configure_env} cmake . {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF")
|
||||||
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
|
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
||||||
|
// patch pkgconf
|
||||||
|
$this->patchPkgconfPrefix(['glfw3.pc']);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/SPC/builder/macos/library/icu.php
Normal file
20
src/SPC/builder/macos/library/icu.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
class icu extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'icu';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
$root = BUILD_ROOT_PATH;
|
||||||
|
shell()->cd($this->source_dir . '/source')
|
||||||
|
->exec("{$this->builder->configure_env} ./runConfigureICU MacOSX --enable-static --disable-shared --prefix={$root}")
|
||||||
|
->exec('make clean')
|
||||||
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
|
->exec('make install');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +1,30 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
|
|
||||||
*
|
|
||||||
* lwmbs is licensed under Mulan PSL v2. You can use this
|
|
||||||
* software according to the terms and conditions of the
|
|
||||||
* Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
*
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace SPC\builder\macos\library;
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
class libffi extends MacOSLibraryBase
|
class libffi extends MacOSLibraryBase
|
||||||
{
|
{
|
||||||
public const NAME = 'libffi';
|
public const NAME = 'libffi';
|
||||||
|
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
[$lib, , $destdir] = SEPARATED_PATH;
|
[, , $destdir] = SEPARATED_PATH;
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec(
|
->exec(
|
||||||
"{$this->builder->configure_env} ./configure " .
|
"{$this->builder->configure_env} ./configure " .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
"--host={$this->builder->arch}-apple-darwin " .
|
"--host={$this->builder->getOption('arch')}-apple-darwin " .
|
||||||
"--target={$this->builder->arch}-apple-darwin " .
|
"--target={$this->builder->getOption('arch')}-apple-darwin " .
|
||||||
'--prefix= ' // use prefix=/
|
'--prefix= ' // use prefix=/
|
||||||
)
|
)
|
||||||
->exec('make clean')
|
->exec('make clean')
|
||||||
|
|||||||
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(): void
|
||||||
|
{
|
||||||
|
$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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ namespace SPC\builder\macos\library;
|
|||||||
|
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
|
||||||
class libpng extends MacOSLibraryBase
|
class libpng extends MacOSLibraryBase
|
||||||
{
|
{
|
||||||
@@ -30,19 +31,21 @@ class libpng extends MacOSLibraryBase
|
|||||||
/**
|
/**
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$optimizations = match ($this->builder->arch) {
|
$optimizations = match ($this->builder->getOption('arch')) {
|
||||||
'x86_64' => '--enable-intel-sse ',
|
'x86_64' => '--enable-intel-sse ',
|
||||||
'arm64' => '--enable-arm-neon ',
|
'arm64' => '--enable-arm-neon ',
|
||||||
default => '',
|
default => '',
|
||||||
};
|
};
|
||||||
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->getOption('gnu-arch')}-apple-darwin " .
|
||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
'--enable-hardware-optimizations ' .
|
'--enable-hardware-optimizations ' .
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\macos\library;
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
@@ -13,14 +14,22 @@ class libxml2 extends MacOSLibraryBase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
|
// macOS need to link iconv dynamically, we add it to extra-libs
|
||||||
|
$extra_libs = $this->builder->getOption('extra-libs', '');
|
||||||
|
if (!str_contains($extra_libs, '-liconv')) {
|
||||||
|
$extra_libs .= ' -liconv';
|
||||||
|
}
|
||||||
|
$this->builder->setOption('extra-libs', $extra_libs);
|
||||||
|
|
||||||
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
|
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
|
||||||
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
|
// $enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
|
||||||
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
||||||
|
|
||||||
[$lib, $include, $destdir] = SEPARATED_PATH;
|
[, , $destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
FileSystem::resetDir($this->source_dir . '/build');
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
shell()->cd($this->source_dir . '/build')
|
shell()->cd($this->source_dir . '/build')
|
||||||
@@ -31,18 +40,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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,18 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\macos\library;
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
class nghttp2 extends MacOSLibraryBase
|
class nghttp2 extends MacOSLibraryBase
|
||||||
{
|
{
|
||||||
public const NAME = 'nghttp2';
|
public const NAME = 'nghttp2';
|
||||||
|
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$args = $this->builder->makeAutoconfArgs(static::NAME, [
|
$args = $this->builder->makeAutoconfArgs(static::NAME, [
|
||||||
'zlib' => null,
|
'zlib' => null,
|
||||||
@@ -49,7 +56,7 @@ class nghttp2 extends MacOSLibraryBase
|
|||||||
"{$this->builder->configure_env} " . ' ./configure ' .
|
"{$this->builder->configure_env} " . ' ./configure ' .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
"--host={$this->builder->gnu_arch}-apple-darwin " .
|
"--host={$this->builder->getOption('gnu-arch')}-apple-darwin " .
|
||||||
'--enable-lib-only ' .
|
'--enable-lib-only ' .
|
||||||
'--with-boost=no ' .
|
'--with-boost=no ' .
|
||||||
$args . ' ' .
|
$args . ' ' .
|
||||||
|
|||||||
@@ -20,11 +20,20 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\macos\library;
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
|
||||||
class openssl extends MacOSLibraryBase
|
class openssl extends MacOSLibraryBase
|
||||||
{
|
{
|
||||||
public const NAME = 'openssl';
|
public const NAME = 'openssl';
|
||||||
|
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
[$lib,,$destdir] = SEPARATED_PATH;
|
[$lib,,$destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
@@ -42,7 +51,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->getOption('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';
|
||||||
|
}
|
||||||
@@ -7,31 +7,27 @@ namespace SPC\builder\traits;
|
|||||||
use SPC\builder\linux\LinuxBuilder;
|
use SPC\builder\linux\LinuxBuilder;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait UnixBuilderTrait
|
trait UnixBuilderTrait
|
||||||
{
|
{
|
||||||
/** @var string 设置的命令前缀,设置为 set -x 可以在终端打印命令 */
|
/** @var string cflags */
|
||||||
public string $set_x = 'set -x';
|
|
||||||
|
|
||||||
/** @var string C 编译器命令 */
|
|
||||||
public string $cc;
|
|
||||||
|
|
||||||
/** @var string C++ 编译器命令 */
|
|
||||||
public string $cxx;
|
|
||||||
|
|
||||||
/** @var string cflags 参数 */
|
|
||||||
public string $arch_c_flags;
|
public string $arch_c_flags;
|
||||||
|
|
||||||
/** @var string C++ flags 参数 */
|
/** @var string C++ flags */
|
||||||
public string $arch_cxx_flags;
|
public string $arch_cxx_flags;
|
||||||
|
|
||||||
/** @var string cmake toolchain file */
|
/** @var string cmake toolchain file */
|
||||||
public string $cmake_toolchain_file;
|
public string $cmake_toolchain_file;
|
||||||
|
|
||||||
/** @var string configure 环境依赖的变量 */
|
/** @var string configure environments */
|
||||||
public string $configure_env;
|
public string $configure_env;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws WrongUsageException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
public function getAllStaticLibFiles(): array
|
public function getAllStaticLibFiles(): array
|
||||||
{
|
{
|
||||||
$libs = [];
|
$libs = [];
|
||||||
@@ -125,7 +121,7 @@ trait UnixBuilderTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清理编译好的文件
|
* Run php clean
|
||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
@@ -141,7 +137,7 @@ trait UnixBuilderTrait
|
|||||||
public function makeCmakeArgs(): string
|
public function makeCmakeArgs(): string
|
||||||
{
|
{
|
||||||
[$lib, $include] = SEPARATED_PATH;
|
[$lib, $include] = SEPARATED_PATH;
|
||||||
$extra = $this instanceof LinuxBuilder ? '-DCMAKE_C_COMPILER=' . $this->cc . ' ' : '';
|
$extra = $this instanceof LinuxBuilder ? '-DCMAKE_C_COMPILER=' . $this->getOption('cc') . ' ' : '';
|
||||||
return $extra . '-DCMAKE_BUILD_TYPE=Release ' .
|
return $extra . '-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
'-DCMAKE_INSTALL_PREFIX=/ ' .
|
'-DCMAKE_INSTALL_PREFIX=/ ' .
|
||||||
"-DCMAKE_INSTALL_LIBDIR={$lib} " .
|
"-DCMAKE_INSTALL_LIBDIR={$lib} " .
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace SPC\builder\traits;
|
|||||||
use SPC\builder\LibraryBase;
|
use SPC\builder\LibraryBase;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait UnixLibraryTrait
|
trait UnixLibraryTrait
|
||||||
@@ -16,6 +17,7 @@ trait UnixLibraryTrait
|
|||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string
|
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string
|
||||||
{
|
{
|
||||||
@@ -43,6 +45,11 @@ trait UnixLibraryTrait
|
|||||||
return implode($sep, $ret);
|
return implode($sep, $ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
public function makeAutoconfEnv(string $prefix = null): string
|
public function makeAutoconfEnv(string $prefix = null): string
|
||||||
{
|
{
|
||||||
if ($prefix === null) {
|
if ($prefix === null) {
|
||||||
@@ -82,7 +89,7 @@ trait UnixLibraryTrait
|
|||||||
* remove libtool archive files
|
* remove libtool archive files
|
||||||
*
|
*
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function cleanLaFiles(): void
|
public function cleanLaFiles(): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\traits;
|
namespace SPC\builder\traits;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,11 +15,12 @@ trait UnixSystemUtilTrait
|
|||||||
/**
|
/**
|
||||||
* 生成 toolchain.cmake,用于 cmake 构建
|
* 生成 toolchain.cmake,用于 cmake 构建
|
||||||
*
|
*
|
||||||
* @param string $os 操作系统代号
|
* @param string $os 操作系统代号
|
||||||
* @param string $target_arch 目标架构
|
* @param string $target_arch 目标架构
|
||||||
* @param string $cflags CFLAGS 参数
|
* @param string $cflags CFLAGS 参数
|
||||||
* @param null|string $cc CC 参数(默认空)
|
* @param null|string $cc CC 参数(默认空)
|
||||||
* @param null|string $cxx CXX 参数(默认空)
|
* @param null|string $cxx CXX 参数(默认空)
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public static function makeCmakeToolchainFile(
|
public static function makeCmakeToolchainFile(
|
||||||
string $os,
|
string $os,
|
||||||
@@ -76,4 +78,20 @@ CMAKE;
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $vars Variables, like: ["CFLAGS" => "-Ixxx"]
|
||||||
|
* @return string like: CFLAGS="-Ixxx"
|
||||||
|
*/
|
||||||
|
public static function makeEnvVarString(array $vars): string
|
||||||
|
{
|
||||||
|
$str = '';
|
||||||
|
foreach ($vars as $key => $value) {
|
||||||
|
if ($str !== '') {
|
||||||
|
$str .= ' ';
|
||||||
|
}
|
||||||
|
$str .= $key . '=' . escapeshellarg($value);
|
||||||
|
}
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait brotli
|
trait brotli
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
protected function build(): void
|
protected function build(): void
|
||||||
{
|
{
|
||||||
FileSystem::resetDir($this->source_dir . '/build-dir');
|
FileSystem::resetDir($this->source_dir . '/build-dir');
|
||||||
|
|||||||
@@ -4,11 +4,17 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait curl
|
trait curl
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$extra = '';
|
$extra = '';
|
||||||
// lib:openssl
|
// lib:openssl
|
||||||
|
|||||||
@@ -4,11 +4,19 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait freetype
|
trait freetype
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$suggested = $this->builder->getLib('libpng') ? '--with-png' : '--without-png';
|
$suggested = $this->builder->getLib('libpng') ? '--with-png' : '--without-png';
|
||||||
$suggested .= ' ';
|
$suggested .= ' ';
|
||||||
@@ -27,9 +35,8 @@ trait freetype
|
|||||||
->exec("make -j{$this->builder->concurrency}")
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
||||||
$this->patchPkgconfPrefix(['freetype2.pc']);
|
$this->patchPkgconfPrefix(['freetype2.pc']);
|
||||||
FileSystem::replaceFile(
|
FileSystem::replaceFileStr(
|
||||||
BUILD_ROOT_PATH . '/lib/pkgconfig/freetype2.pc',
|
BUILD_ROOT_PATH . '/lib/pkgconfig/freetype2.pc',
|
||||||
REPLACE_FILE_STR,
|
|
||||||
' -L/lib ',
|
' -L/lib ',
|
||||||
' -L' . BUILD_ROOT_PATH . '/lib '
|
' -L' . BUILD_ROOT_PATH . '/lib '
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,9 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
trait gmp
|
trait gmp
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec(
|
->exec(
|
||||||
|
|||||||
@@ -4,10 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait imagemagick
|
trait imagemagick
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
protected function build(): void
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$extra = '--without-jxl --without-xml --without-zstd --without-x --disable-openmp ';
|
$extra = '--without-jxl --without-xml --without-zstd --without-x --disable-openmp ';
|
||||||
@@ -46,9 +52,8 @@ trait imagemagick
|
|||||||
];
|
];
|
||||||
$this->patchPkgconfPrefix($filelist);
|
$this->patchPkgconfPrefix($filelist);
|
||||||
foreach ($filelist as $file) {
|
foreach ($filelist as $file) {
|
||||||
FileSystem::replaceFile(
|
FileSystem::replaceFileRegex(
|
||||||
BUILD_LIB_PATH . '/pkgconfig/' . $file,
|
BUILD_LIB_PATH . '/pkgconfig/' . $file,
|
||||||
REPLACE_FILE_PREG,
|
|
||||||
'#includearchdir=/include/ImageMagick-7#m',
|
'#includearchdir=/include/ImageMagick-7#m',
|
||||||
'includearchdir=${prefix}/include/ImageMagick-7'
|
'includearchdir=${prefix}/include/ImageMagick-7'
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,11 +4,19 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait libavif
|
trait libavif
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
// CMake needs a clean build directory
|
// CMake needs a clean build directory
|
||||||
FileSystem::resetDir($this->source_dir . '/build');
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
|
|||||||
@@ -4,11 +4,17 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait libevent
|
trait libevent
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
// CMake needs a clean build directory
|
// CMake needs a clean build directory
|
||||||
FileSystem::resetDir($this->source_dir . '/build');
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
@@ -22,12 +28,12 @@ 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 ' .
|
||||||
'..'
|
'..'
|
||||||
)
|
)
|
||||||
->exec("cmake --build . -j {$this->builder->concurrency}")
|
->exec("cmake --build . -j {$this->builder->concurrency}")
|
||||||
->exec('make install');
|
->exec('make install');
|
||||||
// patch pkgconfig
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace SPC\builder\unix\library;
|
|||||||
|
|
||||||
trait libiconv
|
trait libiconv
|
||||||
{
|
{
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
[,,$destdir] = SEPARATED_PATH;
|
[,,$destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,19 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait libjpeg
|
trait libjpeg
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
// CMake needs a clean build directory
|
// CMake needs a clean build directory
|
||||||
FileSystem::resetDir($this->source_dir . '/build');
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace SPC\builder\unix\library;
|
|||||||
|
|
||||||
trait libsodium
|
trait libsodium
|
||||||
{
|
{
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$root = BUILD_ROOT_PATH;
|
$root = BUILD_ROOT_PATH;
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
|
|||||||
@@ -4,11 +4,17 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait libssh2
|
trait libssh2
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$enable_zlib = $this->builder->getLib('zlib') !== null ? 'ON' : 'OFF';
|
$enable_zlib = $this->builder->getLib('zlib') !== null ? 'ON' : 'OFF';
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,18 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
|
||||||
trait libwebp
|
trait libwebp
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
[,,$destdir] = SEPARATED_PATH;
|
[,,$destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
@@ -11,8 +12,9 @@ trait libyaml
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
// prepare cmake/config.h.in
|
// prepare cmake/config.h.in
|
||||||
if (!is_file(SOURCE_PATH . '/libyaml/cmake/config.h.in')) {
|
if (!is_file(SOURCE_PATH . '/libyaml/cmake/config.h.in')) {
|
||||||
|
|||||||
@@ -4,11 +4,17 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait libzip
|
trait libzip
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$extra = '';
|
$extra = '';
|
||||||
// lib:bzip2
|
// lib:bzip2
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace SPC\builder\unix\library;
|
|||||||
|
|
||||||
trait ncurses
|
trait ncurses
|
||||||
{
|
{
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec(
|
->exec(
|
||||||
|
|||||||
@@ -4,9 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
trait onig
|
trait onig
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
[,,$destdir] = SEPARATED_PATH;
|
[,,$destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
|
|||||||
@@ -6,20 +6,16 @@ namespace SPC\builder\unix\library;
|
|||||||
|
|
||||||
trait pkgconfig
|
trait pkgconfig
|
||||||
{
|
{
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$macos_env = 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' .
|
$macos_env = 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' .
|
||||||
"CC='{$this->builder->cc}' " .
|
"CC='{$this->builder->getOption('cc')}' " .
|
||||||
"CXX='{$this->builder->cxx}' " .
|
"CXX='{$this->builder->getOption('cxx')}' " .
|
||||||
"CFLAGS='{$this->builder->arch_c_flags} -Wimplicit-function-declaration' ";
|
"CFLAGS='{$this->builder->arch_c_flags} -Wimplicit-function-declaration' ";
|
||||||
$linux_env = 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig" ' .
|
$linux_env = 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig" ' .
|
||||||
"CC='{$this->builder->cc}' " .
|
"CC='{$this->builder->getOption('cc')}' " .
|
||||||
"CXX='{$this->builder->cxx}' ";
|
"CXX='{$this->builder->getOption('cxx')}' ";
|
||||||
|
|
||||||
$extra = match (PHP_OS_FAMILY) {
|
|
||||||
'Darwin' => '',
|
|
||||||
default => '--with-internal-glib ',
|
|
||||||
};
|
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec(
|
->exec(
|
||||||
match (PHP_OS_FAMILY) {
|
match (PHP_OS_FAMILY) {
|
||||||
@@ -29,7 +25,7 @@ trait pkgconfig
|
|||||||
'./configure ' .
|
'./configure ' .
|
||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
$extra .
|
'--with-internal-glib ' .
|
||||||
'--prefix=' . BUILD_ROOT_PATH . ' ' .
|
'--prefix=' . BUILD_ROOT_PATH . ' ' .
|
||||||
'--without-sysroot ' .
|
'--without-sysroot ' .
|
||||||
'--without-system-include-path ' .
|
'--without-system-include-path ' .
|
||||||
|
|||||||
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(): void
|
||||||
|
{
|
||||||
|
$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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,9 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
trait readline
|
trait readline
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec(
|
->exec(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace SPC\builder\unix\library;
|
|||||||
|
|
||||||
trait sqlite
|
trait sqlite
|
||||||
{
|
{
|
||||||
protected function build()
|
protected function build(): void
|
||||||
{
|
{
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec("{$this->builder->configure_env} ./configure --enable-static --disable-shared --prefix=")
|
->exec("{$this->builder->configure_env} ./configure --enable-static --disable-shared --prefix=")
|
||||||
|
|||||||
@@ -4,16 +4,23 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
trait xz
|
trait xz
|
||||||
{
|
{
|
||||||
public function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function build(): void
|
||||||
{
|
{
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
->exec(
|
->exec(
|
||||||
"{$this->builder->configure_env} ./configure " .
|
"{$this->builder->configure_env} ./configure " .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
"--host={$this->builder->gnu_arch}-unknown-linux " .
|
"--host={$this->builder->getOption('gnu-arch')}-unknown-linux " .
|
||||||
'--disable-scripts ' .
|
'--disable-scripts ' .
|
||||||
'--disable-doc ' .
|
'--disable-doc ' .
|
||||||
'--with-libiconv ' .
|
'--with-libiconv ' .
|
||||||
|
|||||||
@@ -4,9 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
trait zlib
|
trait zlib
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
[,,$destdir] = SEPARATED_PATH;
|
[,,$destdir] = SEPARATED_PATH;
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,17 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
trait zstd
|
trait zstd
|
||||||
{
|
{
|
||||||
protected function build()
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
{
|
{
|
||||||
FileSystem::resetDir($this->source_dir . '/build/cmake/build');
|
FileSystem::resetDir($this->source_dir . '/build/cmake/build');
|
||||||
shell()->cd($this->source_dir . '/build/cmake/build')
|
shell()->cd($this->source_dir . '/build/cmake/build')
|
||||||
|
|||||||
@@ -17,16 +17,8 @@ abstract class BaseCommand extends Command
|
|||||||
{
|
{
|
||||||
protected bool $no_motd = false;
|
protected bool $no_motd = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* 输入
|
|
||||||
*/
|
|
||||||
protected InputInterface $input;
|
protected InputInterface $input;
|
||||||
|
|
||||||
/**
|
|
||||||
* 输出
|
|
||||||
*
|
|
||||||
* 一般来说同样会是 ConsoleOutputInterface
|
|
||||||
*/
|
|
||||||
protected OutputInterface $output;
|
protected OutputInterface $output;
|
||||||
|
|
||||||
public function __construct(string $name = null)
|
public function __construct(string $name = null)
|
||||||
@@ -36,12 +28,12 @@ abstract class BaseCommand extends Command
|
|||||||
$this->addOption('no-motd', null, null, 'Disable motd');
|
$this->addOption('no-motd', null, null, 'Disable motd');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initialize(InputInterface $input, OutputInterface $output)
|
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
{
|
{
|
||||||
if ($input->getOption('no-motd')) {
|
if ($input->getOption('no-motd')) {
|
||||||
$this->no_motd = true;
|
$this->no_motd = true;
|
||||||
}
|
}
|
||||||
// 注册全局错误处理器
|
|
||||||
set_error_handler(static function ($error_no, $error_msg, $error_file, $error_line) {
|
set_error_handler(static function ($error_no, $error_msg, $error_file, $error_line) {
|
||||||
$tips = [
|
$tips = [
|
||||||
E_WARNING => ['PHP Warning: ', 'warning'],
|
E_WARNING => ['PHP Warning: ', 'warning'],
|
||||||
@@ -77,6 +69,9 @@ abstract class BaseCommand extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
abstract public function handle(): int;
|
abstract public function handle(): int;
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
@@ -91,9 +86,8 @@ abstract class BaseCommand extends Command
|
|||||||
foreach ($msg as $v) {
|
foreach ($msg as $v) {
|
||||||
logger()->error($v);
|
logger()->error($v);
|
||||||
}
|
}
|
||||||
return self::FAILURE;
|
return static::FAILURE;
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
// 不开 debug 模式就不要再显示复杂的调试栈信息了
|
|
||||||
if ($this->getOption('debug')) {
|
if ($this->getOption('debug')) {
|
||||||
ExceptionHandler::getInstance()->handle($e);
|
ExceptionHandler::getInstance()->handle($e);
|
||||||
} else {
|
} else {
|
||||||
@@ -102,10 +96,10 @@ abstract class BaseCommand extends Command
|
|||||||
logger()->error($v);
|
logger()->error($v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self::FAILURE;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self::SUCCESS;
|
return static::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getOption(string $name): mixed
|
protected function getOption(string $name): mixed
|
||||||
@@ -118,11 +112,6 @@ abstract class BaseCommand extends Command
|
|||||||
return $this->input->getArgument($name);
|
return $this->input->getArgument($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否应该执行
|
|
||||||
*
|
|
||||||
* @return bool 返回 true 以继续执行,返回 false 以中断执行
|
|
||||||
*/
|
|
||||||
protected function shouldExecute(): bool
|
protected function shouldExecute(): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace SPC\command;
|
|||||||
use SPC\builder\BuilderProvider;
|
use SPC\builder\BuilderProvider;
|
||||||
use SPC\exception\ExceptionHandler;
|
use SPC\exception\ExceptionHandler;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\SourcePatcher;
|
||||||
use SPC\util\DependencyUtil;
|
use SPC\util\DependencyUtil;
|
||||||
use SPC\util\LicenseDumper;
|
use SPC\util\LicenseDumper;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
@@ -17,7 +18,7 @@ use ZM\Logger\ConsoleColor;
|
|||||||
#[AsCommand('build', 'build CLI binary')]
|
#[AsCommand('build', 'build CLI binary')]
|
||||||
class BuildCliCommand extends BuildCommand
|
class BuildCliCommand extends BuildCommand
|
||||||
{
|
{
|
||||||
public function configure()
|
public function configure(): void
|
||||||
{
|
{
|
||||||
$this->addArgument('extensions', InputArgument::REQUIRED, 'The extensions will be compiled, comma separated');
|
$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('with-libs', null, InputOption::VALUE_REQUIRED, 'add additional libraries, comma separated', '');
|
||||||
@@ -27,17 +28,17 @@ class BuildCliCommand extends BuildCommand
|
|||||||
$this->addOption('build-all', null, null, 'build cli, micro, fpm');
|
$this->addOption('build-all', null, null, 'build cli, micro, fpm');
|
||||||
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
|
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
|
||||||
$this->addOption('enable-zts', null, null, 'enable ZTS support');
|
$this->addOption('enable-zts', null, null, 'enable ZTS support');
|
||||||
|
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
|
||||||
|
$this->addOption('with-micro-fake-cli', null, null, 'Enable phpmicro fake cli');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
// 从参数中获取要编译的 libraries,并转换为数组
|
// transform string to array
|
||||||
$libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs'))));
|
$libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs'))));
|
||||||
// 从参数中获取要编译的 extensions,并转换为数组
|
// transform string to array
|
||||||
$extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions'))));
|
$extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions'))));
|
||||||
|
|
||||||
define('BUILD_ALL_STATIC', true);
|
|
||||||
|
|
||||||
$rule = BUILD_TARGET_NONE;
|
$rule = BUILD_TARGET_NONE;
|
||||||
$rule = $rule | ($this->getOption('build-cli') ? BUILD_TARGET_CLI : 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-micro') ? BUILD_TARGET_MICRO : BUILD_TARGET_NONE);
|
||||||
@@ -49,12 +50,12 @@ class BuildCliCommand extends BuildCommand
|
|||||||
$this->output->writeln("<comment>\t--build-micro\tBuild phpmicro 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-fpm\tBuild php-fpm SAPI</comment>");
|
||||||
$this->output->writeln("<comment>\t--build-all\tBuild all SAPI: cli, micro, fpm</comment>");
|
$this->output->writeln("<comment>\t--build-all\tBuild all SAPI: cli, micro, fpm</comment>");
|
||||||
return 1;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 构建对象
|
// create builder
|
||||||
$builder = BuilderProvider::makeBuilderByInput($this->input);
|
$builder = BuilderProvider::makeBuilderByInput($this->input);
|
||||||
// 根据提供的扩展列表获取依赖库列表并编译
|
// calculate dependencies
|
||||||
[$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries);
|
[$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries);
|
||||||
/* @phpstan-ignore-next-line */
|
/* @phpstan-ignore-next-line */
|
||||||
logger()->info('Build target: ' . ConsoleColor::yellow($builder->getBuildTypeName($rule)));
|
logger()->info('Build target: ' . ConsoleColor::yellow($builder->getBuildTypeName($rule)));
|
||||||
@@ -66,17 +67,30 @@ class BuildCliCommand extends BuildCommand
|
|||||||
logger()->warning('some extensions will be enabled due to dependencies: ' . implode(',', $not_included));
|
logger()->warning('some extensions will be enabled due to dependencies: ' . implode(',', $not_included));
|
||||||
}
|
}
|
||||||
sleep(2);
|
sleep(2);
|
||||||
// 编译和检查库是否完整
|
// compile libraries
|
||||||
$builder->buildLibs($libraries);
|
$builder->buildLibs($libraries);
|
||||||
// 执行扩展检测
|
// check extensions
|
||||||
$builder->proveExts($extensions);
|
$builder->proveExts($extensions);
|
||||||
// strip
|
|
||||||
$builder->setStrip(false);
|
// Process -I option
|
||||||
// 构建
|
$custom_ini = [];
|
||||||
$builder->buildPHP($rule, $this->getOption('bloat'));
|
foreach ($this->input->getOption('with-hardcoded-ini') as $value) {
|
||||||
// 统计时间
|
[$source_name, $ini_value] = explode('=', $value, 2);
|
||||||
|
$custom_ini[$source_name] = $ini_value;
|
||||||
|
logger()->info('Adding hardcoded INI [' . $source_name . ' = ' . $ini_value . ']');
|
||||||
|
}
|
||||||
|
if (!empty($custom_ini)) {
|
||||||
|
SourcePatcher::patchHardcodedINI($custom_ini);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start to build
|
||||||
|
$builder->buildPHP($rule);
|
||||||
|
|
||||||
|
// compile stopwatch :P
|
||||||
$time = round(microtime(true) - START_TIME, 3);
|
$time = round(microtime(true) - START_TIME, 3);
|
||||||
logger()->info('Build complete, used ' . $time . ' s !');
|
logger()->info('Build complete, used ' . $time . ' s !');
|
||||||
|
|
||||||
|
// ---------- When using bin/spc-alpine-docker, the build root path is different from the host system ----------
|
||||||
$build_root_path = BUILD_ROOT_PATH;
|
$build_root_path = BUILD_ROOT_PATH;
|
||||||
$cwd = getcwd();
|
$cwd = getcwd();
|
||||||
$fixed = '';
|
$fixed = '';
|
||||||
@@ -94,17 +108,19 @@ class BuildCliCommand extends BuildCommand
|
|||||||
if (($rule & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
if (($rule & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
||||||
logger()->info('Static php-fpm binary path' . $fixed . ': ' . $build_root_path . '/bin/php-fpm');
|
logger()->info('Static php-fpm binary path' . $fixed . ': ' . $build_root_path . '/bin/php-fpm');
|
||||||
}
|
}
|
||||||
// 导出相关元数据
|
|
||||||
|
// export metadata
|
||||||
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-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));
|
file_put_contents(BUILD_ROOT_PATH . '/build-libraries.json', json_encode($libraries, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||||
// 导出 LICENSE
|
// export licenses
|
||||||
$dumper = new LicenseDumper();
|
$dumper = new LicenseDumper();
|
||||||
$dumper->addExts($extensions)->addLibs($libraries)->addSources(['php-src'])->dump(BUILD_ROOT_PATH . '/license');
|
$dumper->addExts($extensions)->addLibs($libraries)->addSources(['php-src'])->dump(BUILD_ROOT_PATH . '/license');
|
||||||
logger()->info('License path' . $fixed . ': ' . $build_root_path . '/license/');
|
logger()->info('License path' . $fixed . ': ' . $build_root_path . '/license/');
|
||||||
return 0;
|
return static::SUCCESS;
|
||||||
} catch (WrongUsageException $e) {
|
} catch (WrongUsageException $e) {
|
||||||
|
// WrongUsageException is not an exception, it's a user error, so we just print the error message
|
||||||
logger()->critical($e->getMessage());
|
logger()->critical($e->getMessage());
|
||||||
return 1;
|
return static::FAILURE;
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
if ($this->getOption('debug')) {
|
if ($this->getOption('debug')) {
|
||||||
ExceptionHandler::getInstance()->handle($e);
|
ExceptionHandler::getInstance()->handle($e);
|
||||||
@@ -112,7 +128,7 @@ class BuildCliCommand extends BuildCommand
|
|||||||
logger()->critical('Build failed with ' . get_class($e) . ': ' . $e->getMessage());
|
logger()->critical('Build failed with ' . get_class($e) . ': ' . $e->getMessage());
|
||||||
logger()->critical('Please check with --debug option to see more details.');
|
logger()->critical('Please check with --debug option to see more details.');
|
||||||
}
|
}
|
||||||
return 1;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ abstract class BuildCommand extends BaseCommand
|
|||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
|
|
||||||
// 根据运行的操作系统分配允许不同的命令行参数,Windows 需要额外的 VS 和 SDK等,*nix 需要提供架构
|
|
||||||
switch (PHP_OS_FAMILY) {
|
switch (PHP_OS_FAMILY) {
|
||||||
case 'Windows':
|
case 'Windows':
|
||||||
$this->addOption('with-sdk-binary-dir', null, InputOption::VALUE_REQUIRED, 'path to binary sdk');
|
$this->addOption('with-sdk-binary-dir', null, InputOption::VALUE_REQUIRED, 'path to binary sdk');
|
||||||
@@ -29,9 +28,7 @@ abstract class BuildCommand extends BaseCommand
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 是否在编译 make 前清除旧的文件
|
|
||||||
$this->addOption('with-clean', null, null, 'fresh build, `make clean` before `make`');
|
$this->addOption('with-clean', null, null, 'fresh build, `make clean` before `make`');
|
||||||
// 是否采用强制链接,让链接器强制加载静态库文件
|
|
||||||
$this->addOption('bloat', null, null, 'add all libraries into binary');
|
$this->addOption('bloat', null, null, 'add all libraries into binary');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
#[AsCommand('build:libs', 'Build dependencies')]
|
#[AsCommand('build:libs', 'Build dependencies')]
|
||||||
class BuildLibsCommand extends BuildCommand
|
class BuildLibsCommand extends BuildCommand
|
||||||
{
|
{
|
||||||
public function configure()
|
public function configure(): void
|
||||||
{
|
{
|
||||||
$this->addArgument('libraries', InputArgument::REQUIRED, 'The libraries will be compiled, comma separated');
|
$this->addArgument('libraries', InputArgument::REQUIRED, 'The libraries will be compiled, comma separated');
|
||||||
$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, 'Build all libs that static-php-cli needed');
|
$this->addOption('all', 'A', null, 'Build all libs that static-php-cli needed');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initialize(InputInterface $input, OutputInterface $output)
|
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
{
|
{
|
||||||
// --all 等于 ""
|
// --all 等于 ""
|
||||||
if ($input->getOption('all')) {
|
if ($input->getOption('all')) {
|
||||||
@@ -63,7 +63,7 @@ class BuildLibsCommand extends BuildCommand
|
|||||||
|
|
||||||
$time = round(microtime(true) - START_TIME, 3);
|
$time = round(microtime(true) - START_TIME, 3);
|
||||||
logger()->info('Build libs complete, used ' . $time . ' s !');
|
logger()->info('Build libs complete, used ' . $time . ' s !');
|
||||||
return 0;
|
return static::SUCCESS;
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
if ($this->getOption('debug')) {
|
if ($this->getOption('debug')) {
|
||||||
ExceptionHandler::getInstance()->handle($e);
|
ExceptionHandler::getInstance()->handle($e);
|
||||||
@@ -71,7 +71,7 @@ class BuildLibsCommand extends BuildCommand
|
|||||||
logger()->critical('Build failed with ' . get_class($e) . ': ' . $e->getMessage());
|
logger()->critical('Build failed with ' . get_class($e) . ': ' . $e->getMessage());
|
||||||
logger()->critical('Please check with --debug option to see more details.');
|
logger()->critical('Please check with --debug option to see more details.');
|
||||||
}
|
}
|
||||||
return 1;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,42 +4,71 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\command;
|
namespace SPC\command;
|
||||||
|
|
||||||
use CliHelper\Tools\ArgFixer;
|
use SPC\store\FileSystem;
|
||||||
use CliHelper\Tools\DataProvider;
|
|
||||||
use CliHelper\Tools\SeekableArrayIterator;
|
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Helper\ProgressBar;
|
use Symfony\Component\Console\Helper\ProgressBar;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
use function Laravel\Prompts\confirm;
|
||||||
|
use function Laravel\Prompts\text;
|
||||||
|
|
||||||
#[AsCommand('deploy', 'Deploy static-php-cli self to an .phar application')]
|
#[AsCommand('deploy', 'Deploy static-php-cli self to an .phar application')]
|
||||||
class DeployCommand extends BaseCommand
|
class DeployCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
public function configure()
|
public function configure(): void
|
||||||
{
|
{
|
||||||
$this->addArgument('target', InputArgument::OPTIONAL, 'The file or directory to pack.');
|
$this->addArgument('target', InputArgument::OPTIONAL, 'The file or directory to pack.');
|
||||||
$this->addOption('auto-phar-fix', null, InputOption::VALUE_NONE, 'Automatically fix ini option.');
|
$this->addOption('auto-phar-fix', null, InputOption::VALUE_NONE, 'Automatically fix ini option.');
|
||||||
$this->addOption('overwrite', 'W', InputOption::VALUE_NONE, 'Overwrite existing files.');
|
$this->addOption('overwrite', 'W', InputOption::VALUE_NONE, 'Overwrite existing files.');
|
||||||
|
$this->addOption('with-no-dev', 'D', InputOption::VALUE_NONE, 'Automatically use non-dev composer dependencies to reduce size');
|
||||||
|
$this->addOption('with-dev', 'd', InputOption::VALUE_NONE, 'Automatically use dev composer dependencies');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \PharException
|
||||||
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
// 第一阶段流程:如果没有写path,将会提示输入要打包的path
|
$composer = require ROOT_DIR . '/vendor/composer/installed.php';
|
||||||
$prompt = new ArgFixer($this->input, $this->output);
|
if (($composer['root']['dev'] ?? false) === true) {
|
||||||
|
if (!$this->getOption('with-no-dev')) {
|
||||||
|
$this->output->writeln('<comment>Current static-php-cli dependencies have installed dev-dependencies</comment>');
|
||||||
|
$this->output->writeln('<comment>If you want to remove, you can choose "Yes" to run command "composer update --no-dev" to remove.</comment>');
|
||||||
|
$this->output->writeln('<comment>Or choose "No", just pack, deploy.</comment>');
|
||||||
|
$ask = confirm('Do you want to remove dev-dependencies to reduce size of phar file?');
|
||||||
|
} elseif (!$this->getOption('with-dev')) {
|
||||||
|
$ask = true;
|
||||||
|
} else {
|
||||||
|
$ask = false;
|
||||||
|
}
|
||||||
|
if ($ask) {
|
||||||
|
[$code] = shell()->execWithResult('composer update --no-dev');
|
||||||
|
if ($code !== 0) {
|
||||||
|
$this->output->writeln('<error>"composer update --no-dev" failed with exit code [' . $code . ']</error>');
|
||||||
|
$this->output->writeln('<error>You may need to run this command by your own.</error>');
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
$this->output->writeln('<info>Update successfully, you need to re-run deploy command to pack.</info>');
|
||||||
|
return static::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
// 首先得确认是不是关闭了readonly模式
|
// 首先得确认是不是关闭了readonly模式
|
||||||
if (ini_get('phar.readonly') == 1) {
|
if (ini_get('phar.readonly') == 1) {
|
||||||
if ($this->getOption('auto-phar-fix')) {
|
if ($this->getOption('auto-phar-fix')) {
|
||||||
$ask = true;
|
$ask = true;
|
||||||
} else {
|
} else {
|
||||||
$ask = $prompt->requireBool('<comment>pack command needs "phar.readonly" = "Off" !</comment>' . PHP_EOL . 'If you want to automatically set it and continue, just Enter', true);
|
$this->output->writeln('<comment>pack command needs "phar.readonly" = "Off" !</comment>');
|
||||||
|
$ask = confirm('Do you want to automatically set it and continue ?');
|
||||||
|
// $ask = $prompt->requireBool('<comment>pack command needs "phar.readonly" = "Off" !</comment>' . PHP_EOL . 'If you want to automatically set it and continue, just Enter', true);
|
||||||
}
|
}
|
||||||
if ($ask) {
|
if ($ask) {
|
||||||
global $argv;
|
global $argv;
|
||||||
$args = array_merge(['-d', 'phar.readonly=0'], $_SERVER['argv']);
|
$args = array_merge(['-d', 'phar.readonly=0'], $_SERVER['argv'], ['--no-motd']);
|
||||||
if (function_exists('pcntl_exec')) {
|
if (function_exists('pcntl_exec')) {
|
||||||
$this->output->writeln('<info>Changing to phar.readonly=0 mode ...</info>');
|
$this->output->writeln('<info>Changing to phar.readonly=0 mode ...</info>');
|
||||||
if (pcntl_exec(PHP_BINARY, $args) === false) {
|
if (pcntl_exec(PHP_BINARY, $args) === false) {
|
||||||
throw new \PharException('切换到读写模式失败,请检查环境。');
|
throw new \PharException('Switching to read write mode failed, please check the environment.');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->output->writeln('<info>Now running command in child process.</info>');
|
$this->output->writeln('<info>Now running command in child process.</info>');
|
||||||
@@ -51,23 +80,29 @@ class DeployCommand extends BaseCommand
|
|||||||
// 获取路径
|
// 获取路径
|
||||||
$path = WORKING_DIR;
|
$path = WORKING_DIR;
|
||||||
// 如果是目录,则将目录下的所有文件打包
|
// 如果是目录,则将目录下的所有文件打包
|
||||||
$phar_path = $prompt->requireArgument('target', 'Please input the phar target filename', 'static-php-cli.phar');
|
$phar_path = text('Please input the phar target filename', default: '/tmp/static-php-cli.phar');
|
||||||
|
// $phar_path = $prompt->requireArgument('target', 'Please input the phar target filename', 'static-php-cli.phar');
|
||||||
|
|
||||||
if (DataProvider::isRelativePath($phar_path)) {
|
if (FileSystem::isRelativePath($phar_path)) {
|
||||||
$phar_path = '/tmp/' . $phar_path;
|
$phar_path = WORKING_DIR . '/' . $phar_path;
|
||||||
}
|
}
|
||||||
if (file_exists($phar_path)) {
|
if (file_exists($phar_path)) {
|
||||||
$ask = $this->getOption('overwrite') ? true : $prompt->requireBool('<comment>The file "' . $phar_path . '" already exists, do you want to overwrite it?</comment>' . PHP_EOL . 'If you want to, just Enter');
|
if (!$this->getOption('overwrite')) {
|
||||||
|
$this->output->writeln('<comment>The file "' . $phar_path . '" already exists.</comment>');
|
||||||
|
$ask = confirm('Do you want to overwrite it?');
|
||||||
|
} else {
|
||||||
|
$ask = true;
|
||||||
|
}
|
||||||
if (!$ask) {
|
if (!$ask) {
|
||||||
$this->output->writeln('<comment>User canceled.</comment>');
|
$this->output->writeln('<comment>User canceled.</comment>');
|
||||||
return 1;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
@unlink($phar_path);
|
@unlink($phar_path);
|
||||||
}
|
}
|
||||||
$phar = new \Phar($phar_path);
|
$phar = new \Phar($phar_path);
|
||||||
$phar->startBuffering();
|
$phar->startBuffering();
|
||||||
|
|
||||||
$all = DataProvider::scanDirFiles($path, true, true);
|
$all = FileSystem::scanDirFiles($path, true, true);
|
||||||
|
|
||||||
$all = array_filter($all, function ($x) {
|
$all = array_filter($all, function ($x) {
|
||||||
$dirs = preg_match('/(^(config|src|vendor)\\/|^(composer\\.json|README\\.md|source\\.json|LICENSE|README-en\\.md)$)/', $x);
|
$dirs = preg_match('/(^(config|src|vendor)\\/|^(composer\\.json|README\\.md|source\\.json|LICENSE|README-en\\.md)$)/', $x);
|
||||||
@@ -97,7 +132,7 @@ class DeployCommand extends BaseCommand
|
|||||||
$phar->setStub($phar->createDefaultStub($stub));
|
$phar->setStub($phar->createDefaultStub($stub));
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->output->writeln($e);
|
$this->output->writeln($e);
|
||||||
return 1;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
$phar->addFromString('.prod', 'true');
|
$phar->addFromString('.prod', 'true');
|
||||||
$phar->stopBuffering();
|
$phar->stopBuffering();
|
||||||
@@ -114,12 +149,12 @@ class DeployCommand extends BaseCommand
|
|||||||
}
|
}
|
||||||
chmod($phar_path, 0755);
|
chmod($phar_path, 0755);
|
||||||
$this->output->writeln('<info>Phar Executable: ' . $phar_path . '</info>');
|
$this->output->writeln('<info>Phar Executable: ' . $phar_path . '</info>');
|
||||||
return 0;
|
return static::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function progress(int $max = 0): ProgressBar
|
private function progress(): ProgressBar
|
||||||
{
|
{
|
||||||
$progress = new ProgressBar($this->output, $max);
|
$progress = new ProgressBar($this->output, 0);
|
||||||
$progress->setBarCharacter('<fg=green>⚬</>');
|
$progress->setBarCharacter('<fg=green>⚬</>');
|
||||||
$progress->setEmptyBarCharacter('<fg=red>⚬</>');
|
$progress->setEmptyBarCharacter('<fg=red>⚬</>');
|
||||||
$progress->setProgressCharacter('<fg=green>➤</>');
|
$progress->setProgressCharacter('<fg=green>➤</>');
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user