Compare commits

..

7 Commits

Author SHA1 Message Date
Jerry Ma
29efc2c5a5 Add extension gmssl support (#544)
* Add extension gmssl support

* cs-fix

* Add framework for gmssl
2024-09-20 12:32:31 +08:00
Jerry Ma
e35836943e Update FUNDING.yml 2024-09-19 21:27:24 +08:00
Jerry Ma
2beecee219 Add extension msgpack support (#543) 2024-09-17 22:34:57 +08:00
Jerry Ma
ad098d085e Update redis to 6.0.2, add alternative license file searcher (#539)
* Update redis to 6.0.2, add alternative license file searcher

* Update docs about source module
2024-09-09 17:41:29 +08:00
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
27 changed files with 581 additions and 27 deletions

4
.github/FUNDING.yml vendored
View File

@@ -3,7 +3,7 @@
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
ko_fi: crazywhalecc # 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
@@ -11,5 +11,5 @@ 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
# noinspection YAMLSchemaValidation
buy_me_a_coffee: crazywhalecc
buy_me_a_coffee: # crazywhalecc
custom: 'https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md' # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -120,8 +120,8 @@ jobs:
php:
- "8.0"
- "8.1"
- "8.2.22"
- "8.3.10"
- "8.2"
- "8.3"
os:
- ubuntu-latest
- macos-13

View File

@@ -189,6 +189,16 @@
"gmp"
]
},
"gmssl": {
"support": {
"BSD": "wip"
},
"type": "external",
"source": "ext-gmssl",
"lib-depends": [
"gmssl"
]
},
"iconv": {
"support": {
"BSD": "wip"
@@ -360,6 +370,15 @@
"zlib"
]
},
"msgpack": {
"support": {
"BSD": "wip"
},
"type": "external",
"source": "msgpack",
"arg-type-unix": "with",
"arg-type-win": "enable"
},
"mysqli": {
"type": "builtin",
"arg-type": "with",

View File

@@ -127,6 +127,18 @@
"gmp.h"
]
},
"gmssl": {
"source": "gmssl",
"static-libs-unix": [
"libgmssl.a"
],
"static-libs-windows": [
"gmssl.lib"
],
"frameworks": [
"Security"
]
},
"icu": {
"source": "icu",
"cpp-library": true,

View File

@@ -83,6 +83,15 @@
"path": "LICENSE"
}
},
"ext-gmssl": {
"type": "ghtar",
"repo": "gmssl/GmSSL-PHP",
"path": "php-src/ext/gmssl",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-imagick": {
"type": "url",
"url": "https://pecl.php.net/get/imagick",
@@ -194,6 +203,14 @@
"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."
}
},
"gmssl": {
"type": "ghtar",
"repo": "guanzhi/GmSSL",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"icu": {
"type": "ghrel",
"repo": "unicode-org/icu",
@@ -497,7 +514,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"
@@ -514,6 +531,16 @@
"path": "LICENSE"
}
},
"msgpack": {
"type": "url",
"url": "https://pecl.php.net/get/msgpack",
"path": "php-src/ext/msgpack",
"filename": "msgpack.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ncurses": {
"type": "filelist",
"url": "https://ftp.gnu.org/pub/gnu/ncurses/",
@@ -649,11 +676,14 @@
"redis": {
"type": "git",
"path": "php-src/ext/redis",
"rev": "5.3.7",
"rev": "release/6.0.2",
"url": "https://github.com/phpredis/phpredis",
"license": {
"type": "file",
"path": "COPYING"
"path": [
"LICENSE",
"COPYING"
]
}
},
"snappy": {

View File

@@ -317,3 +317,24 @@ When an open source project has multiple licenses, multiple files can be specifi
}
}
```
When the license of an open source project uses different files between versions,
`path` can be used as an array to list the possible license files:
```json
{
"redis": {
"type": "git",
"path": "php-src/ext/redis",
"rev": "release/6.0.2",
"url": "https://github.com/phpredis/phpredis",
"license": {
"type": "file",
"path": [
"LICENSE",
"COPYING"
]
}
}
}
```

View File

@@ -48,7 +48,7 @@ These environment variables are system-specific and will only take effect on a s
|---------------------|-----------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
| `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_opcache,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) |
| `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
@@ -66,7 +66,7 @@ These environment variables are system-specific and will only take effect on a s
| `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_opcache,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) |
| `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
@@ -92,7 +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_opcache,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) |
| `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

@@ -204,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,

View File

@@ -297,3 +297,23 @@ pkg.json 存放的是非源码类型的文件资源,例如 musl-toolchain、UP
}
}
```
当一个开源项目的许可证在不同版本间使用不同的文件,`path` 参数可以使用数组将可能的许可证文件列出:
```json
{
"redis": {
"type": "git",
"path": "php-src/ext/redis",
"rev": "release/6.0.2",
"url": "https://github.com/phpredis/phpredis",
"license": {
"type": "file",
"path": [
"LICENSE",
"COPYING"
]
}
}
}
```

View File

@@ -46,7 +46,7 @@ SPC_CONCURRENCY=4 bin/spc build mbstring,pcntl --build-cli
|---------------------|-----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| `PHP_SDK_PATH` | `{pwd}\php-sdk-binary-tools` | PHP SDK 工具的安装目录 |
| `UPX_EXEC` | `$PKG_ROOT_PATH\bin\upx.exe` | UPX 压缩工具的路径 |
| `SPC_MICRO_PATCHES` | `static_opcache,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) |
| `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
@@ -64,7 +64,7 @@ SPC_CONCURRENCY=4 bin/spc build mbstring,pcntl --build-cli
| `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_opcache,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) |
| `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
@@ -90,7 +90,7 @@ SPC_CONCURRENCY=4 bin/spc build mbstring,pcntl --build-cli
| `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_opcache,static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream` | 使用的 phpmicro [patches](https://github.com/easysoft/phpmicro/blob/master/patches/Readme.md) |
| `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`。

View File

@@ -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

@@ -30,7 +30,7 @@ use Symfony\Component\Console\Application;
*/
final class ConsoleApplication extends Application
{
public const VERSION = '2.3.3';
public const VERSION = '2.3.4';
public function __construct()
{

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('gmssl')]
class gmssl extends Extension
{
public function patchBeforeBuildconf(): bool
{
if (str_contains(file_get_contents(SOURCE_PATH . '/php-src/ext/gmssl/config.w32'), 'CHECK_LIB(')) {
return false;
}
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/gmssl/config.w32', 'AC_DEFINE(', 'CHECK_LIB("gmssl.lib", "gmssl", PHP_GMSSL);' . PHP_EOL . 'AC_DEFINE(');
return true;
}
}

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

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class gmssl extends LinuxLibraryBase
{
use \SPC\builder\unix\library\gmssl;
public const NAME = 'gmssl';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class gmssl extends MacOSLibraryBase
{
use \SPC\builder\unix\library\gmssl;
public const NAME = 'gmssl';
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait gmssl
{
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
// CMake needs a clean build directory
FileSystem::resetDir($this->source_dir . '/build');
// Start build
shell()->cd($this->source_dir . '/build')
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF ..")
->execWithEnv("cmake --build . -j {$this->builder->concurrency}")
->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH);
}
}

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class gmssl extends WindowsLibraryBase
{
public const NAME = 'gmssl';
protected function build(): void
{
// reset cmake
FileSystem::resetDir($this->source_dir . '\builddir');
// start build
cmd()->cd($this->source_dir . '\builddir')
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake .. -G "NMake Makefiles" -DWIN32=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" -DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" -DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH),
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH
);
FileSystem::writeFile($this->source_dir . '\builddir\cmake_install.cmake', 'set(CMAKE_INSTALL_PREFIX "' . str_replace('\\', '/', BUILD_ROOT_PATH) . '")' . PHP_EOL . FileSystem::readFile($this->source_dir . '\builddir\cmake_install.cmake'));
cmd()->cd($this->source_dir . '\builddir')
->execWithWrapper(
$this->builder->makeSimpleWrapper('nmake'),
'install XCFLAGS=/MT'
);
}
}

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"');
@@ -179,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')) {
@@ -211,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

@@ -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,8 +108,12 @@ class SourcePatcher
// $check = !defined('DEBUG_MODE') ? ' -q' : '';
// f_passthru('cd ' . SOURCE_PATH . '/php-src && git checkout' . $check . ' HEAD');
$spc_micro_patches = getenv('SPC_MICRO_PATCHES');
$spc_micro_patches = $spc_micro_patches === false ? [] : explode(',', $spc_micro_patches);
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);
}
$patch_list = $spc_micro_patches;
$patches = [];
$serial = ['80', '81', '82', '83', '84'];

View File

@@ -64,7 +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_opcache,static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static');
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
@@ -92,7 +92,7 @@ class GlobalEnvManager
self::initIfNotExists('SPC_EXTRA_LIBS', '');
// SPC_MICRO_PATCHES for linux
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_opcache,static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream');
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');
@@ -145,7 +145,7 @@ class GlobalEnvManager
self::initIfNotExists('SPC_EXTRA_LIBS', '');
// SPC_MICRO_PATCHES for macOS
self::initIfNotExists('SPC_MICRO_PATCHES', 'static_opcache,static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,macos_iconv');
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

View File

@@ -118,20 +118,26 @@ class LicenseDumper
/**
* @throws RuntimeException
*/
private function loadSourceFile(string $source_name, int $index, ?string $in_path, ?string $custom_base_path = null): string
private function loadSourceFile(string $source_name, int $index, null|array|string $in_path, ?string $custom_base_path = null): string
{
if (is_null($in_path)) {
throw new RuntimeException('source [' . $source_name . '] license file is not set, please check config/source.json');
}
if (file_exists(SOURCE_PATH . '/' . ($custom_base_path ?? $source_name) . '/' . $in_path)) {
return file_get_contents(SOURCE_PATH . '/' . ($custom_base_path ?? $source_name) . '/' . $in_path);
if (!is_array($in_path)) {
$in_path = [$in_path];
}
foreach ($in_path as $item) {
if (file_exists(SOURCE_PATH . '/' . ($custom_base_path ?? $source_name) . '/' . $item)) {
return file_get_contents(SOURCE_PATH . '/' . ($custom_base_path ?? $source_name) . '/' . $item);
}
}
if (file_exists(BUILD_ROOT_PATH . '/source-licenses/' . $source_name . '/' . $index . '.txt')) {
return file_get_contents(BUILD_ROOT_PATH . '/source-licenses/' . $source_name . '/' . $index . '.txt');
}
throw new RuntimeException('source [' . $source_name . '] license file [' . $in_path . '] not exist');
throw new RuntimeException('Cannot find any license file in source [' . $source_name . '] directory!');
}
}

View File

@@ -0,0 +1,8 @@
<?php
declare(strict_types=1);
assert(function_exists('gmssl_rand_bytes'));
assert(function_exists('gmssl_sm3'));
assert(bin2hex(gmssl_sm3('123456')) === '207cf410532f92a47dee245ce9b11ff71f578ebd763eb3bbea44ebd043d018fb');

View File

@@ -0,0 +1,7 @@
<?php
declare(strict_types=1);
assert(function_exists('msgpack_pack'));
assert(function_exists('msgpack_unpack'));
assert(msgpack_unpack(msgpack_pack(['foo', 'bar'])) === ['foo', 'bar']);

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

@@ -19,13 +19,13 @@ $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' => 'imap,swoole-hook-sqlite,swoole',
'Windows' => 'igbinary,redis,session',
'Linux', 'Darwin' => 'gmssl',
'Windows' => 'gmssl',
};
// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`).
$with_libs = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => '',
'Linux', 'Darwin' => 'liblz4',
'Windows' => '',
};