Compare commits

..

15 Commits
2.3.2 ... 2.3.3

Author SHA1 Message Date
Jerry Ma
c55ccf242b Use static-php/phpmicro temporarily (#536) 2024-09-06 13:38:54 +08:00
Jerry Ma
b45081dd9c Add --custom-git (-G) option for download command (#534)
* Add --custom-git (-G) option for download command

* Update manual-build.md

* Update manual-build.md

* Update DownloadCommand.php
2024-09-05 00:00:58 +08:00
Jerry Ma
326d682e44 Make opcache patch independent (#533)
* Make opcache patch independent

* Restore tests.yml

* Workaround for older php
2024-09-05 00:00:36 +08:00
crazywhalecc
b354e017ba Add switch-php-version specific patch version support 2024-09-04 16:41:53 +08:00
crazywhalecc
3ce302d0e6 Use old version 2024-09-04 16:35:39 +08:00
crazywhalecc
a38f9e6344 Update docs 2024-09-04 16:35:39 +08:00
crazywhalecc
4e08295cea Add patch version support for downloading php-src 2024-09-04 16:35:39 +08:00
crazywhalecc
73654e5984 Add dependency map generator and related docs 2024-08-21 11:53:26 +08:00
crazywhalecc
077da6f6a4 Correct snappy ext-suggest to ext-suggests 2024-08-21 11:53:26 +08:00
crazywhalecc
0665af2537 Add SPC_MICRO_PATCHES env var 2024-08-20 12:23:12 +08:00
crazywhalecc
d5832c22e3 Change to deploy OSS 2024-08-18 15:50:08 +08:00
crazywhalecc
d231364c1a Add tests 2024-08-18 15:50:08 +08:00
crazywhalecc
fdb5c6aa1d Fix alpine edge build with PHP 7.4 and 8.0 2024-08-18 15:50:08 +08:00
crazywhalecc
47ba881870 Fix alpine edge build imap library bug 2024-08-18 15:50:08 +08:00
crazywhalecc
9fd0508417 Fix swoole-hook-sqlite with PHP 8.3 on macOS arm64 bug 2024-08-18 15:50:08 +08:00
33 changed files with 911 additions and 125 deletions

View File

@@ -115,17 +115,16 @@ jobs:
with:
files: dist/${{ matrix.operating-system.filename }}
- name: "Deploy to Self-Hosted Server"
- name: "Deploy to self-hosted OSS"
if: github.repository == 'crazywhalecc/static-php-cli'
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SERVER_SECRET_KEY }}
ARGS: "-rltgoDzvO"
SOURCE: "dist/"
REMOTE_HOST: ${{ secrets.DEPLOY_SERVER_HOST }}
REMOTE_PORT: ${{ secrets.DEPLOY_SERVER_PORT }}
REMOTE_USER: ${{ secrets.DEPLOY_SERVER_USER }}
TARGET: ${{ secrets.DEPLOY_SERVER_TARGET_SPC_NIGHTLY }}
uses: static-php/upload-s3-action@v1.0.0
with:
aws_key_id: ${{ secrets.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws_bucket: ${{ secrets.AWS_BUCKET }}
source_dir: "dist/"
destination_dir: static-php-cli/spc-bin/nightly/
endpoint: ${{ secrets.AWS_ENDPOINT }}
- name: "Upload Artifact"
uses: actions/upload-artifact@v4

View File

@@ -58,6 +58,8 @@ jobs:
- name: "Generate Extension Support List"
run: |
bin/spc dev:gen-ext-docs > docs/extensions.md
bin/spc dev:gen-ext-dep-docs > docs/deps-map-ext.md
bin/spc dev:gen-lib-dep-docs > docs/deps-map-lib.md
- name: Build
run: yarn docs:build

View File

@@ -184,7 +184,7 @@ bin/spc --version
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
# 下载依赖时,优先下载有预编译的库(节省编译依赖的时间)
./bin/spc download --for-extensions="openssl,curl,mbstring,mbregex" --prefer-pre-built
# 下载编译不同版本的 PHP (--with-php=x.y推荐 7.3 ~ 8.3)
# 下载编译不同版本的 PHP (--with-php=x.y 或 --with-php=x.y.z,推荐 8.1 ~ 8.3)
./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx

View File

@@ -195,7 +195,7 @@ Basic usage for building php with some extensions:
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
# download pre-built libraries first (save time for compiling dependencies)
./bin/spc download --for-extensions="openssl,curl,mbstring,mbregex" --prefer-pre-built
# download different PHP version (--with-php=x.y, recommend 7.3 ~ 8.3)
# download different PHP version (--with-php=x.y or --with-php=x.y.z, recommend 8.1 ~ 8.3)
./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
# with bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl extension, build both CLI and phpmicro SAPI

View File

@@ -590,7 +590,7 @@
"lib-depends": [
"snappy"
],
"ext-suggest": [
"ext-suggests": [
"apcu"
]
},

View File

@@ -497,7 +497,7 @@
"type": "git",
"path": "php-src/sapi/micro",
"rev": "master",
"url": "https://github.com/easysoft/phpmicro",
"url": "https://github.com/static-php/phpmicro",
"license": {
"type": "file",
"path": "LICENSE"

View File

@@ -10,6 +10,7 @@ export default {
{text: 'Extension Notes', link: '/en/guide/extension-notes'},
{text: 'Command Generator', link: '/en/guide/cli-generator'},
{text: 'Environment Variables', link: '/en/guide/env-vars', collapsed: true,},
{text: 'Dependency Table', link: '/en/guide/deps-map'},
]
},
{

View File

@@ -10,6 +10,7 @@ export default {
{text: '扩展注意事项', link: '/zh/guide/extension-notes'},
{text: '编译命令生成器', link: '/zh/guide/cli-generator'},
{text: '环境变量列表', link: '/zh/guide/env-vars'},
{text: '依赖关系图表', link: '/zh/guide/deps-map'},
]
},
{

0
docs/deps-map-ext.md Normal file
View File

0
docs/deps-map-lib.md Normal file
View File

26
docs/en/guide/deps-map.md Normal file
View File

@@ -0,0 +1,26 @@
---
outline: 'deep'
---
# Dependency Table
When compiling PHP, each extension and library has dependencies, which may be required or optional.
You can choose whether to include these optional dependencies.
For example, when compiling the `gd` extension under Linux,
the `zlib,libpng` libraries and the `zlib` extension are forced to be compiled,
while the `libavif,libwebp,libjpeg,freetype` libraries are optional libraries and will not be compiled by default
unless specified by the `--with-libs=avif,webp,jpeg,freetype` option.
- For optional extensions (optional features of extensions), you need to specify them manually at compile time, for example, to enable igbinary support for Redis: `bin/spc build redis,igbinary`.
- For optional libraries, you need to compile and specify them through the `--with-libs=XXX` option.
- If you want to enable all optional extensions, you can use `bin/spc build redis --with-suggested-exts`.
- If you want to enable all optional libraries, you can use `--with-suggested-libs`.
## Extension Dependency Table
<!--@include: ../../deps-map-ext.md-->
## Library Dependency Table
<!--@include: ../../deps-map-lib.md-->

View File

@@ -44,27 +44,29 @@ These environment variables are system-specific and will only take effect on a s
### Windows
| var name | default value | comment |
|----------------|------------------------------|---------------------------|
| `PHP_SDK_PATH` | `{pwd}\php-sdk-binary-tools` | PHP SDK tools path |
| `UPX_EXEC` | `$PKG_ROOT_PATH\bin\upx.exe` | UPX compression tool path |
| var name | default value | comment |
|---------------------|-----------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
| `PHP_SDK_PATH` | `{pwd}\php-sdk-binary-tools` | PHP SDK tools path |
| `UPX_EXEC` | `$PKG_ROOT_PATH\bin\upx.exe` | UPX compression tool path |
| `SPC_MICRO_PATCHES` | `static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static` | Used phpmicro [patches](https://github.com/easysoft/phpmicro/blob/master/patches/Readme.md) |
### macOS
| var name | default value | comment |
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
| `CC` | `clang` | C Compiler |
| `CXX` | `clang++` | C++ Compiler |
| `SPC_DEFAULT_C_FLAGS` | `--target=arm64-apple-darwin` or `--target=x86_64-apple-darwin` | Default C flags (not the same as `CFLAGS`) |
| `SPC_DEFAULT_CXX_FLAGS` | `--target=arm64-apple-darwin` or `--target=x86_64-apple-darwin` | Default C flags (not the same as `CPPFLAGS`) |
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | PHP `buildconf` command prefix |
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | PHP `configure` command prefix |
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | PHP `make` command prefix |
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS -Werror=unknown-warning-option` | `CFLAGS` variable of PHP `configure` command |
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | `CPPFLAGS` variable of PHP `configure` command |
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | `LDFLAGS` variable of PHP `configure` command |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os` or `-g -O0` (the latter when using `--no-strip`) | `EXTRA_CFLAGS` variable of PHP `make` command |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | `-lresolv` | Extra `EXTRA_LIBS` variables for PHP `make` command |
| var name | default value | comment |
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
| `CC` | `clang` | C Compiler |
| `CXX` | `clang++` | C++ Compiler |
| `SPC_DEFAULT_C_FLAGS` | `--target=arm64-apple-darwin` or `--target=x86_64-apple-darwin` | Default C flags (not the same as `CFLAGS`) |
| `SPC_DEFAULT_CXX_FLAGS` | `--target=arm64-apple-darwin` or `--target=x86_64-apple-darwin` | Default C flags (not the same as `CPPFLAGS`) |
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | PHP `buildconf` command prefix |
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | PHP `configure` command prefix |
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | PHP `make` command prefix |
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS -Werror=unknown-warning-option` | `CFLAGS` variable of PHP `configure` command |
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | `CPPFLAGS` variable of PHP `configure` command |
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | `LDFLAGS` variable of PHP `configure` command |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os` or `-g -O0` (the latter when using `--no-strip`) | `EXTRA_CFLAGS` variable of PHP `make` command |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | `-lresolv` | Extra `EXTRA_LIBS` variables for PHP `make` command |
| `SPC_MICRO_PATCHES` | `static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,macos_iconv` | Used phpmicro [patches](https://github.com/easysoft/phpmicro/blob/master/patches/Readme.md) |
### Linux
@@ -90,6 +92,7 @@ These environment variables are system-specific and will only take effect on a s
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | empty | Extra `EXTRA_LIBS` variables for PHP `make` command |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM` | `-all-static` (when using `clang`: `-Xcompiler -fuse-ld=lld -all-static`) | Additional `LDFLAGS` variable for `make` command |
| `SPC_NO_MUSL_PATH` | empty | Whether to not insert the PATH of the musl toolchain (not inserted when the value is `yes`) |
| `SPC_MICRO_PATCHES` | `static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream` | Used phpmicro [patches](https://github.com/easysoft/phpmicro/blob/master/patches/Readme.md) |
> `{ld_lib_path}` value is `/usr/local/musl/$GNU_ARCH-linux-musl/lib`。
### FreeBSD

View File

@@ -14,14 +14,6 @@ Some extensions or libraries that the extension depends on will have some option
For example, the gd library optionally supports libwebp, freetype, etc.
If you only use `bin/spc build gd --build-cli` they will not be included (static-php-cli defaults to the minimum dependency principle).
You can use `--with-libs=` to add these libraries when compiling.
When the dependent libraries of this compilation include them, gd will automatically use them to enable these features.
(For example: `bin/spc build gd --with-libs=libwebp,freetype --build-cli`)
Alternatively you can use `--with-suggested-exts` and `--with-suggested-libs` to enable all optional dependencies of these extensions and libraries.
(For example: `bin/spc build gd --with-suggested-libs --build-cli`)
If you don't know whether an extension has optional features,
you can check the [spc configuration file](https://github.com/crazywhalecc/static-php-cli/tree/main/config)
or use the command `bin/spc dev:extensions` (library dependency is `lib-suggests`, extension dependency is `ext-suggests`).
For more information about optional libraries, see [Extensions, Library Dependency Map](./deps-map).
For optional libraries, you can also select an extension from the [Command Generator](./cli-generator) and then select optional libraries.
:::

View File

@@ -143,6 +143,7 @@ including php-src and the source code of various dependent libraries.
bin/spc download --all
# Download all dependent packages, and specify the main version of PHP to download, optional: 7.3, 7.4, 8.0, 8.1, 8.2, 8.3
# Also supports specific version of php release: 8.3.10, 8.2.22, etc.
bin/spc download --all --with-php=8.2
# Show download progress bar while downloading (curl)
@@ -170,7 +171,7 @@ bin/spc download --for-libs=liblz4,libevent --for-extensions=pcntl,rar,xml
bin/spc download --for-libs=liblz4,libevent --without-suggestions
# When downloading sources, ignore some source caches (always force download, e.g. switching PHP version)
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3.10
# Set retry times (default is 0)
bin/spc download --all --retry=2
@@ -203,6 +204,19 @@ bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
```
If the source you download is not a link, but a git repository, you can use `-G` or `--custom-git` to rewrite the download link,
so that the downloader can force the use of the specified git repository to download packages from this source.
The usage method is `{source-name}:{branch}:{url}`, which can rewrite the download link of multiple libraries at the same time.
It is also available when downloading with the `--for-extensions` option.
```bash
# Specifying to download the source code of the PHP extension from the specified branch of the git repository
bin/spc download --for-extensions=redis -G "php-src:master:https://github.com/php/php-src.git"
# Download the latest code from the master branch of the swoole-src repository instead of PECL release version
bin/spc download --for-extensions=swoole -G "swoole:master:https://github.com/swoole/swoole-src.git"
```
## Command - doctor
If you can run `bin/spc` normally but cannot compile static PHP or dependent libraries normally,

22
docs/zh/guide/deps-map.md Normal file
View File

@@ -0,0 +1,22 @@
---
outline: 'deep'
---
# 依赖关系图表
在编译 PHP 时,每个扩展、库都有依赖关系,这些依赖关系可能是必需的,也可能是可选的。在编译 PHP 时,可以选择是否包含这些可选的依赖关系。
例如,在 Linux 下编译 `gd` 扩展时,会强制编译 `zlib,libpng` 库和 `zlib` 扩展,而 `libavif,libwebp,libjpeg,freetype` 库都是可选的库,默认不会编译,除非通过 `--with-libs=avif,webp,jpeg,freetype` 选项指定。
- 对于可选扩展(扩展的可选特性),需手动在编译时指定,例如启用 Redis 的 igbinary 支持:`bin/spc build redis,igbinary`
- 对于可选库,需通过 `--with-libs=XXX` 选项编译指定。
- 如果想启用所有的可选扩展,可以使用 `bin/spc build redis --with-suggested-exts` 参数。
- 如果想启用所有的可选库,可以使用 `--with-suggested-libs` 参数。
## 扩展的依赖图
<!--@include: ../../deps-map-ext.md-->
## 库的依赖表
<!--@include: ../../deps-map-lib.md-->

View File

@@ -42,52 +42,56 @@ SPC_CONCURRENCY=4 bin/spc build mbstring,pcntl --build-cli
### Windows
| var name | default value | comment |
|----------------|------------------------------|-----------------|
| `PHP_SDK_PATH` | `{pwd}\php-sdk-binary-tools` | PHP SDK 工具的安装目录 |
| `UPX_EXEC` | `$PKG_ROOT_PATH\bin\upx.exe` | UPX 压缩工具的路径 |
| var name | default value | comment |
|---------------------|-----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| `PHP_SDK_PATH` | `{pwd}\php-sdk-binary-tools` | PHP SDK 工具的安装目录 |
| `UPX_EXEC` | `$PKG_ROOT_PATH\bin\upx.exe` | UPX 压缩工具的路径 |
| `SPC_MICRO_PATCHES` | `static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static` | 使用的 phpmicro [patches](https://github.com/easysoft/phpmicro/blob/master/patches/Readme.md) |
### macOS
| var name | default value | comment |
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|
| `CC` | `clang` | C 编译器 |
| `CXX` | `clang++` | C++ 编译器 |
| `SPC_DEFAULT_C_FLAGS` | `--target=arm64-apple-darwin``--target=x86_64-apple-darwin` | 默认 C 编译标志(与 `CFLAGS` 不同) |
| `SPC_DEFAULT_CXX_FLAGS` | `--target=arm64-apple-darwin``--target=x86_64-apple-darwin` | 默认 C++ 编译标志(与 `CXXFLAGS` 不同) |
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | 编译 PHP `buildconf` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | 编译 PHP `configure` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | 编译 PHP `make` 命令前缀 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS -Werror=unknown-warning-option` | PHP `configure` 命令的 `CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | PHP `configure` 命令的 `CPPFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | PHP `configure` 命令的 `LDFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os``-g -O0`(当使用 `--no-strip` 时为后者) | PHP `make` 命令的 `EXTRA_CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | `-lresolv` | PHP `make` 命令的额外 `EXTRA_LIBS` 变量 |
| var name | default value | comment |
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| `CC` | `clang` | C 编译器 |
| `CXX` | `clang++` | C++ 编译器 |
| `SPC_DEFAULT_C_FLAGS` | `--target=arm64-apple-darwin``--target=x86_64-apple-darwin` | 默认 C 编译标志(与 `CFLAGS` 不同) |
| `SPC_DEFAULT_CXX_FLAGS` | `--target=arm64-apple-darwin``--target=x86_64-apple-darwin` | 默认 C++ 编译标志(与 `CXXFLAGS` 不同) |
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | 编译 PHP `buildconf` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | 编译 PHP `configure` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | 编译 PHP `make` 命令前缀 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS -Werror=unknown-warning-option` | PHP `configure` 命令的 `CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | PHP `configure` 命令的 `CPPFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | PHP `configure` 命令的 `LDFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os``-g -O0`(当使用 `--no-strip` 时为后者) | PHP `make` 命令的 `EXTRA_CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | `-lresolv` | PHP `make` 命令的额外 `EXTRA_LIBS` 变量 |
| `SPC_MICRO_PATCHES` | `static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,macos_iconv` | 使用的 phpmicro [patches](https://github.com/easysoft/phpmicro/blob/master/patches/Readme.md) |
### Linux
| var name | default value | comment |
|----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------|
| `UPX_EXEC` | `$PKG_ROOT_PATH/bin/upx` | UPX 压缩工具的路径 |
| `GNU_ARCH` | `x86_64``aarch64` | 当前环境的 CPU 架构 |
| `CC` | Alpine: `gcc`, Other: `$GNU_ARCH-linux-musl-gcc` | C 编译器 |
| `CXX` | Alpine: `g++`, Other: `$GNU_ARCH-linux-musl-g++` | C++ 编译器 |
| `AR` | Alpine: `ar`, Other: `$GNU_ARCH-linux-musl-ar` | 静态库工具 |
| `LD` | `ld.gold` | 链接器 |
| `PATH` | `/usr/local/musl/bin:/usr/local/musl/$GNU_ARCH-linux-musl/bin:$PATH` | 系统 PATH |
| `SPC_DEFAULT_C_FLAGS` | empty | 默认 C 编译标志 |
| `SPC_DEFAULT_CXX_FLAGS` | empty | 默认 C++ 编译标志 |
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | 编译 PHP `buildconf` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `LD_LIBRARY_PATH={ld_lib_path} ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | 编译 PHP `configure` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | 编译 PHP `make` 命令前缀 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS` | PHP `configure` 命令的 `CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | PHP `configure` 命令的 `CPPFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | PHP `configure` 命令的 `LDFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_LIBS` | `-ldl -lpthread` | PHP `configure` 命令的 `LIBS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os -fno-ident -fPIE``-g -O0 -fno-ident -fPIE`(当使用 `--no-strip` 时为后者) | PHP `make` 命令的 `EXTRA_CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | empty | PHP `make` 命令的额外 `EXTRA_LIBS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM` | `-all-static`(当使用 `clang` 时:`-Xcompiler -fuse-ld=lld -all-static` | `make` 命令的额外 `LDFLAGS` 变量(用于编译程序) |
| `SPC_NO_MUSL_PATH` | empty | 是否不插入 musl 工具链的 PATH值为 `yes` 时不插入) |
| var name | default value | comment |
|----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| `UPX_EXEC` | `$PKG_ROOT_PATH/bin/upx` | UPX 压缩工具的路径 |
| `GNU_ARCH` | `x86_64``aarch64` | 当前环境的 CPU 架构 |
| `CC` | Alpine: `gcc`, Other: `$GNU_ARCH-linux-musl-gcc` | C 编译器 |
| `CXX` | Alpine: `g++`, Other: `$GNU_ARCH-linux-musl-g++` | C++ 编译器 |
| `AR` | Alpine: `ar`, Other: `$GNU_ARCH-linux-musl-ar` | 静态库工具 |
| `LD` | `ld.gold` | 链接器 |
| `PATH` | `/usr/local/musl/bin:/usr/local/musl/$GNU_ARCH-linux-musl/bin:$PATH` | 系统 PATH |
| `SPC_DEFAULT_C_FLAGS` | empty | 默认 C 编译标志 |
| `SPC_DEFAULT_CXX_FLAGS` | empty | 默认 C++ 编译标志 |
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | 编译 PHP `buildconf` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `LD_LIBRARY_PATH={ld_lib_path} ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | 编译 PHP `configure` 命令前缀 |
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | 编译 PHP `make` 命令前缀 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS` | PHP `configure` 命令的 `CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | PHP `configure` 命令的 `CPPFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | PHP `configure` 命令的 `LDFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_CONFIGURE_LIBS` | `-ldl -lpthread` | PHP `configure` 命令的 `LIBS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os -fno-ident -fPIE``-g -O0 -fno-ident -fPIE`(当使用 `--no-strip` 时为后者) | PHP `make` 命令的 `EXTRA_CFLAGS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | empty | PHP `make` 命令的额外 `EXTRA_LIBS` 变量 |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM` | `-all-static`(当使用 `clang` 时:`-Xcompiler -fuse-ld=lld -all-static` | `make` 命令的额外 `LDFLAGS` 变量(用于编译程序) |
| `SPC_NO_MUSL_PATH` | empty | 是否不插入 musl 工具链的 PATH值为 `yes` 时不插入) |
| `SPC_MICRO_PATCHES` | `static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream` | 使用的 phpmicro [patches](https://github.com/easysoft/phpmicro/blob/master/patches/Readme.md) |
> `{ld_lib_path}` 值为 `/usr/local/musl/$GNU_ARCH-linux-musl/lib`。
### FreeBSD

View File

@@ -132,7 +132,7 @@ event 扩展在 macOS 系统下编译后暂无法使用 `openpty` 特性。相
parallel 扩展只支持 PHP 8.0 及以上版本,并只支持 ZTS 构建(`--enable-zts`)。
# spx
## spx
1. [SPX 扩展](https://github.com/NoiseByNorthwest/php-spx) 只支持非线程模式。
2. SPX 目前不支持 Windows且官方仓库也不支持静态编译static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。

View File

@@ -13,12 +13,5 @@
有些扩展或扩展依赖的库会有一些可选的特性,例如 gd 库可选支持 libwebp、freetype 等。
如果你只使用 `bin/spc build gd --build-cli` 是不会包含它们static-php-cli 默认为最小依赖原则)。
你可以在编译时使用 `--with-libs=` 加入这些库当本次编译的依赖库中包含它们gd 会自动依赖它们启用这些特性
(如:`bin/spc build gd --with-libs=libwebp,freetype --build-cli`
或者你也可以使用 `--with-suggested-exts``--with-suggested-libs` 启用这些扩展和库所有可选的依赖。
(如:`bin/spc build gd --with-suggested-libs --build-cli`
如果你不知道某个扩展是否有可选特性,可以通过查看 [spc 配置文件](https://github.com/crazywhalecc/static-php-cli/tree/main/config)
或使用命令 `bin/spc dev:extensions` 查看(库依赖为 `lib-suggests`,扩展依赖为 `ext-suggests`)。
有关编译可选库,请参考 [扩展、库的依赖关系图表](./deps-map)。对于可选的库,你也可以从 [编译命令生成器](./cli-generator) 中选择扩展后展开选择可选库
:::

View File

@@ -132,8 +132,8 @@ bin/spc download --for-libs=liblz4,libevent --for-extensions=pcntl,rar,xml
# 仅下载要编译的库(包括其依赖,使用库名,不包含可选库)
bin/spc download --for-libs=liblz4,libevent --without-suggestions
# 下载资源时,忽略部分资源的缓存,强制下载(如切换 PHP 版本)
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3
# 下载资源时,忽略部分资源的缓存,强制下载(如切换特定 PHP 版本)
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3.10
# 下载资源时,优先下载有预编译包的依赖库(减少编译依赖的时间)
bin/spc download --for-extensions="curl,pcntl,xml,mbstring" --prefer-pre-built
@@ -141,7 +141,7 @@ bin/spc download --for-extensions="curl,pcntl,xml,mbstring" --prefer-pre-built
# 下载所有依赖包
bin/spc download --all
# 下载所有依赖包,并指定下载的 PHP 主版本可选7.37.48.08.18.28.3。
# 下载所有依赖包,并指定下载的 PHP 主版本可选7.37.48.08.18.28.3,也可以使用特定的版本,如 8.3.10
bin/spc download --all --with-php=8.2
# 下载时显示下载进度条curl
@@ -176,6 +176,17 @@ bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
```
如果你下载的资源不是链接,而是一个 Git 仓库,你可以使用 `-G``--custom-git` 重写下载链接,让下载器强制使用你指定的 Git 仓库下载此 source 的包。
使用方法为 `{source-name}:{branch}:{url}` 即可,可同时重写多个库的下载地址。在使用 `--for-extensions` 选项下载时同样可用。
```bash
# 例如:下载 master 分支的 php-src
bin/spc download --for-extensions=redis,phar -G "php-src:master:https://github.com/php/php-src.git"
# 从 swoole-src 仓库下载 master 分支的最新代码,而不是发行版
bin/spc download --for-extensions=swoole -G "swoole:master:https://github.com/swoole/swoole-src.git"
```
## 命令 doctor - 环境检查
如果你可以正常运行 `bin/spc` 但无法正常编译静态的 PHP 或依赖库,可以先运行 `bin/spc doctor` 检查系统自身是否缺少依赖。

View File

@@ -9,7 +9,9 @@ use SPC\command\BuildLibsCommand;
use SPC\command\DeleteDownloadCommand;
use SPC\command\dev\AllExtCommand;
use SPC\command\dev\ExtVerCommand;
use SPC\command\dev\GenerateExtDepDocsCommand;
use SPC\command\dev\GenerateExtDocCommand;
use SPC\command\dev\GenerateLibDepDocsCommand;
use SPC\command\dev\LibVerCommand;
use SPC\command\dev\PackLibCommand;
use SPC\command\dev\PhpVerCommand;
@@ -28,7 +30,7 @@ use Symfony\Component\Console\Application;
*/
final class ConsoleApplication extends Application
{
public const VERSION = '2.3.2';
public const VERSION = '2.3.3';
public function __construct()
{
@@ -55,6 +57,8 @@ final class ConsoleApplication extends Application
new ExtVerCommand(),
new SortConfigCommand(),
new GenerateExtDocCommand(),
new GenerateExtDepDocsCommand(),
new GenerateLibDepDocsCommand(),
new PackLibCommand(),
]
);

View File

@@ -7,6 +7,7 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\SourcePatcher;
use SPC\util\CustomExt;
#[CustomExt('opcache')]
@@ -23,6 +24,24 @@ class opcache extends Extension
}
}
public function patchBeforeBuildconf(): bool
{
if (file_exists(SOURCE_PATH . '/php-src/.opcache_patched')) {
return false;
}
// if 8.2.0 <= PHP_VERSION < 8.2.23, we need to patch from legacy patch file
if (version_compare($this->builder->getPHPVersion(), '8.2.0', '>=') && version_compare($this->builder->getPHPVersion(), '8.2.23', '<')) {
SourcePatcher::patchFile('spc_fix_static_opcache_before_80222.patch', SOURCE_PATH . '/php-src');
}
// if 8.3.0 <= PHP_VERSION < 8.3.11, we need to patch from legacy patch file
elseif (version_compare($this->builder->getPHPVersion(), '8.3.0', '>=') && version_compare($this->builder->getPHPVersion(), '8.3.11', '<')) {
SourcePatcher::patchFile('spc_fix_static_opcache_before_80310.patch', SOURCE_PATH . '/php-src');
} else {
SourcePatcher::patchMicro(items: ['static_opcache']);
}
return file_put_contents(SOURCE_PATH . '/php-src/.opcache_patched', '1') !== false;
}
public function getUnixConfigureArg(): string
{
return '--enable-opcache';

View File

@@ -52,7 +52,7 @@ class imap extends LinuxLibraryBase
->exec('chmod +x src/osdep/unix/drivers')
->exec('chmod +x src/osdep/unix/mkauths')
->exec(
"yes | make slx {$ssl_options}"
"yes | make slx {$ssl_options} EXTRACFLAGS='-fPIC -fpermissive'"
);
try {
shell()

View File

@@ -34,6 +34,7 @@ class DownloadCommand extends BaseCommand
$this->addOption('clean', null, null, 'Clean old download cache and source before fetch');
$this->addOption('all', 'A', null, 'Fetch all sources that static-php-cli needed');
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');
$this->addOption('custom-git', 'G', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source git url, e.g "php-src:master:https://github.com/php/php-src.git"');
$this->addOption('from-zip', 'Z', InputOption::VALUE_REQUIRED, 'Fetch from zip archive');
$this->addOption('for-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"');
$this->addOption('for-libs', 'l', InputOption::VALUE_REQUIRED, 'Fetch by libraries, e.g "libcares,openssl,onig"');
@@ -123,10 +124,15 @@ class DownloadCommand extends BaseCommand
// Define PHP major version
$ver = $this->php_major_ver = $this->getOption('with-php') ?? '8.1';
define('SPC_BUILD_PHP_VERSION', $ver);
// match x.y
preg_match('/^\d+\.\d+$/', $ver, $matches);
if (!$matches) {
logger()->error("bad version arg: {$ver}, x.y required!");
return static::FAILURE;
// match x.y.z
preg_match('/^\d+\.\d+\.\d+$/', $ver, $matches);
if (!$matches) {
logger()->error("bad version arg: {$ver}, x.y or x.y.z required!");
return static::FAILURE;
}
}
// retry
@@ -174,6 +180,12 @@ class DownloadCommand extends BaseCommand
[$source_name, $url] = explode(':', $value, 2);
$custom_urls[$source_name] = $url;
}
// Process -G options
$custom_gits = [];
foreach ($this->input->getOption('custom-git') as $value) {
[$source_name, $branch, $url] = explode(':', $value, 3);
$custom_gits[$source_name] = [$branch, $url];
}
// If passing --prefer-pre-built option, we need to load pre-built library list from pre-built.json targeted releases
if ($this->getOption('prefer-pre-built')) {
@@ -206,6 +218,18 @@ class DownloadCommand extends BaseCommand
}
logger()->info("Fetching source {$source} from custom url [{$ni}/{$cnt}]");
Downloader::downloadSource($source, $new_config, true);
} elseif (isset($custom_gits[$source])) {
$config = Config::getSource($source);
$new_config = [
'type' => 'git',
'rev' => $custom_gits[$source][0],
'url' => $custom_gits[$source][1],
];
if (isset($config['path'])) {
$new_config['path'] = $config['path'];
}
logger()->info("Fetching source {$source} from custom git [{$ni}/{$cnt}]");
Downloader::downloadSource($source, $new_config, true);
} else {
$config = Config::getSource($source);
// Prefer pre-built, we need to search pre-built library

View File

@@ -32,8 +32,12 @@ class SwitchPhpVersionCommand extends BaseCommand
{
$php_ver = $this->input->getArgument('php-major-version');
if (!in_array($php_ver, ['7.4', '8.0', '8.1', '8.2', '8.3'])) {
$this->output->writeln('<error>Invalid PHP major version ' . $php_ver . ' !</error>');
return static::FAILURE;
// match x.y.z
preg_match('/^\d+\.\d+\.\d+$/', $php_ver, $matches);
if (!$matches) {
$this->output->writeln('<error>Invalid PHP version ' . $php_ver . ' !</error>');
return static::FAILURE;
}
}
// detect if downloads/.lock.json exists

View File

@@ -0,0 +1,166 @@
<?php
declare(strict_types=1);
namespace SPC\command\dev;
use SPC\command\BaseCommand;
use SPC\store\FileSystem;
use SPC\util\ConfigValidator;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand('dev:gen-ext-dep-docs', 'Generate ext dependency map markdown', [], true)]
class GenerateExtDepDocsCommand extends BaseCommand
{
protected bool $no_motd = true;
public function handle(): int
{
// Get ext.json
$exts = json_decode(FileSystem::readFile(ROOT_DIR . '/config/ext.json'), true);
ConfigValidator::validateExts($exts);
// Markdown table needs format, we need to calculate the max length of each column
$content = '';
// Calculate table column max length
$max_linux = [0, 20, 19, 20, 19];
$max_macos = [0, 20, 19, 20, 19];
$max_windows = [0, 20, 19, 20, 19];
$max_freebsd = [0, 20, 19, 20, 19];
$md_lines_linux = [];
$md_lines_macos = [];
$md_lines_windows = [];
$md_lines_freebsd = [];
foreach ($exts as $ext_name => $ext) {
$line_linux = [
"<b>{$ext_name}</b>",
implode('<br>', $ext['ext-depends-linux'] ?? $ext['ext-depends-unix'] ?? $ext['ext-depends'] ?? []),
implode('<br>', $ext['ext-suggests-linux'] ?? $ext['ext-suggests-unix'] ?? $ext['ext-suggests'] ?? []),
implode('<br>', $ext['lib-depends-linux'] ?? $ext['lib-depends-unix'] ?? $ext['lib-depends'] ?? []),
implode('<br>', $ext['lib-suggests-linux'] ?? $ext['lib-suggests-unix'] ?? $ext['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_linux, $line_linux);
if ($this->isSupported($ext, 'Linux') && !$this->isEmptyLine($line_linux)) {
$md_lines_linux[] = $line_linux;
}
$line_macos = [
"<b>{$ext_name}</b>",
implode('<br>', $ext['ext-depends-macos'] ?? $ext['ext-depends-unix'] ?? $ext['ext-depends'] ?? []),
implode('<br>', $ext['ext-suggests-macos'] ?? $ext['ext-suggests-unix'] ?? $ext['ext-suggests'] ?? []),
implode('<br>', $ext['lib-depends-macos'] ?? $ext['lib-depends-unix'] ?? $ext['lib-depends'] ?? []),
implode('<br>', $ext['lib-suggests-macos'] ?? $ext['lib-suggests-unix'] ?? $ext['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_macos, $line_macos);
if ($this->isSupported($ext, 'macOS') && !$this->isEmptyLine($line_macos)) {
$md_lines_macos[] = $line_macos;
}
$line_windows = [
"<b>{$ext_name}</b>",
implode('<br>', $ext['ext-depends-windows'] ?? $ext['ext-depends-win'] ?? $ext['ext-depends'] ?? []),
implode('<br>', $ext['ext-suggests-windows'] ?? $ext['ext-suggests-win'] ?? $ext['ext-suggests'] ?? []),
implode('<br>', $ext['lib-depends-windows'] ?? $ext['lib-depends-win'] ?? $ext['lib-depends'] ?? []),
implode('<br>', $ext['lib-suggests-windows'] ?? $ext['lib-suggests-win'] ?? $ext['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_windows, $line_windows);
if ($this->isSupported($ext, 'Windows') && !$this->isEmptyLine($line_windows)) {
$md_lines_windows[] = $line_windows;
}
$line_freebsd = [
"<b>{$ext_name}</b>",
implode('<br>', $ext['ext-depends-freebsd'] ?? $ext['ext-depends-bsd'] ?? $ext['ext-depends-unix'] ?? $ext['ext-depends'] ?? []),
implode('<br>', $ext['ext-suggests-freebsd'] ?? $ext['ext-suggests-bsd'] ?? $ext['ext-suggests-unix'] ?? $ext['ext-suggests'] ?? []),
implode('<br>', $ext['lib-depends-freebsd'] ?? $ext['lib-depends-bsd'] ?? $ext['lib-depends-unix'] ?? $ext['lib-depends'] ?? []),
implode('<br>', $ext['lib-suggests-freebsd'] ?? $ext['lib-suggests-bsd'] ?? $ext['lib-suggests-unix'] ?? $ext['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_freebsd, $line_freebsd);
if ($this->isSupported($ext, 'BSD') && !$this->isEmptyLine($line_freebsd)) {
$md_lines_freebsd[] = $line_freebsd;
}
}
// Generate markdown
if (!empty($md_lines_linux)) {
$content .= "### Linux\n\n";
$content .= '| ';
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
// 生成首行
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_linux[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_linux[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_linux as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_linux[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
if (!empty($md_lines_macos)) {
$content .= "\n\n### macOS\n\n";
$content .= '| ';
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
// 生成首行
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_macos[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_macos[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_macos as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_macos[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
if (!empty($md_lines_windows)) {
$content .= "\n\n### Windows\n\n";
$content .= '| ';
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
// 生成首行
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_windows[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_windows[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_windows as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_windows[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
if (!empty($md_lines_freebsd)) {
$content .= "\n\n### FreeBSD\n\n";
$content .= '| ';
$pads = ['Extension Name', 'Required Extensions', 'Suggested Extensions', 'Required Libraries', 'Suggested Libraries'];
// 生成首行
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_freebsd[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
// 生成第二行表格分割符 | --- | --- | --- | --- | --- |
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_freebsd[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_freebsd as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_freebsd[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
$this->output->writeln($content);
return static::SUCCESS;
}
private function applyMaxLen(array &$max, array $lines): void
{
foreach ($max as $k => $v) {
$max[$k] = max($v, strlen($lines[$k]));
}
}
private function isSupported(array $ext, string $os): bool
{
return !in_array($ext['support'][$os] ?? 'yes', ['no', 'wip']);
}
private function isEmptyLine(array $line): bool
{
return $line[1] === '' && $line[2] === '' && $line[3] === '' && $line[4] === '';
}
}

View File

@@ -0,0 +1,172 @@
<?php
declare(strict_types=1);
namespace SPC\command\dev;
use SPC\command\BaseCommand;
use SPC\store\Config;
use SPC\store\FileSystem;
use SPC\util\ConfigValidator;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand('dev:gen-lib-dep-docs', 'Generate lib dependency map markdown', [], true)]
class GenerateLibDepDocsCommand extends BaseCommand
{
protected bool $no_motd = true;
protected array $support_lib_list = [];
public function handle(): int
{
foreach (['linux', 'macos', 'windows', 'freebsd'] as $os) {
$this->support_lib_list[$os] = [];
$classes = FileSystem::getClassesPsr4(
FileSystem::convertPath(ROOT_DIR . '/src/SPC/builder/' . $os . '/library'),
'SPC\builder\\' . $os . '\library'
);
foreach ($classes as $class) {
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {
$this->support_lib_list[$os][$class::NAME] = $class;
}
}
}
// Get lib.json
$libs = json_decode(FileSystem::readFile(ROOT_DIR . '/config/lib.json'), true);
ConfigValidator::validateLibs($libs);
// Markdown table needs format, we need to calculate the max length of each column
$content = '';
// Calculate table column max length
$max_linux = [0, 20, 19];
$max_macos = [0, 20, 19];
$max_windows = [0, 20, 19];
$max_freebsd = [0, 20, 19];
$md_lines_linux = [];
$md_lines_macos = [];
$md_lines_windows = [];
$md_lines_freebsd = [];
foreach ($libs as $lib_name => $lib) {
$line_linux = [
"<b>{$lib_name}</b>",
implode('<br>', $lib['lib-depends-linux'] ?? $lib['lib-depends-unix'] ?? $lib['lib-depends'] ?? []),
implode('<br>', $lib['lib-suggests-linux'] ?? $lib['lib-suggests-unix'] ?? $lib['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_linux, $line_linux);
if ($this->isSupported($lib_name, 'linux') && !$this->isEmptyLine($line_linux)) {
$md_lines_linux[] = $line_linux;
}
$line_macos = [
"<b>{$lib_name}</b>",
implode('<br>', $lib['lib-depends-macos'] ?? $lib['lib-depends-unix'] ?? $lib['lib-depends'] ?? []),
implode('<br>', $lib['lib-suggests-macos'] ?? $lib['lib-suggests-unix'] ?? $lib['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_macos, $line_macos);
if ($this->isSupported($lib_name, 'macos') && !$this->isEmptyLine($line_macos)) {
$md_lines_macos[] = $line_macos;
}
$line_windows = [
"<b>{$lib_name}</b>",
implode('<br>', $lib['lib-depends-windows'] ?? $lib['lib-depends-win'] ?? $lib['lib-depends'] ?? []),
implode('<br>', $lib['lib-suggests-windows'] ?? $lib['lib-suggests-win'] ?? $lib['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_windows, $line_windows);
if ($this->isSupported($lib_name, 'windows') && !$this->isEmptyLine($line_windows)) {
$md_lines_windows[] = $line_windows;
}
$line_freebsd = [
"<b>{$lib_name}</b>",
implode('<br>', $lib['lib-depends-freebsd'] ?? $lib['lib-depends-bsd'] ?? $lib['lib-depends-unix'] ?? $lib['lib-depends'] ?? []),
implode('<br>', $lib['lib-suggests-freebsd'] ?? $lib['lib-suggests-bsd'] ?? $lib['lib-suggests-unix'] ?? $lib['lib-suggests'] ?? []),
];
$this->applyMaxLen($max_freebsd, $line_freebsd);
if ($this->isSupported($lib_name, 'freebsd') && !$this->isEmptyLine($line_freebsd)) {
$md_lines_freebsd[] = $line_freebsd;
}
}
// Generate markdown
if (!empty($md_lines_linux)) {
$content .= "### Linux\n\n";
$content .= '| ';
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_linux[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_linux[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_linux as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_linux[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
if (!empty($md_lines_macos)) {
$content .= "### macOS\n\n";
$content .= '| ';
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_macos[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_macos[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_macos as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_macos[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
if (!empty($md_lines_windows)) {
$content .= "### Windows\n\n";
$content .= '| ';
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_windows[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_windows[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_windows as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_windows[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
if (!empty($md_lines_freebsd)) {
$content .= "### FreeBSD\n\n";
$content .= '| ';
$pads = ['Library Name', 'Required Libraries', 'Suggested Libraries'];
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad($pad, $max_freebsd[$i]), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
$content .= '| ';
$content .= implode(' | ', array_map(fn ($i, $pad) => str_pad('', $max_freebsd[$i], '-'), array_keys($pads), $pads));
$content .= ' |' . PHP_EOL;
foreach ($md_lines_freebsd as $line) {
$content .= '| ' . implode(' | ', array_map(fn ($i, $pad) => str_pad($line[$i], $max_freebsd[$i]), array_keys($line), $line)) . ' |' . PHP_EOL;
}
}
$this->output->writeln($content);
return static::SUCCESS;
}
private function applyMaxLen(array &$max, array $lines): void
{
foreach ($max as $k => $v) {
$max[$k] = max($v, strlen($lines[$k]));
}
}
private function isSupported(string $ext_name, string $os): bool
{
if (!in_array($os, ['linux', 'macos', 'freebsd', 'windows'])) {
throw new \InvalidArgumentException('Invalid os: ' . $os);
}
return isset($this->support_lib_list[$os][$ext_name]);
}
private function isEmptyLine(array $line): bool
{
return $line[1] === '' && $line[2] === '';
}
}

View File

@@ -88,7 +88,7 @@ class SourcePatcher
* @throws RuntimeException
* @throws FileSystemException
*/
public static function patchMicro(): bool
public static function patchMicro(string $name = '', string $target = '', ?array $items = null): bool
{
if (!file_exists(SOURCE_PATH . '/php-src/sapi/micro/php_micro.c')) {
return false;
@@ -108,22 +108,13 @@ class SourcePatcher
// $check = !defined('DEBUG_MODE') ? ' -q' : '';
// f_passthru('cd ' . SOURCE_PATH . '/php-src && git checkout' . $check . ' HEAD');
$default = [
'static_opcache',
'static_extensions_win32',
'cli_checks',
'disable_huge_page',
'vcruntime140',
'win32',
'zend_stream',
];
if (PHP_OS_FAMILY === 'Windows') {
$default[] = 'cli_static';
if ($items !== null) {
$spc_micro_patches = $items;
} else {
$spc_micro_patches = getenv('SPC_MICRO_PATCHES');
$spc_micro_patches = $spc_micro_patches === false ? [] : explode(',', $spc_micro_patches);
}
if (PHP_OS_FAMILY === 'Darwin') {
$default[] = 'macos_iconv';
}
$patch_list = $default;
$patch_list = $spc_micro_patches;
$patches = [];
$serial = ['80', '81', '82', '83', '84'];
foreach ($patch_list as $patchName) {
@@ -142,12 +133,14 @@ class SourcePatcher
throw new RuntimeException("failed finding patch {$patchName}");
}
$patchesStr = str_replace('/', DIRECTORY_SEPARATOR, implode(' ', $patches));
f_passthru(
'cd ' . SOURCE_PATH . '/php-src && ' .
(PHP_OS_FAMILY === 'Windows' ? 'type' : 'cat') . ' ' . $patchesStr . ' | patch -p1 '
);
foreach ($patches as $patch) {
logger()->info("Patching micro with {$patch}");
$patchesStr = str_replace('/', DIRECTORY_SEPARATOR, $patch);
f_passthru(
'cd ' . SOURCE_PATH . '/php-src && ' .
(PHP_OS_FAMILY === 'Windows' ? 'type' : 'cat') . ' ' . $patchesStr . ' | patch -p1 '
);
}
return true;
}
@@ -205,6 +198,19 @@ class SourcePatcher
'PHP_ADD_INCLUDE([$ext_srcdir])',
"PHP_ADD_INCLUDE( [\$ext_srcdir] )\n PHP_ADD_INCLUDE([\$abs_srcdir/ext])"
);
// swoole 5.1.3 build fix
// get swoole version first
$file = SOURCE_PATH . '/php-src/ext/swoole/include/swoole_version.h';
// Match #define SWOOLE_VERSION "5.1.3"
$pattern = '/#define SWOOLE_VERSION "(.+)"/';
if (preg_match($pattern, file_get_contents($file), $matches)) {
$version = $matches[1];
} else {
$version = '1.0.0';
}
if ($version === '5.1.3') {
self::patchFile('spc_fix_swoole_50513.patch', SOURCE_PATH . '/php-src/ext/swoole');
}
return true;
}
@@ -401,14 +407,17 @@ class SourcePatcher
if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0) {
$ver_id = intval($match[1]);
if ($ver_id < 80000) {
return false;
self::patchFile('spc_fix_alpine_build_php80.patch', SOURCE_PATH . '/php-src');
return true;
}
if ($ver_id < 80100) {
self::patchFile('spc_fix_libxml2_12_php80.patch', SOURCE_PATH . '/php-src');
self::patchFile('spc_fix_alpine_build_php80.patch', SOURCE_PATH . '/php-src');
return true;
}
if ($ver_id < 80200) {
self::patchFile('spc_fix_libxml2_12_php81.patch', SOURCE_PATH . '/php-src');
self::patchFile('spc_fix_alpine_build_php80.patch', SOURCE_PATH . '/php-src');
return true;
}
return false;

View File

@@ -64,6 +64,7 @@ class GlobalEnvManager
// Windows need php-sdk binary tools
self::initIfNotExists('PHP_SDK_PATH', WORKING_DIR . DIRECTORY_SEPARATOR . 'php-sdk-binary-tools');
self::initIfNotExists('UPX_EXEC', PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'upx.exe');
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static');
}
private static function initLinuxEnv(BuilderBase $builder): void
@@ -90,6 +91,9 @@ class GlobalEnvManager
self::initIfNotExists('SPC_DEFAULT_CXX_FLAGS', '');
self::initIfNotExists('SPC_EXTRA_LIBS', '');
// SPC_MICRO_PATCHES for linux
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream');
// Init linux-only env
self::initIfNotExists('UPX_EXEC', PKG_ROOT_PATH . '/bin/upx');
self::initIfNotExists('GNU_ARCH', arch2gnu(php_uname('m')));
@@ -140,6 +144,9 @@ class GlobalEnvManager
// Init extra libs (will be appended before `before-php-buildconf` event point)
self::initIfNotExists('SPC_EXTRA_LIBS', '');
// SPC_MICRO_PATCHES for macOS
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,macos_iconv');
$init_spc_cmd_maps = [
// Init default build command prefix
'SPC_CMD_PREFIX_PHP_BUILDCONF' => './buildconf --force',

View File

@@ -0,0 +1,28 @@
diff --git a/main/streams/cast.c b/main/streams/cast.c
index 0978ca4d..677fc6dc 100644
--- a/main/streams/cast.c
+++ b/main/streams/cast.c
@@ -102,6 +102,9 @@ static ssize_t stream_cookie_writer(void *cookie, const char *buffer, size_t siz
# ifdef COOKIE_SEEKER_USES_OFF64_T
static int stream_cookie_seeker(void *cookie, off64_t *position, int whence)
+# else
+static int stream_cookie_seeker(void *cookie, off_t *position, int whence)
+# endif
{
*position = php_stream_seek((php_stream *)cookie, (zend_off_t)*position, whence);
@@ -111,13 +114,6 @@ static int stream_cookie_seeker(void *cookie, off64_t *position, int whence)
}
return 0;
}
-# else
-static int stream_cookie_seeker(void *cookie, zend_off_t position, int whence)
-{
-
- return php_stream_seek((php_stream *)cookie, position, whence);
-}
-# endif
static int stream_cookie_closer(void *cookie)
{

View File

@@ -0,0 +1,129 @@
diff --git a/build/order_by_dep.awk b/build/order_by_dep.awk
index 1e71ea2069..3da32d8830 100644
--- a/build/order_by_dep.awk
+++ b/build/order_by_dep.awk
@@ -37,6 +37,11 @@ function get_module_index(name, i)
function do_deps(mod_idx, module_name, mod_name_len, dep, ext, val, depidx)
{
module_name = mods[mod_idx];
+ # TODO: real skip zend extension
+ if (module_name == "opcache") {
+ delete mods[mod_idx];
+ return;
+ }
mod_name_len = length(module_name);
for (ext in mod_deps) {
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 5f6b854d47..ea15c0d5bc 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -91,7 +91,10 @@ typedef int gid_t;
#include <immintrin.h>
#endif
+#ifdef COMPILE_DL_OPCACHE
+// avoid symbol conflict
ZEND_EXTENSION();
+#endif
#ifndef ZTS
zend_accel_globals accel_globals;
@@ -4808,7 +4811,11 @@ static int accel_finish_startup(void)
return SUCCESS;
}
+#ifdef COMPILE_DL_OPCACHE
ZEND_EXT_API zend_extension zend_extension_entry = {
+#else
+zend_extension opcache_zend_extension_entry = {
+#endif
ACCELERATOR_PRODUCT_NAME, /* name */
PHP_VERSION, /* version */
"Zend Technologies", /* author */
diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4
index 2a83fa2455..7b3b37182e 100644
--- a/ext/opcache/config.m4
+++ b/ext/opcache/config.m4
@@ -21,7 +21,8 @@ PHP_ARG_ENABLE([opcache-jit],
if test "$PHP_OPCACHE" != "no"; then
dnl Always build as shared extension
- ext_shared=yes
+ dnl why?
+ dnl ext_shared=yes
if test "$PHP_HUGE_CODE_PAGES" = "yes"; then
AC_DEFINE(HAVE_HUGE_CODE_PAGES, 1, [Define to enable copying PHP CODE pages into HUGE PAGES (experimental)])
@@ -327,7 +328,9 @@ int main() {
shared_alloc_mmap.c \
shared_alloc_posix.c \
$ZEND_JIT_SRC,
- shared,,"-Wno-implicit-fallthrough -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1",,yes)
+ $ext_shared,,"-Wno-implicit-fallthrough -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1",,yes)
+
+ AC_DEFINE(HAVE_OPCACHE, 1, [opcache enabled])
PHP_ADD_EXTENSION_DEP(opcache, pcre)
diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32
index 764a2edaab..95427090ce 100644
--- a/ext/opcache/config.w32
+++ b/ext/opcache/config.w32
@@ -16,7 +16,9 @@ if (PHP_OPCACHE != "no") {
zend_persist_calc.c \
zend_file_cache.c \
zend_shared_alloc.c \
- shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+ shared_alloc_win32.c", PHP_OPCACHE_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+
+ AC_DEFINE('HAVE_OPCACHE', 1, 'opcache enabled');
if (PHP_OPCACHE_JIT == "yes") {
if (CHECK_HEADER_ADD_INCLUDE("dynasm/dasm_x86.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) {
diff --git a/main/main.c b/main/main.c
index 8c16f01b11..0560348a06 100644
--- a/main/main.c
+++ b/main/main.c
@@ -2011,6 +2011,18 @@ void dummy_invalid_parameter_handler(
}
#endif
+// this can be moved to other place
+#if defined(HAVE_OPCACHE) && !defined(COMPILE_DL_OPCACHE)
+extern zend_extension opcache_zend_extension_entry;
+extern void zend_register_extension(zend_extension *new_extension, void *handle);
+
+int zend_load_static_extensions(void)
+{
+ zend_register_extension(&opcache_zend_extension_entry, NULL /*opcache cannot be unloaded*/);
+ return 0;
+}
+#endif
+
/* {{{ php_module_startup */
int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint32_t num_additional_modules)
{
@@ -2253,6 +2265,9 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
ahead of all other internals
*/
php_ini_register_extensions();
+#if defined(HAVE_OPCACHE) && !defined(COMPILE_DL_OPCACHE)
+ zend_load_static_extensions();
+#endif
zend_startup_modules();
/* start Zend extensions */
diff --git a/win32/build/confutils.js b/win32/build/confutils.js
index 1a2dfe43b4..ae405f035a 100644
--- a/win32/build/confutils.js
+++ b/win32/build/confutils.js
@@ -1535,6 +1535,8 @@ function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir)
}
}
+ // TODO: real skip zend extensions
+ if (extname != 'opcache')
extension_module_ptrs += '\tphpext_' + extname + '_ptr,\r\n';
DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_PHP) $(CFLAGS_' + EXT + ')');

View File

@@ -0,0 +1,129 @@
diff --git a/build/order_by_dep.awk b/build/order_by_dep.awk
index 1e71ea2069..3da32d8830 100644
--- a/build/order_by_dep.awk
+++ b/build/order_by_dep.awk
@@ -37,6 +37,11 @@ function get_module_index(name, i)
function do_deps(mod_idx, module_name, mod_name_len, dep, ext, val, depidx)
{
module_name = mods[mod_idx];
+ # TODO: real skip zend extension
+ if (module_name == "opcache") {
+ delete mods[mod_idx];
+ return;
+ }
mod_name_len = length(module_name);
for (ext in mod_deps) {
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index ec33c69eb2..b8ce7e3eca 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -93,7 +93,10 @@ typedef int gid_t;
#include <immintrin.h>
#endif
+#ifdef COMPILE_DL_OPCACHE
+// avoid symbol conflict
ZEND_EXTENSION();
+#endif
#ifndef ZTS
zend_accel_globals accel_globals;
@@ -4814,7 +4817,11 @@ static int accel_finish_startup(void)
#endif /* ZEND_WIN32 */
}
+#ifdef COMPILE_DL_OPCACHE
ZEND_EXT_API zend_extension zend_extension_entry = {
+#else
+zend_extension opcache_zend_extension_entry = {
+#endif
ACCELERATOR_PRODUCT_NAME, /* name */
PHP_VERSION, /* version */
"Zend Technologies", /* author */
diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4
index 2a83fa2455..7b3b37182e 100644
--- a/ext/opcache/config.m4
+++ b/ext/opcache/config.m4
@@ -21,7 +21,8 @@ PHP_ARG_ENABLE([opcache-jit],
if test "$PHP_OPCACHE" != "no"; then
dnl Always build as shared extension
- ext_shared=yes
+ dnl why?
+ dnl ext_shared=yes
if test "$PHP_HUGE_CODE_PAGES" = "yes"; then
AC_DEFINE(HAVE_HUGE_CODE_PAGES, 1, [Define to enable copying PHP CODE pages into HUGE PAGES (experimental)])
@@ -327,7 +328,9 @@ int main() {
shared_alloc_mmap.c \
shared_alloc_posix.c \
$ZEND_JIT_SRC,
- shared,,"-Wno-implicit-fallthrough -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1",,yes)
+ $ext_shared,,"-Wno-implicit-fallthrough -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1",,yes)
+
+ AC_DEFINE(HAVE_OPCACHE, 1, [opcache enabled])
PHP_ADD_EXTENSION_DEP(opcache, pcre)
diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32
index 764a2edaab..95427090ce 100644
--- a/ext/opcache/config.w32
+++ b/ext/opcache/config.w32
@@ -16,7 +16,9 @@ if (PHP_OPCACHE != "no") {
zend_persist_calc.c \
zend_file_cache.c \
zend_shared_alloc.c \
- shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+ shared_alloc_win32.c", PHP_OPCACHE_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+
+ AC_DEFINE('HAVE_OPCACHE', 1, 'opcache enabled');
if (PHP_OPCACHE_JIT == "yes") {
if (CHECK_HEADER_ADD_INCLUDE("dynasm/dasm_x86.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) {
diff --git a/main/main.c b/main/main.c
index 6fdfbce13e..bcccfad6e3 100644
--- a/main/main.c
+++ b/main/main.c
@@ -2012,6 +2012,18 @@ void dummy_invalid_parameter_handler(
}
#endif
+// this can be moved to other place
+#if defined(HAVE_OPCACHE) && !defined(COMPILE_DL_OPCACHE)
+extern zend_extension opcache_zend_extension_entry;
+extern void zend_register_extension(zend_extension *new_extension, void *handle);
+
+int zend_load_static_extensions(void)
+{
+ zend_register_extension(&opcache_zend_extension_entry, NULL /*opcache cannot be unloaded*/);
+ return 0;
+}
+#endif
+
/* {{{ php_module_startup */
zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_module)
{
@@ -2196,6 +2208,9 @@ zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additi
ahead of all other internals
*/
php_ini_register_extensions();
+#if defined(HAVE_OPCACHE) && !defined(COMPILE_DL_OPCACHE)
+ zend_load_static_extensions();
+#endif
zend_startup_modules();
/* start Zend extensions */
diff --git a/win32/build/confutils.js b/win32/build/confutils.js
index 359c751b7b..01068efcf6 100644
--- a/win32/build/confutils.js
+++ b/win32/build/confutils.js
@@ -1534,6 +1534,8 @@ function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir)
}
}
+ // TODO: real skip zend extensions
+ if (extname != 'opcache')
extension_module_ptrs += '\tphpext_' + extname + '_ptr,\r\n';
DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_PHP) $(CFLAGS_' + EXT + ')');

View File

@@ -0,0 +1,27 @@
diff --git a/ext-src/php_swoole_call_stack.h b/ext-src/php_swoole_call_stack.h
index 8c89f83..639a303 100644
--- a/ext-src/php_swoole_call_stack.h
+++ b/ext-src/php_swoole_call_stack.h
@@ -18,8 +18,8 @@
#ifdef ZEND_CHECK_STACK_LIMIT
#define HOOK_PHP_CALL_STACK(callback) \
- auto __stack_limit = EG(stack_limit); \
- auto __stack_base = EG(stack_base); \
+ void *__stack_limit = EG(stack_limit); \
+ void *__stack_base = EG(stack_base); \
EG(stack_base) = (void *) 0; \
EG(stack_limit) = (void *) 0; \
callback EG(stack_limit) = __stack_limit; \
diff --git a/thirdparty/php83/pdo_odbc/odbc_driver.c b/thirdparty/php83/pdo_odbc/odbc_driver.c
index c83da64..a5e3a8b 100644
--- a/thirdparty/php83/pdo_odbc/odbc_driver.c
+++ b/thirdparty/php83/pdo_odbc/odbc_driver.c
@@ -25,6 +25,7 @@
#include "pdo/php_pdo.h"
#include "pdo/php_pdo_driver.h"
#include "zend_exceptions.h"
+#include <php_odbc_utils.h>
static void pdo_odbc_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) {
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *) dbh->driver_data;

View File

@@ -19,7 +19,7 @@ $upx = true;
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
$extensions = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'iconv',
'Linux', 'Darwin' => 'imap,swoole-hook-sqlite,swoole',
'Windows' => 'igbinary,redis,session',
};