mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-03 06:45:39 +08:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
460238a6b0 | ||
|
|
2a197487d5 | ||
|
|
51ce2befd8 | ||
|
|
e909dd15b0 | ||
|
|
aaf712be3c | ||
|
|
725e6b25dc | ||
|
|
ea322c0d3b | ||
|
|
f7730735c0 | ||
|
|
752b88f62d | ||
|
|
6131e1881b | ||
|
|
980da4ea0f | ||
|
|
b698ae2f50 | ||
|
|
50632f6527 | ||
|
|
6d4755d8c9 | ||
|
|
75b85c26dc | ||
|
|
1c8bbfbbdf | ||
|
|
c5a70f101a | ||
|
|
956c87a657 | ||
|
|
778b0eadcd | ||
|
|
b8e6f9d1be | ||
|
|
0e024a8c43 | ||
|
|
65b0bd01c8 | ||
|
|
3745dfc931 | ||
|
|
0186ae5ff2 | ||
|
|
f1eacac4fd | ||
|
|
4abe0064e6 | ||
|
|
cbc3adbec0 | ||
|
|
0902f80b46 | ||
|
|
47101d058b | ||
|
|
bc978ecbde | ||
|
|
a2cb5165d3 | ||
|
|
e582fa8b22 | ||
|
|
8ec8838634 | ||
|
|
8f259ffed9 | ||
|
|
74c2cf824b | ||
|
|
9ea3b04e82 | ||
|
|
99cb8c77b7 | ||
|
|
7056280c57 | ||
|
|
c14421c9ca | ||
|
|
085437e925 | ||
|
|
fa17a48483 | ||
|
|
78c1484570 | ||
|
|
9c2ea79bec | ||
|
|
b7ffe3fd1f | ||
|
|
dac14ae16e |
9
.github/workflows/build-linux-x86_64.yml
vendored
9
.github/workflows/build-linux-x86_64.yml
vendored
@@ -77,10 +77,10 @@ jobs:
|
||||
|
||||
# If there's no dependencies cache, fetch sources, with or without debug
|
||||
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||
run: CACHE_API_EXEC=yes ./bin/spc download --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
|
||||
run: CACHE_API_EXEC=yes ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
|
||||
|
||||
# Run build command
|
||||
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||
- run: ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
@@ -115,8 +115,3 @@ jobs:
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
|
||||
# Upload downloaded files
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: download-files
|
||||
path: downloads/
|
||||
|
||||
5
.github/workflows/build-macos-x86_64.yml
vendored
5
.github/workflows/build-macos-x86_64.yml
vendored
@@ -115,8 +115,3 @@ jobs:
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
|
||||
# Upload downloaded files
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: download-files
|
||||
path: downloads/
|
||||
|
||||
17
README-en.md
17
README-en.md
@@ -11,14 +11,16 @@ This feature is provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro
|
||||
|
||||
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
|
||||
> The project has renamed the `refactor` branch to the `main` branch, please pay attention to changing the branch name for dependent projects.
|
||||
|
||||
## Compilation Requirements
|
||||
|
||||
Yes, this project is written in PHP, pretty funny.
|
||||
@@ -223,6 +225,11 @@ The basic principles for contributing are as follows:
|
||||
|
||||
If you want to contribute document content, please go to [crazywhalecc/static-php-cli-docs](https://github.com/crazywhalecc/static-php-cli-docs).
|
||||
|
||||
Part of the English document is written by me, and part is translated by Google,
|
||||
and there may be inaccurate descriptions, strange or offensive expressions.
|
||||
If you are a native English speaker, some corrections to the documentation are welcome.
|
||||
|
||||
|
||||
## Sponsor this project
|
||||
|
||||
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
|
||||
@@ -244,6 +251,6 @@ and comply with the corresponding project's LICENSE.
|
||||
|
||||
## Advanced
|
||||
|
||||
This project is pure open source project, and some modules are separated for developing.
|
||||
|
||||
This section will be improved after refactor version released.
|
||||
The refactoring branch of this project is written modularly.
|
||||
If you are interested in this project and want to join the development,
|
||||
you can refer to the [Contribution Guide](https://static-php-cli.zhamao.me) of the documentation to contribute code or documentation. (TODO)
|
||||
|
||||
12
README.md
12
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
Compile A Statically Linked PHP With Swoole and other Extensions.
|
||||
|
||||
If you are using English, see [English README](README-en.md).
|
||||
**If you are using English, see [English README](README-en.md).**
|
||||
|
||||
编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携!(cli SAPI)
|
||||
|
||||
@@ -12,13 +12,15 @@ If you are using English, see [English README](README-en.md).
|
||||
|
||||
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
|
||||
> 项目已重命名 `refactor` 分支为 `main` 分支,请依赖的项目注意更改分支名称。
|
||||
|
||||
## 编译环境需求
|
||||
|
||||
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
||||
@@ -222,6 +224,4 @@ cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
|
||||
## 进阶
|
||||
|
||||
本项目重构分支为模块化编写。
|
||||
|
||||
TODO:这部分将在基础功能完成后编写完成。
|
||||
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php-cli.zhamao.me) 贡献代码或文档。(TODO)
|
||||
|
||||
@@ -53,6 +53,19 @@
|
||||
"sockets"
|
||||
]
|
||||
},
|
||||
"memcached": {
|
||||
"type": "external",
|
||||
"source": "memcached",
|
||||
"arg-type": "custom",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"libmemcached"
|
||||
],
|
||||
"ext-depends": [
|
||||
"session",
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"exif": {
|
||||
"type": "builtin"
|
||||
},
|
||||
@@ -138,6 +151,7 @@
|
||||
},
|
||||
"intl": {
|
||||
"type": "builtin",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"icu"
|
||||
]
|
||||
@@ -151,8 +165,9 @@
|
||||
},
|
||||
"mbregex": {
|
||||
"type": "builtin",
|
||||
"lib-depends": [
|
||||
"onig"
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"mbstring"
|
||||
]
|
||||
},
|
||||
"mbstring": {
|
||||
@@ -162,6 +177,17 @@
|
||||
"onig"
|
||||
]
|
||||
},
|
||||
"memcache": {
|
||||
"type": "external",
|
||||
"source": "ext-memcache",
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"zlib"
|
||||
],
|
||||
"ext-depends": [
|
||||
"session"
|
||||
]
|
||||
},
|
||||
"mongodb": {
|
||||
"type": "external",
|
||||
"source": "mongodb",
|
||||
@@ -182,7 +208,10 @@
|
||||
},
|
||||
"mysqlnd": {
|
||||
"type": "builtin",
|
||||
"arg-type-windows": "with"
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"opcache": {
|
||||
"type": "builtin"
|
||||
@@ -211,12 +240,13 @@
|
||||
},
|
||||
"pdo_pgsql": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "with-prefix",
|
||||
"ext-depends": [
|
||||
"pdo"
|
||||
"pdo",
|
||||
"pgsql"
|
||||
],
|
||||
"lib-depends": [
|
||||
"pq"
|
||||
"postgresql"
|
||||
]
|
||||
},
|
||||
"pdo_sqlite": {
|
||||
@@ -230,6 +260,13 @@
|
||||
"sqlite"
|
||||
]
|
||||
},
|
||||
"pgsql": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"postgresql"
|
||||
]
|
||||
},
|
||||
"phar": {
|
||||
"type": "builtin",
|
||||
"ext-depends": [
|
||||
@@ -320,6 +357,7 @@
|
||||
"type": "external",
|
||||
"source": "swoole",
|
||||
"arg-type": "custom",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"openssl"
|
||||
],
|
||||
|
||||
@@ -381,7 +381,19 @@
|
||||
"postgresql": {
|
||||
"source": "postgresql",
|
||||
"static-libs-unix": [
|
||||
"libpg.a"
|
||||
"libpq.a",
|
||||
"libpgport.a",
|
||||
"libpgcommon.a"
|
||||
],
|
||||
"lib-depends": [
|
||||
"libiconv",
|
||||
"libxml2",
|
||||
"openssl",
|
||||
"zlib",
|
||||
"readline"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"icu"
|
||||
]
|
||||
},
|
||||
"pthreads4w": {
|
||||
@@ -450,6 +462,13 @@
|
||||
"zconf.h"
|
||||
]
|
||||
},
|
||||
"libmemcached": {
|
||||
"source": "libmemcached",
|
||||
"static-libs-unix": [
|
||||
"libmemcached.a",
|
||||
"libmemcachedutil.a"
|
||||
]
|
||||
},
|
||||
"zstd": {
|
||||
"source": "zstd",
|
||||
"static-libs-unix": [
|
||||
|
||||
@@ -16,6 +16,25 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"memcached": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/memcached",
|
||||
"path": "php-src/ext/memcached",
|
||||
"filename": "memcached.tgz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"libmemcached": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/crazywhalecc/libmemcached-macos.git",
|
||||
"rev": "master",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
}
|
||||
},
|
||||
"brotli": {
|
||||
"type": "ghtar",
|
||||
"repo": "google/brotli",
|
||||
@@ -61,6 +80,16 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"ext-memcache": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/memcache",
|
||||
"path": "php-src/ext/memcache",
|
||||
"filename": "memcache.tgz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"ext-ssh2": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/ssh2",
|
||||
@@ -318,7 +347,8 @@
|
||||
}
|
||||
},
|
||||
"postgresql": {
|
||||
"type": "custom",
|
||||
"type": "url",
|
||||
"url": "https://ftp.postgresql.org/pub/source/v15.1/postgresql-15.1.tar.gz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYRIGHT"
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace SPC;
|
||||
use SPC\command\DeployCommand;
|
||||
use SPC\store\FileSystem;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Command\HelpCommand;
|
||||
use Symfony\Component\Console\Command\ListCommand;
|
||||
|
||||
@@ -16,7 +15,7 @@ use Symfony\Component\Console\Command\ListCommand;
|
||||
*/
|
||||
class ConsoleApplication extends Application
|
||||
{
|
||||
public const VERSION = '2.0-rc2';
|
||||
public const VERSION = '2.0-rc4';
|
||||
|
||||
/**
|
||||
* @throws \ReflectionException
|
||||
|
||||
@@ -9,6 +9,7 @@ use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\SourceExtractor;
|
||||
use SPC\util\CustomExt;
|
||||
use SPC\util\DependencyUtil;
|
||||
|
||||
@@ -87,7 +88,7 @@ abstract class BuilderBase
|
||||
$lib->calcDependency();
|
||||
}
|
||||
|
||||
$this->initSource(libs: $libraries);
|
||||
SourceExtractor::initSource(libs: $libraries);
|
||||
|
||||
// 构建库
|
||||
foreach ($this->libs as $lib) {
|
||||
@@ -140,6 +141,37 @@ abstract class BuilderBase
|
||||
return $this->exts[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有要编译的扩展对象
|
||||
*
|
||||
* @return Extension[]
|
||||
*/
|
||||
public function getExts(): array
|
||||
{
|
||||
return $this->exts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 C++ 扩展是否存在
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function hasCppExtension(): bool
|
||||
{
|
||||
// judge cpp-extension
|
||||
$exts = array_keys($this->getExts());
|
||||
$cpp = false;
|
||||
foreach ($exts as $ext) {
|
||||
if (Config::getExt($ext, 'cpp-extension', false) === true) {
|
||||
$cpp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $cpp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置本次 Builder 是否为仅编译库的模式
|
||||
*/
|
||||
@@ -153,15 +185,17 @@ abstract class BuilderBase
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws \ReflectionException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function proveExts(array $extensions): void
|
||||
{
|
||||
CustomExt::loadCustomExt();
|
||||
$this->initSource(sources: ['php-src']);
|
||||
SourceExtractor::initSource(sources: ['php-src']);
|
||||
if ($this->getPHPVersionID() >= 80000) {
|
||||
$this->initSource(sources: ['micro']);
|
||||
SourceExtractor::initSource(sources: ['micro']);
|
||||
}
|
||||
$this->initSource(exts: $extensions);
|
||||
SourceExtractor::initSource(exts: $extensions);
|
||||
foreach ($extensions as $extension) {
|
||||
$class = CustomExt::getExtClass($extension);
|
||||
$ext = new $class($extension, $this);
|
||||
@@ -190,6 +224,7 @@ abstract class BuilderBase
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function makeExtensionArgs(): string
|
||||
{
|
||||
@@ -261,52 +296,4 @@ abstract class BuilderBase
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function initSource(?array $sources = null, ?array $libs = null, ?array $exts = null): void
|
||||
{
|
||||
if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) {
|
||||
throw new WrongUsageException('Download lock file "downloads/.lock.json" not found, maybe you need to download sources first ?');
|
||||
}
|
||||
$lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true);
|
||||
|
||||
$sources_extracted = [];
|
||||
// source check exist
|
||||
if (is_array($sources)) {
|
||||
foreach ($sources as $source) {
|
||||
$sources_extracted[$source] = true;
|
||||
}
|
||||
}
|
||||
// lib check source exist
|
||||
if (is_array($libs)) {
|
||||
foreach ($libs as $lib) {
|
||||
// get source name for lib
|
||||
$source = Config::getLib($lib, 'source');
|
||||
$sources_extracted[$source] = true;
|
||||
}
|
||||
}
|
||||
// ext check source exist
|
||||
if (is_array($exts)) {
|
||||
foreach ($exts as $ext) {
|
||||
// get source name for ext
|
||||
if (Config::getExt($ext, 'type') !== 'external') {
|
||||
continue;
|
||||
}
|
||||
$source = Config::getExt($ext, 'source');
|
||||
$sources_extracted[$source] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// start check
|
||||
foreach ($sources_extracted as $source => $item) {
|
||||
if (!isset($lock[$source])) {
|
||||
throw new WrongUsageException('Source [' . $source . '] not downloaded, you should download it first !');
|
||||
}
|
||||
|
||||
// check source dir exist
|
||||
$check = $lock[$source]['move_path'] === null ? SOURCE_PATH . '/' . $source : SOURCE_PATH . '/' . $lock[$source]['move_path'];
|
||||
if (!is_dir($check)) {
|
||||
FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), $lock[$source]['move_path']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,33 @@ class Extension
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before ./buildconf
|
||||
* If you need to patch some code, overwrite this and return true
|
||||
*/
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before ./configure
|
||||
* If you need to patch some code, overwrite this and return true
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before make
|
||||
* If you need to patch some code, overwrite this and return true
|
||||
*/
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
|
||||
@@ -135,6 +135,7 @@ abstract class LibraryBase
|
||||
// 传入 true,表明直接编译
|
||||
if ($force_build) {
|
||||
logger()->info('Building required library [' . static::NAME . ']');
|
||||
$this->patchBeforeBuild();
|
||||
$this->build();
|
||||
return BUILD_STATUS_OK;
|
||||
}
|
||||
@@ -162,6 +163,14 @@ abstract class LibraryBase
|
||||
return BUILD_STATUS_ALREADY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch before build, overwrite this and return true to patch libs
|
||||
*/
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取构建当前 lib 的 Builder 对象
|
||||
*/
|
||||
|
||||
25
src/SPC/builder/extension/bz2.php
Normal file
25
src/SPC/builder/extension/bz2.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('bz2')]
|
||||
class bz2 extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
|
||||
FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, '/-lbz2/', $this->getLibFilesString() . $frameworks);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
52
src/SPC/builder/extension/curl.php
Normal file
52
src/SPC/builder/extension/curl.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('curl')]
|
||||
class curl extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
logger()->info('patching before-configure for curl checks');
|
||||
$file1 = "AC_DEFUN([PHP_CHECK_LIBRARY], [\n $3\n])";
|
||||
$files = FileSystem::readFile(SOURCE_PATH . '/php-src/ext/curl/config.m4');
|
||||
$file2 = 'AC_DEFUN([PHP_CHECK_LIBRARY], [
|
||||
save_old_LDFLAGS=$LDFLAGS
|
||||
ac_stuff="$5"
|
||||
|
||||
save_ext_shared=$ext_shared
|
||||
ext_shared=yes
|
||||
PHP_EVAL_LIBLINE([$]ac_stuff, LDFLAGS)
|
||||
AC_CHECK_LIB([$1],[$2],[
|
||||
LDFLAGS=$save_old_LDFLAGS
|
||||
ext_shared=$save_ext_shared
|
||||
$3
|
||||
],[
|
||||
LDFLAGS=$save_old_LDFLAGS
|
||||
ext_shared=$save_ext_shared
|
||||
unset ac_cv_lib_$1[]_$2
|
||||
$4
|
||||
])dnl
|
||||
])';
|
||||
file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
|
||||
FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, '/-lcurl/', $this->getLibFilesString() . $frameworks);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('event')]
|
||||
@@ -23,4 +25,18 @@ class event extends Extension
|
||||
}
|
||||
return $arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/configure',
|
||||
REPLACE_FILE_PREG,
|
||||
'/-levent_openssl/',
|
||||
$this->getLibFilesString()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,9 @@ class mbregex extends Extension
|
||||
{
|
||||
return 'mbstring';
|
||||
}
|
||||
|
||||
public function getConfigureArg(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
48
src/SPC/builder/extension/memcache.php
Normal file
48
src/SPC/builder/extension/memcache.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('memcache')]
|
||||
class memcache extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
return '--enable-memcache --with-zlib-dir=' . BUILD_ROOT_PATH;
|
||||
}
|
||||
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
|
||||
REPLACE_FILE_STR,
|
||||
'if test -d $abs_srcdir/src ; then',
|
||||
'if test -d $abs_srcdir/main ; then'
|
||||
);
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
|
||||
REPLACE_FILE_STR,
|
||||
'export CPPFLAGS="$CPPFLAGS $INCLUDES"',
|
||||
'export CPPFLAGS="$CPPFLAGS $INCLUDES -I$abs_srcdir/main"'
|
||||
);
|
||||
// add for in-tree building
|
||||
file_put_contents(
|
||||
SOURCE_PATH . '/php-src/ext/memcache/php_memcache.h',
|
||||
<<<'EOF'
|
||||
#ifndef PHP_MEMCACHE_H
|
||||
#define PHP_MEMCACHE_H
|
||||
|
||||
extern zend_module_entry memcache_module_entry;
|
||||
#define phpext_memcache_ptr &memcache_module_entry
|
||||
|
||||
#endif
|
||||
EOF
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
18
src/SPC/builder/extension/memcached.php
Normal file
18
src/SPC/builder/extension/memcached.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('memcached')]
|
||||
class memcached extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$rootdir = BUILD_ROOT_PATH;
|
||||
return "--enable-memcached --with-zlib-dir={$rootdir} --with-libmemcached-dir={$rootdir} --disable-memcached-sasl --enable-memcached-json";
|
||||
}
|
||||
}
|
||||
25
src/SPC/builder/extension/openssl.php
Normal file
25
src/SPC/builder/extension/openssl.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
use SPC\util\Util;
|
||||
|
||||
#[CustomExt('openssl')]
|
||||
class openssl extends Extension
|
||||
{
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
// patch openssl3 with php8.0 bug
|
||||
if (file_exists(SOURCE_PATH . '/openssl/VERSION.dat') && Util::getPHPVersionID() < 80100) {
|
||||
$openssl_c = file_get_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c');
|
||||
$openssl_c = preg_replace('/REGISTER_LONG_CONSTANT\s*\(\s*"OPENSSL_SSLV23_PADDING"\s*.+;/', '', $openssl_c);
|
||||
file_put_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c', $openssl_c);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
28
src/SPC/builder/extension/pdo_sqlite.php
Normal file
28
src/SPC/builder/extension/pdo_sqlite.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('pdo_sqlite')]
|
||||
class pdo_sqlite extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/configure',
|
||||
REPLACE_FILE_PREG,
|
||||
'/sqlite3_column_table_name=yes/',
|
||||
'sqlite3_column_table_name=no'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
28
src/SPC/builder/extension/pgsql.php
Normal file
28
src/SPC/builder/extension/pgsql.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('pgsql')]
|
||||
class pgsql extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/configure',
|
||||
REPLACE_FILE_PREG,
|
||||
'/-lpq/',
|
||||
$this->getLibFilesString()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
28
src/SPC/builder/extension/readline.php
Normal file
28
src/SPC/builder/extension/readline.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('readline')]
|
||||
class readline extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/configure',
|
||||
REPLACE_FILE_PREG,
|
||||
'/-lncurses/',
|
||||
$this->getLibFilesString()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
28
src/SPC/builder/extension/ssh2.php
Normal file
28
src/SPC/builder/extension/ssh2.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('ssh2')]
|
||||
class ssh2 extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/configure',
|
||||
REPLACE_FILE_PREG,
|
||||
'/-lssh2/',
|
||||
$this->getLibFilesString()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
use SPC\util\Util;
|
||||
|
||||
#[CustomExt('swow')]
|
||||
class swow extends Extension
|
||||
@@ -17,4 +18,17 @@ class swow extends Extension
|
||||
$arg .= $this->builder->getLib('curl') ? ' --enable-swow-curl' : ' --disable-swow-curl';
|
||||
return $arg;
|
||||
}
|
||||
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
if (Util::getPHPVersionID() >= 80000 && !is_link(SOURCE_PATH . '/php-src/ext/swow')) {
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D swow swow-src\ext');
|
||||
} else {
|
||||
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && ln -s swow-src/ext swow');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,8 @@ class LinuxBuilder extends BuilderBase
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($this->getExt('swoole') || $this->getExt('intl')) {
|
||||
|
||||
if ($this->hasCppExtension()) {
|
||||
$extra_libs .= ' -lstdc++';
|
||||
}
|
||||
if ($this->getExt('imagick')) {
|
||||
@@ -168,11 +169,11 @@ class LinuxBuilder extends BuilderBase
|
||||
|
||||
$envs = "{$envs} CFLAGS='{$cflags}' LIBS='-ldl -lpthread'";
|
||||
|
||||
SourcePatcher::patchPHPBuildconf($this);
|
||||
SourcePatcher::patchBeforeBuildconf($this);
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||
|
||||
SourcePatcher::patchPHPConfigure($this);
|
||||
SourcePatcher::patchBeforeConfigure($this);
|
||||
|
||||
if ($this->getPHPVersionID() < 80000) {
|
||||
$json_74 = '--enable-json ';
|
||||
@@ -199,7 +200,7 @@ class LinuxBuilder extends BuilderBase
|
||||
$envs
|
||||
);
|
||||
|
||||
SourcePatcher::patchPHPAfterConfigure($this);
|
||||
SourcePatcher::patchBeforeMake($this);
|
||||
|
||||
file_put_contents('/tmp/comment', $this->note_section);
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ abstract class LinuxLibraryBase extends LibraryBase
|
||||
// 传入 true,表明直接编译
|
||||
if ($force_build) {
|
||||
logger()->info('Building required library [' . static::NAME . ']');
|
||||
$this->patchBeforeBuild();
|
||||
$this->build();
|
||||
return BUILD_STATUS_OK;
|
||||
}
|
||||
|
||||
20
src/SPC/builder/linux/library/libmemcached.php
Normal file
20
src/SPC/builder/linux/library/libmemcached.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
use SPC\exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* gmp is a template library class for unix
|
||||
*/
|
||||
class libmemcached extends LinuxLibraryBase
|
||||
{
|
||||
public const NAME = 'libmemcached';
|
||||
|
||||
public function build()
|
||||
{
|
||||
throw new RuntimeException('libmemcached is currently not supported on Linux platform');
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,34 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libpng extends LinuxLibraryBase
|
||||
{
|
||||
public const NAME = 'libpng';
|
||||
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/libpng/configure',
|
||||
REPLACE_FILE_STR,
|
||||
'-lz',
|
||||
BUILD_LIB_PATH . '/libz.a'
|
||||
);
|
||||
if (SystemUtil::getOSRelease()['dist'] === 'alpine') {
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/libpng/configure',
|
||||
REPLACE_FILE_STR,
|
||||
'-lm',
|
||||
'/usr/lib/libm.a'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
@@ -39,12 +59,9 @@ class libpng extends LinuxLibraryBase
|
||||
'arm64' => '--enable-arm-neon ',
|
||||
default => '',
|
||||
};
|
||||
|
||||
// patch configure
|
||||
SourcePatcher::patchUnixLibpng();
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->exec('chmod +x ./configure')
|
||||
->exec('chmod +x ./install-sh')
|
||||
->exec(
|
||||
"{$this->builder->configure_env} ./configure " .
|
||||
"--host={$this->builder->gnu_arch}-unknown-linux " .
|
||||
|
||||
12
src/SPC/builder/linux/library/postgresql.php
Normal file
12
src/SPC/builder/linux/library/postgresql.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class postgresql extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\postgresql;
|
||||
|
||||
public const NAME = 'postgresql';
|
||||
}
|
||||
@@ -54,7 +54,7 @@ class MacOSBuilder extends BuilderBase
|
||||
'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' .
|
||||
"CC='{$this->cc}' " .
|
||||
"CXX='{$this->cxx}' " .
|
||||
"CFLAGS='{$this->arch_c_flags} -Wimplicit-function-declaration'";
|
||||
"CFLAGS='{$this->arch_c_flags} -Wimplicit-function-declaration -Os'";
|
||||
|
||||
// 创立 pkg-config 和放头文件的目录
|
||||
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
||||
@@ -118,12 +118,15 @@ class MacOSBuilder extends BuilderBase
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @param int $build_target build target
|
||||
* @param bool $bloat just raw add all lib files
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = false): void
|
||||
{
|
||||
$extra_libs = $this->getFrameworks(true) . ' ' . ($this->getExt('swoole') || $this->getExt('intl') ? '-lc++ ' : '');
|
||||
$extra_libs = $this->getFrameworks(true) . ' ' . ($this->hasCppExtension() ? '-lc++ ' : '');
|
||||
if (!$bloat) {
|
||||
$extra_libs .= implode(' ', $this->getAllStaticLibFiles());
|
||||
} else {
|
||||
@@ -137,12 +140,12 @@ class MacOSBuilder extends BuilderBase
|
||||
);
|
||||
}
|
||||
|
||||
// patch before configure
|
||||
SourcePatcher::patchPHPBuildconf($this);
|
||||
// patch before buildconf
|
||||
SourcePatcher::patchBeforeBuildconf($this);
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||
|
||||
SourcePatcher::patchPHPConfigure($this);
|
||||
SourcePatcher::patchBeforeConfigure($this);
|
||||
|
||||
if ($this->getLib('libxml2') || $this->getExt('iconv')) {
|
||||
$extra_libs .= ' -liconv';
|
||||
@@ -174,7 +177,7 @@ class MacOSBuilder extends BuilderBase
|
||||
$this->configure_env
|
||||
);
|
||||
|
||||
SourcePatcher::patchPHPAfterConfigure($this);
|
||||
SourcePatcher::patchBeforeMake($this);
|
||||
|
||||
$this->cleanMake();
|
||||
|
||||
@@ -209,7 +212,7 @@ class MacOSBuilder extends BuilderBase
|
||||
public function buildCli(string $extra_libs): void
|
||||
{
|
||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||
$shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli");
|
||||
$shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli");
|
||||
if ($this->strip) {
|
||||
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
|
||||
}
|
||||
|
||||
@@ -20,19 +20,32 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class curl extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\curl {
|
||||
build as unixBuild;
|
||||
}
|
||||
use \SPC\builder\unix\library\curl;
|
||||
|
||||
public const NAME = 'curl';
|
||||
|
||||
protected function build()
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
SourcePatcher::patchCurlMacOS();
|
||||
$this->unixBuild();
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/curl/CMakeLists.txt',
|
||||
REPLACE_FILE_PREG,
|
||||
'/NOT COREFOUNDATION_FRAMEWORK/m',
|
||||
'FALSE'
|
||||
);
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/curl/CMakeLists.txt',
|
||||
REPLACE_FILE_PREG,
|
||||
'/NOT SYSTEMCONFIGURATION_FRAMEWORK/m',
|
||||
'FALSE'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
31
src/SPC/builder/macos/library/libmemcached.php
Normal file
31
src/SPC/builder/macos/library/libmemcached.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
/**
|
||||
* gmp is a template library class for unix
|
||||
*/
|
||||
class libmemcached extends MacOSLibraryBase
|
||||
{
|
||||
public const NAME = 'libmemcached';
|
||||
|
||||
public function build()
|
||||
{
|
||||
$rootdir = BUILD_ROOT_PATH;
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->exec('chmod +x configure')
|
||||
->exec(
|
||||
"{$this->builder->configure_env} ./configure " .
|
||||
'--enable-static --disable-shared ' .
|
||||
'--disable-sasl ' .
|
||||
"--prefix={$rootdir}"
|
||||
)
|
||||
->exec('make clean')
|
||||
->exec('sed -ie "s/-Werror//g" ' . $this->source_dir . '/Makefile')
|
||||
->exec("make -j{$this->builder->concurrency}")
|
||||
->exec('make install');
|
||||
}
|
||||
}
|
||||
@@ -31,18 +31,16 @@ class libxml2 extends MacOSLibraryBase
|
||||
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||
'-DLIBXML2_WITH_ICONV=ON ' .
|
||||
"-DLIBXML2_WITH_ZLIB={$enable_zlib} " .
|
||||
"-DLIBXML2_WITH_ICU={$enable_icu} " .
|
||||
'-DLIBXML2_WITH_ICU=OFF ' .
|
||||
"-DLIBXML2_WITH_LZMA={$enable_xz} " .
|
||||
'-DLIBXML2_WITH_PYTHON=OFF ' .
|
||||
'-DLIBXML2_WITH_PROGRAMS=OFF ' .
|
||||
'-DLIBXML2_WITH_TESTS=OFF ' .
|
||||
'-DCMAKE_INSTALL_PREFIX=/ ' .
|
||||
"-DCMAKE_INSTALL_LIBDIR={$lib} " .
|
||||
"-DCMAKE_INSTALL_INCLUDEDIR={$include} " .
|
||||
"-DCMAKE_INSTALL_PREFIX={$destdir} " .
|
||||
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||
'..'
|
||||
)
|
||||
->exec("cmake --build . -j {$this->builder->concurrency}")
|
||||
->exec("make install DESTDIR={$destdir}");
|
||||
->exec('make install');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ class openssl extends MacOSLibraryBase
|
||||
"{$this->builder->configure_env} ./Configure no-shared {$extra} " .
|
||||
'--prefix=/ ' . // use prefix=/
|
||||
"--libdir={$lib} " .
|
||||
" darwin64-{$this->builder->arch}-cc"
|
||||
'--openssldir=/System/Library/OpenSSL ' .
|
||||
"darwin64-{$this->builder->arch}-cc"
|
||||
)
|
||||
->exec('make clean')
|
||||
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
||||
|
||||
12
src/SPC/builder/macos/library/postgresql.php
Normal file
12
src/SPC/builder/macos/library/postgresql.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
class postgresql extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\postgresql;
|
||||
|
||||
public const NAME = 'postgresql';
|
||||
}
|
||||
@@ -22,6 +22,7 @@ trait libevent
|
||||
'-DEVENT__LIBRARY_TYPE=STATIC ' .
|
||||
'-DEVENT__DISABLE_BENCHMARK=ON ' .
|
||||
'-DEVENT__DISABLE_THREAD_SUPPORT=ON ' .
|
||||
'-DEVENT__DISABLE_MBEDTLS=ON ' .
|
||||
'-DEVENT__DISABLE_TESTS=ON ' .
|
||||
'-DEVENT__DISABLE_SAMPLES=ON ' .
|
||||
'..'
|
||||
|
||||
89
src/SPC/builder/unix/library/postgresql.php
Normal file
89
src/SPC/builder/unix/library/postgresql.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
trait postgresql
|
||||
{
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
protected function build()
|
||||
{
|
||||
$builddir = BUILD_ROOT_PATH;
|
||||
$env = $this->builder->configure_env;
|
||||
$envs = $env;
|
||||
$packages = 'openssl zlib readline libxml-2.0'; // icu-uc icu-io icu-i18n libzstd
|
||||
|
||||
$pkgconfig_executable = $builddir . '/bin/pkg-config';
|
||||
$output = shell()->execWithResult($env . " {$pkgconfig_executable} --cflags-only-I --static " . $packages);
|
||||
if (!empty($output[1][0])) {
|
||||
$cppflags = $output[1][0];
|
||||
$envs .= " CPPFLAGS=\"{$cppflags}\"";
|
||||
}
|
||||
$output = shell()->execWithResult($env . " {$pkgconfig_executable} --libs-only-L --static " . $packages);
|
||||
if (!empty($output[1][0])) {
|
||||
$ldflags = $output[1][0];
|
||||
$envs .= $this instanceof MacOSLibraryBase ? " LDFLAGS=\"{$ldflags}\" " : " LDFLAGS=\"{$ldflags} -static\" ";
|
||||
}
|
||||
$output = shell()->execWithResult($env . " {$pkgconfig_executable} --libs-only-l --static " . $packages);
|
||||
if (!empty($output[1][0])) {
|
||||
$libs = $output[1][0];
|
||||
$envs .= " LIBS=\"{$libs}\" ";
|
||||
}
|
||||
|
||||
FileSystem::resetDir($this->source_dir . '/build');
|
||||
|
||||
# 有静态链接配置 参考文件: src/interfaces/libpq/Makefile
|
||||
shell()->cd($this->source_dir . '/build')
|
||||
->exec('sed -i.backup "s/invokes exit\'; exit 1;/invokes exit\';/" ../src/interfaces/libpq/Makefile')
|
||||
->exec(' sed -i.backup "293 s/^/#$/" ../src/Makefile.shlib')
|
||||
->exec('sed -i.backup "441 s/^/#$/" ../src/Makefile.shlib');
|
||||
|
||||
// configure
|
||||
shell()->cd($this->source_dir . '/build')
|
||||
->exec(
|
||||
"{$envs} ../configure " .
|
||||
"--prefix={$builddir} " .
|
||||
'--disable-thread-safety ' .
|
||||
'--enable-coverage=no ' .
|
||||
'--with-ssl=openssl ' .
|
||||
'--with-readline ' .
|
||||
'--with-libxml ' .
|
||||
($this->builder->getLib('icu') ? '--with-icu ' : '--without-icu ') .
|
||||
'--without-ldap ' .
|
||||
'--without-libxslt ' .
|
||||
'--without-lz4 ' .
|
||||
'--without-zstd ' .
|
||||
'--without-perl ' .
|
||||
'--without-python ' .
|
||||
'--without-pam ' .
|
||||
'--without-ldap ' .
|
||||
'--without-bonjour ' .
|
||||
'--without-tcl '
|
||||
);
|
||||
|
||||
// build
|
||||
shell()->cd($this->source_dir . '/build')
|
||||
->exec($envs . ' make -C src/bin/pg_config install')
|
||||
->exec($envs . ' make -C src/include install')
|
||||
->exec($envs . ' make -C src/common install')
|
||||
->exec($envs . ' make -C src/backend/port install')
|
||||
->exec($envs . ' make -C src/port install')
|
||||
->exec($envs . ' make -C src/backend/libpq install')
|
||||
->exec($envs . ' make -C src/interfaces/libpq install');
|
||||
|
||||
// remove dynamic libs
|
||||
shell()->cd($this->source_dir . '/build')
|
||||
->exec("rm -rf {$builddir}/lib/*.so.*")
|
||||
->exec("rm -rf {$builddir}/lib/*.so")
|
||||
->exec("rm -rf {$builddir}/lib/*.dylib");
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ namespace SPC\command;
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\exception\ExceptionHandler;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\util\DependencyUtil;
|
||||
use SPC\util\LicenseDumper;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
@@ -27,6 +28,7 @@ class BuildCliCommand extends BuildCommand
|
||||
$this->addOption('build-all', null, null, 'build cli, micro, fpm');
|
||||
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
|
||||
$this->addOption('enable-zts', null, null, 'enable ZTS support');
|
||||
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
@@ -71,7 +73,17 @@ class BuildCliCommand extends BuildCommand
|
||||
// 执行扩展检测
|
||||
$builder->proveExts($extensions);
|
||||
// strip
|
||||
$builder->setStrip(false);
|
||||
$builder->setStrip(!$this->getOption('no-strip'));
|
||||
// Process -I option
|
||||
$custom_ini = [];
|
||||
foreach ($this->input->getOption('with-hardcoded-ini') as $value) {
|
||||
[$source_name, $ini_value] = explode('=', $value, 2);
|
||||
$custom_ini[$source_name] = $ini_value;
|
||||
logger()->info('Adding hardcoded INI [' . $source_name . ' = ' . $ini_value . ']');
|
||||
}
|
||||
if (!empty($custom_ini)) {
|
||||
SourcePatcher::patchHardcodedINI($custom_ini);
|
||||
}
|
||||
// 构建
|
||||
$builder->buildPHP($rule, $this->getOption('bloat'));
|
||||
// 统计时间
|
||||
|
||||
@@ -31,6 +31,7 @@ class DownloadCommand extends BaseCommand
|
||||
$this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format like 8.1', '8.1');
|
||||
$this->addOption('clean', null, null, 'Clean old download cache and source before fetch');
|
||||
$this->addOption('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('from-zip', 'Z', InputOption::VALUE_REQUIRED, 'Fetch from zip archive');
|
||||
}
|
||||
|
||||
@@ -139,14 +140,37 @@ class DownloadCommand extends BaseCommand
|
||||
}
|
||||
$chosen_sources = $sources;
|
||||
|
||||
// Process -U options
|
||||
$custom_urls = [];
|
||||
foreach ($this->input->getOption('custom-url') as $value) {
|
||||
[$source_name, $url] = explode(':', $value, 2);
|
||||
$custom_urls[$source_name] = $url;
|
||||
}
|
||||
|
||||
// Download them
|
||||
f_mkdir(DOWNLOAD_PATH);
|
||||
$cnt = count($chosen_sources);
|
||||
$ni = 0;
|
||||
foreach ($chosen_sources as $source) {
|
||||
++$ni;
|
||||
logger()->info("Fetching source {$source} [{$ni}/{$cnt}]");
|
||||
Downloader::downloadSource($source, Config::getSource($source));
|
||||
if (isset($custom_urls[$source])) {
|
||||
$config = Config::getSource($source);
|
||||
$new_config = [
|
||||
'type' => 'url',
|
||||
'url' => $custom_urls[$source],
|
||||
];
|
||||
if (isset($config['path'])) {
|
||||
$new_config['path'] = $config['path'];
|
||||
}
|
||||
if (isset($config['filename'])) {
|
||||
$new_config['filename'] = $config['filename'];
|
||||
}
|
||||
logger()->info("Fetching source {$source} from custom url [{$ni}/{$cnt}]");
|
||||
Downloader::downloadSource($source, $new_config, true);
|
||||
} else {
|
||||
logger()->info("Fetching source {$source} [{$ni}/{$cnt}]");
|
||||
Downloader::downloadSource($source, Config::getSource($source));
|
||||
}
|
||||
}
|
||||
// 打印拉取资源用时
|
||||
$time = round(microtime(true) - START_TIME, 3);
|
||||
|
||||
35
src/SPC/command/ExtractCommand.php
Normal file
35
src/SPC/command/ExtractCommand.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command;
|
||||
|
||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||
use SPC\store\SourceExtractor;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
#[AsCommand('extract', 'Extract required sources')]
|
||||
class ExtractCommand extends BaseCommand
|
||||
{
|
||||
use UnixSystemUtilTrait;
|
||||
|
||||
protected string $php_major_ver;
|
||||
|
||||
public function configure()
|
||||
{
|
||||
$this->addArgument('sources', InputArgument::REQUIRED, 'The sources will be compiled, comma separated');
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
|
||||
if (empty($sources)) {
|
||||
$this->output->writeln('<erorr>sources cannot be empty, at least contain one !</erorr>');
|
||||
return 1;
|
||||
}
|
||||
SourceExtractor::initSource(sources: $sources);
|
||||
logger()->info('Extract done !');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
24
src/SPC/command/dev/AllExtCommand.php
Normal file
24
src/SPC/command/dev/AllExtCommand.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command\dev;
|
||||
|
||||
use SPC\command\BaseCommand;
|
||||
use SPC\store\Config;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand('dev:ext-all', 'Dev command')]
|
||||
class AllExtCommand extends BaseCommand
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$this->output->writeln(implode(',', array_keys(Config::getExts())));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
43
src/SPC/command/dev/ExtInfoCommand.php
Normal file
43
src/SPC/command/dev/ExtInfoCommand.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command\dev;
|
||||
|
||||
use SPC\command\BaseCommand;
|
||||
use SPC\store\Config;
|
||||
use SPC\util\DependencyUtil;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
#[AsCommand('dev:ext-info', 'Dev command')]
|
||||
class ExtInfoCommand extends BaseCommand
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->addArgument('extensions', InputArgument::REQUIRED, 'The extension name you need to get info');
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions'))));
|
||||
|
||||
// 根据提供的扩展列表获取依赖库列表并编译
|
||||
foreach ($extensions as $extension) {
|
||||
$this->output->writeln('<comment>[ ' . $extension . ' ]</comment>');
|
||||
[, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps([$extension]);
|
||||
$lib_suggests = Config::getExt($extension, 'lib-suggests', []);
|
||||
$ext_suggests = Config::getExt($extension, 'ext-suggests', []);
|
||||
$this->output->writeln("<info>lib-depends:\t" . implode(', ', $libraries) . '</info>');
|
||||
$this->output->writeln("<info>lib-suggests:\t" . implode(', ', $lib_suggests) . '</info>');
|
||||
$this->output->writeln("<info>ext-depends:\t" . implode(',', $not_included) . '</info>');
|
||||
$this->output->writeln("<info>ext-suggests:\t" . implode(', ', $ext_suggests) . '</info>');
|
||||
if (Config::getExt($extension, 'unix-only', false)) {
|
||||
$this->output->writeln("<info>Unix only:\ttrue</info>");
|
||||
}
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
33
src/SPC/command/dev/PhpVerCommand.php
Normal file
33
src/SPC/command/dev/PhpVerCommand.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command\dev;
|
||||
|
||||
use SPC\command\BaseCommand;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand('dev:php-ver', 'Dev command')]
|
||||
class PhpVerCommand extends BaseCommand
|
||||
{
|
||||
public function initialize(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->no_motd = true;
|
||||
parent::initialize($input, $output);
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
// Find php from source/php-src
|
||||
$file = SOURCE_PATH . '/php-src/main/php_version.h';
|
||||
$result = preg_match('/#define PHP_VERSION "([^"]+)"/', file_get_contents($file), $match);
|
||||
if ($result === false) {
|
||||
$this->output->writeln('<error>PHP source not found, maybe you need to extract first ?</error>');
|
||||
return 1;
|
||||
}
|
||||
$this->output->writeln('<info>' . $match[1] . '</info>');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -265,7 +265,7 @@ class Downloader
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function downloadSource(string $name, ?array $source = null): void
|
||||
public static function downloadSource(string $name, ?array $source = null, bool $force = false): void
|
||||
{
|
||||
if ($source === null) {
|
||||
$source = Config::getSource($name);
|
||||
@@ -278,7 +278,7 @@ class Downloader
|
||||
$lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? [];
|
||||
}
|
||||
// If lock file exists, skip downloading
|
||||
if (isset($lock[$name])) {
|
||||
if (isset($lock[$name]) && !$force) {
|
||||
if ($lock[$name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename'])) {
|
||||
logger()->notice("source [{$name}] already downloaded: " . $lock[$name]['filename']);
|
||||
return;
|
||||
|
||||
61
src/SPC/store/SourceExtractor.php
Normal file
61
src/SPC/store/SourceExtractor.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\store;
|
||||
|
||||
use SPC\exception\WrongUsageException;
|
||||
|
||||
class SourceExtractor
|
||||
{
|
||||
public static function initSource(?array $sources = null, ?array $libs = null, ?array $exts = null): void
|
||||
{
|
||||
if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) {
|
||||
throw new WrongUsageException('Download lock file "downloads/.lock.json" not found, maybe you need to download sources first ?');
|
||||
}
|
||||
$lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true);
|
||||
|
||||
$sources_extracted = [];
|
||||
// source check exist
|
||||
if (is_array($sources)) {
|
||||
foreach ($sources as $source) {
|
||||
$sources_extracted[$source] = true;
|
||||
}
|
||||
}
|
||||
// lib check source exist
|
||||
if (is_array($libs)) {
|
||||
foreach ($libs as $lib) {
|
||||
// get source name for lib
|
||||
$source = Config::getLib($lib, 'source');
|
||||
$sources_extracted[$source] = true;
|
||||
}
|
||||
}
|
||||
// ext check source exist
|
||||
if (is_array($exts)) {
|
||||
foreach ($exts as $ext) {
|
||||
// get source name for ext
|
||||
if (Config::getExt($ext, 'type') !== 'external') {
|
||||
continue;
|
||||
}
|
||||
$source = Config::getExt($ext, 'source');
|
||||
$sources_extracted[$source] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// start check
|
||||
foreach ($sources_extracted as $source => $item) {
|
||||
if (Config::getSource($source) === null) {
|
||||
throw new WrongUsageException("Source [{$source}] not exists, please check name and correct it !");
|
||||
}
|
||||
if (!isset($lock[$source])) {
|
||||
throw new WrongUsageException('Source [' . $source . '] not downloaded or not locked, you should download it first !');
|
||||
}
|
||||
|
||||
// check source dir exist
|
||||
$check = $lock[$source]['move_path'] === null ? SOURCE_PATH . '/' . $source : SOURCE_PATH . '/' . $lock[$source]['move_path'];
|
||||
if (!is_dir($check)) {
|
||||
FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), $lock[$source]['move_path']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,137 +6,47 @@ namespace SPC\store;
|
||||
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\linux\LinuxBuilder;
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\util\Util;
|
||||
|
||||
class SourcePatcher
|
||||
{
|
||||
public static function init()
|
||||
{
|
||||
FileSystem::addSourceExtractHook('swow', [SourcePatcher::class, 'patchSwow']);
|
||||
// FileSystem::addSourceExtractHook('swow', [SourcePatcher::class, 'patchSwow']);
|
||||
FileSystem::addSourceExtractHook('micro', [SourcePatcher::class, 'patchMicro']);
|
||||
FileSystem::addSourceExtractHook('openssl', [SourcePatcher::class, 'patchOpenssl11Darwin']);
|
||||
}
|
||||
|
||||
public static function patchPHPBuildconf(BuilderBase $builder): void
|
||||
/**
|
||||
* Source patcher runner before buildconf
|
||||
*
|
||||
* @param BuilderBase $builder Builder
|
||||
*/
|
||||
public static function patchBeforeBuildconf(BuilderBase $builder): void
|
||||
{
|
||||
if ($builder->getExt('curl')) {
|
||||
logger()->info('patching before-configure for curl checks');
|
||||
$file1 = "AC_DEFUN([PHP_CHECK_LIBRARY], [\n $3\n])";
|
||||
$files = FileSystem::readFile(SOURCE_PATH . '/php-src/ext/curl/config.m4');
|
||||
$file2 = 'AC_DEFUN([PHP_CHECK_LIBRARY], [
|
||||
save_old_LDFLAGS=$LDFLAGS
|
||||
ac_stuff="$5"
|
||||
|
||||
save_ext_shared=$ext_shared
|
||||
ext_shared=yes
|
||||
PHP_EVAL_LIBLINE([$]ac_stuff, LDFLAGS)
|
||||
AC_CHECK_LIB([$1],[$2],[
|
||||
LDFLAGS=$save_old_LDFLAGS
|
||||
ext_shared=$save_ext_shared
|
||||
$3
|
||||
],[
|
||||
LDFLAGS=$save_old_LDFLAGS
|
||||
ext_shared=$save_ext_shared
|
||||
unset ac_cv_lib_$1[]_$2
|
||||
$4
|
||||
])dnl
|
||||
])';
|
||||
file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2);
|
||||
}
|
||||
|
||||
// if ($builder->getExt('pdo_sqlite')) {
|
||||
// FileSystem::replaceFile()
|
||||
// }
|
||||
}
|
||||
|
||||
public static function patchSwow(): bool
|
||||
{
|
||||
if (Util::getPHPVersionID() >= 80000) {
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D swow swow-src\ext');
|
||||
} else {
|
||||
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && ln -s swow-src/ext swow');
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeBuildconf() === true) {
|
||||
logger()->info('Extension [' . $ext->getName() . '] patched before buildconf');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function patchPHPConfigure(BuilderBase $builder): void
|
||||
{
|
||||
$frameworks = $builder instanceof MacOSBuilder ? ' ' . $builder->getFrameworks(true) . ' ' : '';
|
||||
$patch = [];
|
||||
if ($curl = $builder->getExt('curl')) {
|
||||
$patch[] = ['curl check', '/-lcurl/', $curl->getLibFilesString() . $frameworks];
|
||||
}
|
||||
if ($bzip2 = $builder->getExt('bz2')) {
|
||||
$patch[] = ['bzip2 check', '/-lbz2/', $bzip2->getLibFilesString() . $frameworks];
|
||||
}
|
||||
if ($pdo_sqlite = $builder->getExt('pdo_sqlite')) {
|
||||
$patch[] = ['pdo_sqlite linking', '/sqlite3_column_table_name=yes/', 'sqlite3_column_table_name=no'];
|
||||
}
|
||||
if ($event = $builder->getExt('event')) {
|
||||
$patch[] = ['event check', '/-levent_openssl/', $event->getLibFilesString()];
|
||||
}
|
||||
if ($readline = $builder->getExt('readline')) {
|
||||
$patch[] = ['readline patch', '/-lncurses/', $readline->getLibFilesString()];
|
||||
}
|
||||
if ($ssh2 = $builder->getExt('ssh2')) {
|
||||
$patch[] = ['ssh2 patch', '/-lssh2/', $ssh2->getLibFilesString()];
|
||||
}
|
||||
$patch[] = ['disable capstone', '/have_capstone="yes"/', 'have_capstone="no"'];
|
||||
foreach ($patch as $item) {
|
||||
logger()->info('Patching configure: ' . $item[0]);
|
||||
FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, $item[1], $item[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function patchUnixLibpng(): void
|
||||
/**
|
||||
* Source patcher runner before configure
|
||||
*
|
||||
* @param BuilderBase $builder Builder
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public static function patchBeforeConfigure(BuilderBase $builder): void
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/libpng/configure',
|
||||
REPLACE_FILE_STR,
|
||||
'-lz',
|
||||
BUILD_LIB_PATH . '/libz.a'
|
||||
);
|
||||
if (SystemUtil::getOSRelease()['dist'] === 'alpine') {
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/libpng/configure',
|
||||
REPLACE_FILE_STR,
|
||||
'-lm',
|
||||
'/usr/lib/libm.a'
|
||||
);
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeConfigure() === true) {
|
||||
logger()->info('Extension [' . $ext->getName() . '] patched before configure');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function patchUnixSsh2(): void
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/php-src/configure',
|
||||
REPLACE_FILE_STR,
|
||||
'-lssh2',
|
||||
BUILD_LIB_PATH . '/libssh2.a'
|
||||
);
|
||||
}
|
||||
|
||||
public static function patchCurlMacOS(): void
|
||||
{
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/curl/CMakeLists.txt',
|
||||
REPLACE_FILE_PREG,
|
||||
'/NOT COREFOUNDATION_FRAMEWORK/m',
|
||||
'FALSE'
|
||||
);
|
||||
FileSystem::replaceFile(
|
||||
SOURCE_PATH . '/curl/CMakeLists.txt',
|
||||
REPLACE_FILE_PREG,
|
||||
'/NOT SYSTEMCONFIGURATION_FRAMEWORK/m',
|
||||
'FALSE'
|
||||
);
|
||||
// patch capstone
|
||||
FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, '/have_capstone="yes"/', 'have_capstone="no"');
|
||||
}
|
||||
|
||||
public static function patchMicro(?array $list = null, bool $reverse = false): bool
|
||||
@@ -176,7 +86,7 @@ class SourcePatcher
|
||||
}
|
||||
$patch_list = $list ?? $default;
|
||||
$patches = [];
|
||||
$serial = ['80', '81', '82'];
|
||||
$serial = ['80', '81', '82', '83'];
|
||||
foreach ($patch_list as $patchName) {
|
||||
if (file_exists(SOURCE_PATH . "/php-src/sapi/micro/patches/{$patchName}.patch")) {
|
||||
$patches[] = "sapi/micro/patches/{$patchName}.patch";
|
||||
@@ -217,19 +127,75 @@ class SourcePatcher
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function patchPHPAfterConfigure(BuilderBase $param)
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public static function patchBeforeMake(BuilderBase $builder): void
|
||||
{
|
||||
if ($param instanceof LinuxBuilder) {
|
||||
// Try to fix debian environment build lack HAVE_STRLCAT problem
|
||||
if ($builder instanceof LinuxBuilder) {
|
||||
FileSystem::replaceFile(SOURCE_PATH . '/php-src/main/php_config.h', REPLACE_FILE_PREG, '/^#define HAVE_STRLCPY 1$/m', '');
|
||||
FileSystem::replaceFile(SOURCE_PATH . '/php-src/main/php_config.h', REPLACE_FILE_PREG, '/^#define HAVE_STRLCAT 1$/m', '');
|
||||
}
|
||||
FileSystem::replaceFile(SOURCE_PATH . '/php-src/main/php_config.h', REPLACE_FILE_PREG, '/^#define HAVE_OPENPTY 1$/m', '');
|
||||
|
||||
// patch openssl3 with php8.0 bug
|
||||
if (file_exists(SOURCE_PATH . '/openssl/VERSION.dat') && Util::getPHPVersionID() < 80100) {
|
||||
$openssl_c = file_get_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c');
|
||||
$openssl_c = preg_replace('/REGISTER_LONG_CONSTANT\s*\(\s*"OPENSSL_SSLV23_PADDING"\s*.+;/', '', $openssl_c);
|
||||
file_put_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c', $openssl_c);
|
||||
// call extension patch before make
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeMake() === true) {
|
||||
logger()->info('Extension [' . $ext->getName() . '] patched before make');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public static function patchHardcodedINI(array $ini = []): bool
|
||||
{
|
||||
$cli_c = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c';
|
||||
$cli_c_bak = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c.bak';
|
||||
$micro_c = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c';
|
||||
$micro_c_bak = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c.bak';
|
||||
|
||||
// Try to reverse backup file
|
||||
$find_pattern = 'const char HARDCODED_INI[] =';
|
||||
$patch_str = '';
|
||||
foreach ($ini as $key => $value) {
|
||||
$patch_str .= "\"{$key}={$value}\\n\"\n";
|
||||
}
|
||||
$patch_str = "const char HARDCODED_INI[] =\n{$patch_str}";
|
||||
|
||||
// Detect backup, if we have backup, it means we need to reverse first
|
||||
if (file_exists($cli_c_bak) || file_exists($micro_c_bak)) {
|
||||
self::unpatchHardcodedINI();
|
||||
}
|
||||
|
||||
// Backup it
|
||||
$result = file_put_contents($cli_c_bak, file_get_contents($cli_c));
|
||||
$result = $result && file_put_contents($micro_c_bak, file_get_contents($micro_c));
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Patch it
|
||||
FileSystem::replaceFile($cli_c, REPLACE_FILE_STR, $find_pattern, $patch_str);
|
||||
FileSystem::replaceFile($micro_c, REPLACE_FILE_STR, $find_pattern, $patch_str);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function unpatchHardcodedINI(): bool
|
||||
{
|
||||
$cli_c = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c';
|
||||
$cli_c_bak = SOURCE_PATH . '/php-src/sapi/cli/php_cli.c.bak';
|
||||
$micro_c = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c';
|
||||
$micro_c_bak = SOURCE_PATH . '/php-src/sapi/micro/php_micro.c.bak';
|
||||
if (!file_exists($cli_c_bak) && !file_exists($micro_c_bak)) {
|
||||
return false;
|
||||
}
|
||||
$result = file_put_contents($cli_c, file_get_contents($cli_c_bak));
|
||||
$result = $result && file_put_contents($micro_c, file_get_contents($micro_c_bak));
|
||||
@unlink($cli_c_bak);
|
||||
@unlink($micro_c_bak);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user