mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
Compare commits
9 Commits
b87a633496
...
3c438914c2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c438914c2 | ||
|
|
d8a1a3c838 | ||
|
|
6b0baa8365 | ||
|
|
c93a4e843f | ||
|
|
3daafa0b0e | ||
|
|
9ce92e39d5 | ||
|
|
4edd05f4df | ||
|
|
3af2811951 | ||
|
|
cfa89e3003 |
@ -46,7 +46,7 @@ chmod +x spc
|
||||
- [X] macOS support
|
||||
- [X] Exception handler
|
||||
- [ ] Windows support
|
||||
- [ ] PHP 7.4 support
|
||||
- [X] PHP 7.4 support
|
||||
|
||||
## Supported Extensions (WIP)
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ chmod +x spc
|
||||
- [X] macOS 支持
|
||||
- [ ] Windows 支持
|
||||
- [ ] Linux 支持
|
||||
- [ ] PHP 7.4 支持
|
||||
- [X] PHP 7.4 支持
|
||||
|
||||
## 支持的扩展情况(WIP)
|
||||
|
||||
|
||||
@ -30,7 +30,8 @@
|
||||
"type": "builtin",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
"libxml2",
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"enchant": {
|
||||
@ -75,11 +76,11 @@
|
||||
"libwebp",
|
||||
"libjpeg",
|
||||
"xpm",
|
||||
"libfreetype"
|
||||
"freetype"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"libiconv",
|
||||
"libfreetype",
|
||||
"freetype",
|
||||
"libjpeg",
|
||||
"zlib",
|
||||
"libpng",
|
||||
@ -100,7 +101,7 @@
|
||||
},
|
||||
"gmp": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "none",
|
||||
"lib-depends": [
|
||||
"gmp"
|
||||
]
|
||||
|
||||
@ -68,6 +68,18 @@
|
||||
"SystemConfiguration"
|
||||
]
|
||||
},
|
||||
"gmp": {
|
||||
"source": "gmp",
|
||||
"static-libs-unix": [
|
||||
"libgmp.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"libgmp.lib"
|
||||
],
|
||||
"headers": [
|
||||
"gmp.h"
|
||||
]
|
||||
},
|
||||
"libffi": {
|
||||
"source": "libffi",
|
||||
"static-libs-unix": [
|
||||
@ -86,6 +98,7 @@
|
||||
"ffitarget.h"
|
||||
]
|
||||
},
|
||||
|
||||
"libpng": {
|
||||
"source": "libpng",
|
||||
"static-libs-unix": [
|
||||
@ -190,6 +203,28 @@
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"libmcrypt": {
|
||||
"source": "libmcrypt",
|
||||
"static-libs-unix": [
|
||||
"libmcrypt.a"
|
||||
]
|
||||
},
|
||||
"mcrypt": {
|
||||
"source": "mcrypt",
|
||||
"static-libs-unix": [
|
||||
"libmcrypt.a"
|
||||
]
|
||||
},
|
||||
"freetype": {
|
||||
"source": "freetype",
|
||||
"static-libs-unix": [
|
||||
"libfreetype.a"
|
||||
],
|
||||
"headers-unix": [
|
||||
"freetype2/freetype/freetype.h",
|
||||
"freetype2/ft2build.h"
|
||||
]
|
||||
},
|
||||
"nghttp2": {
|
||||
"source": "nghttp2",
|
||||
"static-libs-unix": [
|
||||
|
||||
@ -35,6 +35,24 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"freetype": {
|
||||
"type": "filelist",
|
||||
"url": "https://download.savannah.gnu.org/releases/freetype/",
|
||||
"regex": "/href=\"(?<file>freetype-(?<version>[^\"]+)\\.tar\\.xz)\"/",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE.TXT"
|
||||
}
|
||||
},
|
||||
"gmp": {
|
||||
"type": "filelist",
|
||||
"url": "https://gmplib.org/download/gmp/",
|
||||
"regex": "/href=\"(?<file>gmp-(?<version>[^\"]+)\\.tar\\.xz)\"/",
|
||||
"license": {
|
||||
"type": "text",
|
||||
"text": "Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2. These licenses make the library free to use, share, and improve, and allow you to pass on the result. The GNU licenses give freedoms, but also set firm restrictions on the use with non-free programs."
|
||||
}
|
||||
},
|
||||
"libffi": {
|
||||
"type": "ghrel",
|
||||
"repo": "libffi/libffi",
|
||||
@ -44,6 +62,22 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"mcrypt": {
|
||||
"type": "url",
|
||||
"url": "https://jaist.dl.sourceforge.net/project/mcrypt/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
}
|
||||
},
|
||||
"libmcrypt": {
|
||||
"type": "url",
|
||||
"url": "https://nchc.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
}
|
||||
},
|
||||
"libpng": {
|
||||
"type": "git",
|
||||
"url": "https://git.code.sf.net/p/libpng/code",
|
||||
|
||||
117
ext-support.md
117
ext-support.md
@ -3,57 +3,68 @@
|
||||
> - yes: supported and tested
|
||||
> - untested: supported but not tested
|
||||
> - empty: not supported yet
|
||||
> - issue link: not supported yet due to issue
|
||||
> - faulty with issue link: not supported yet due to issue
|
||||
|
||||
| | Linux | macOS | Windows |
|
||||
|------------|-------|----------|---------|
|
||||
| bcmath | | yes | |
|
||||
| bz2 | | untested | |
|
||||
| calendar | | yes | |
|
||||
| ctype | | | |
|
||||
| curl | | yes | |
|
||||
| date | | yes | |
|
||||
| dom | | | |
|
||||
| event | | | |
|
||||
| exif | | | |
|
||||
| filter | | | |
|
||||
| fileinfo | | | |
|
||||
| ftp | | | |
|
||||
| gd | | untested | |
|
||||
| gmp | | untested | |
|
||||
| hash | | yes | |
|
||||
| iconv | | | |
|
||||
| inotify | | | |
|
||||
| json | | yes | |
|
||||
| libxml | | | |
|
||||
| mbstring | | | |
|
||||
| mcrypt | | | |
|
||||
| mongodb | | | |
|
||||
| mysqli | | | |
|
||||
| mysqlnd | | | |
|
||||
| openssl | | yes | |
|
||||
| pcntl | | untested | |
|
||||
| pcre | | yes | |
|
||||
| pdo | | yes | |
|
||||
| pdo_mysql | | | |
|
||||
| pdo_sqlite | | yes | |
|
||||
| pdo_pgsql | | | |
|
||||
| phar | | | |
|
||||
| posix | | | |
|
||||
| protobuf | | | |
|
||||
| readline | | | |
|
||||
| redis | | | |
|
||||
| Reflection | | yes | |
|
||||
| shmop | | | |
|
||||
| simplexml | | | |
|
||||
| soap | | | |
|
||||
| sockets | | | |
|
||||
| sqlite3 | | untested | |
|
||||
| swow | | | |
|
||||
| swoole | | yes | |
|
||||
| tokenizer | | | |
|
||||
| xml | | | |
|
||||
| xmlreader | | | |
|
||||
| xmlwriter | | | |
|
||||
| zip | | | |
|
||||
| zlib | | | |
|
||||
| | Linux | macOS | Windows |
|
||||
|------------|-------|--------------------------------------------------------------------|---------|
|
||||
| bcmath | | yes | |
|
||||
| bz2 | | untested | |
|
||||
| calendar | | yes | |
|
||||
| ctype | | yes | |
|
||||
| curl | | yes | |
|
||||
| date | | yes | |
|
||||
| dom | | untested | |
|
||||
| event | | | |
|
||||
| exif | | yes | |
|
||||
| filter | | yes | |
|
||||
| fileinfo | | | |
|
||||
| ftp | | yes | |
|
||||
| gd | | untested | |
|
||||
| gmp | | untested | |
|
||||
| hash | | yes | |
|
||||
| iconv | | | |
|
||||
| inotify | | | |
|
||||
| json | | yes | |
|
||||
| libxml | | yes | |
|
||||
| mbstring | | yes | |
|
||||
| mcrypt | | [faulty](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| mongodb | | | |
|
||||
| mysqli | | | |
|
||||
| mysqlnd | | yes | |
|
||||
| openssl | | yes | |
|
||||
| pcntl | | untested | |
|
||||
| pcre | | yes | |
|
||||
| pdo | | yes | |
|
||||
| pdo_mysql | | yes | |
|
||||
| pdo_sqlite | | yes | |
|
||||
| pdo_pgsql | | | |
|
||||
| phar | | yes | |
|
||||
| posix | | yes | |
|
||||
| protobuf | | | |
|
||||
| readline | | | |
|
||||
| redis | | yes | |
|
||||
| Reflection | | yes | |
|
||||
| session | | yes | |
|
||||
| shmop | | | |
|
||||
| simplexml | | untested | |
|
||||
| soap | | | |
|
||||
| sockets | | | |
|
||||
| sqlite3 | | untested | |
|
||||
| swow | | | |
|
||||
| swoole | | [faulty](https://github.com/crazywhalecc/static-php-cli/issues/32) | |
|
||||
| tokenizer | | yes | |
|
||||
| xml | | yes | |
|
||||
| xmlreader | | untested | |
|
||||
| xmlwriter | | untested | |
|
||||
| zip | | yes | |
|
||||
| zlib | | yes | |
|
||||
|
||||
## Additional Requirements
|
||||
|
||||
- phpmicro requires PHP >= 8.0
|
||||
- swoole >= 5.0 requires PHP >= 8.0
|
||||
- swow requires PHP >= 8.0
|
||||
|
||||
## Bugs
|
||||
|
||||
See [#32](https://github.com/crazywhalecc/static-php-cli/issues/32).
|
||||
|
||||
@ -182,6 +182,13 @@ class Extension
|
||||
$arg .= ' --with-event-openssl --with-openssl-dir="' . BUILD_ROOT_PATH . '"';
|
||||
}
|
||||
break;*/
|
||||
case 'mbstring':
|
||||
$arg = ' --disable-mbregex ONIG_CFLAGS=-I"' . BUILD_ROOT_PATH . '" ' .
|
||||
'ONIG_LIBS="' . $this->getLibFilesString() . '" ';
|
||||
break;
|
||||
case 'gmp':
|
||||
$arg = ' --with-gmp="' . BUILD_ROOT_PATH . '" ';
|
||||
break;
|
||||
case 'sqlite3':
|
||||
$arg = ' --with-sqlite3="' . BUILD_ROOT_PATH . '" ' .
|
||||
'SQLITE_CFLAGS=-I"' . BUILD_INCLUDE_PATH . '" ' .
|
||||
@ -213,6 +220,11 @@ class Extension
|
||||
'CURL_LIBS="' . $this->getLibFilesString() . '" ';
|
||||
break;
|
||||
case 'gd':
|
||||
if ($this->builder->getLib('freetype')) {
|
||||
$arg .= ' --with-freetype ' .
|
||||
'FREETYPE2_CFLAGS=-I"' . BUILD_INCLUDE_PATH . '/freetype2" ' .
|
||||
'FREETYPE2_LIBS="' . $this->getLibFilesString() . '" ';
|
||||
}
|
||||
$arg .= ' ' .
|
||||
'PNG_CFLAGS=-I"' . BUILD_INCLUDE_PATH . '" ' .
|
||||
'PNG_LIBS="' . $this->getLibFilesString() . '" ';
|
||||
|
||||
@ -219,6 +219,9 @@ class MacOSBuilder extends BuilderBase
|
||||
*/
|
||||
public function buildMicro(string $extra_libs): void
|
||||
{
|
||||
if ($this->getPHPVersionID() < 80000) {
|
||||
throw new RuntimeException('phpmicro only support PHP >= 8.0!');
|
||||
}
|
||||
if ($this->getExt('phar')) {
|
||||
$this->phar_patched = true;
|
||||
try {
|
||||
@ -253,11 +256,18 @@ class MacOSBuilder extends BuilderBase
|
||||
'cd ' . SOURCE_PATH . '/php-src && ' .
|
||||
"make -j{$this->concurrency} " .
|
||||
'EXTRA_CFLAGS="-g -Os -fno-ident" ' . // 生成调试信息、优化编译后的尺寸、禁用标识符(如变量、函数名)缩短
|
||||
"EXTRA_LIBS=\"{$extra_libs} -lresolv -lsqlite3\" " .
|
||||
"EXTRA_LIBS=\"{$extra_libs} -lresolv\" " .
|
||||
// TODO: comment things
|
||||
'cli &&' .
|
||||
'dsymutil -f sapi/cli/php &&' .
|
||||
'strip sapi/cli/php'
|
||||
);
|
||||
}
|
||||
|
||||
public function getPHPVersionID(): int
|
||||
{
|
||||
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
|
||||
preg_match('/PHP_VERSION_ID (\d+)/', $file, $match);
|
||||
return intval($match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
38
src/SPC/builder/macos/library/freetype.php
Normal file
38
src/SPC/builder/macos/library/freetype.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
/**
|
||||
* is a template library class for unix
|
||||
*/
|
||||
class freetype extends MacOSLibraryBase
|
||||
{
|
||||
public const NAME = 'freetype';
|
||||
|
||||
protected function build()
|
||||
{
|
||||
[,,$destdir] = SEPARATED_PATH;
|
||||
|
||||
$suggested = '';
|
||||
$suggested .= ($this->builder->getLib('libpng') instanceof MacOSLibraryBase) ? ('--with-png=' . BUILD_ROOT_PATH) : '--without-png';
|
||||
$suggested .= ' ';
|
||||
$suggested .= ($this->builder->getLib('bzip2') instanceof MacOSLibraryBase) ? ('--with-bzip2=' . BUILD_ROOT_PATH) : '--without-bzip2';
|
||||
$suggested .= ' ';
|
||||
$suggested .= ($this->builder->getLib('brotli') instanceof MacOSLibraryBase) ? ('--with-brotli=' . BUILD_ROOT_PATH) : '--without-brotli';
|
||||
$suggested .= ' ';
|
||||
|
||||
f_passthru(
|
||||
$this->builder->set_x . ' && ' .
|
||||
"cd {$this->source_dir} && " .
|
||||
"{$this->builder->configure_env} ./configure " .
|
||||
'--enable-static --disable-shared --without-harfbuzz ' .
|
||||
$suggested .
|
||||
'--prefix= && ' . // use prefix=/
|
||||
'make clean && ' .
|
||||
"make -j{$this->builder->concurrency} && " .
|
||||
'make install DESTDIR=' . $destdir
|
||||
);
|
||||
}
|
||||
}
|
||||
29
src/SPC/builder/macos/library/gmp.php
Normal file
29
src/SPC/builder/macos/library/gmp.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
/**
|
||||
* gmp is a template library class for unix
|
||||
*/
|
||||
class gmp extends MacOSLibraryBase
|
||||
{
|
||||
public const NAME = 'gmp';
|
||||
|
||||
protected function build()
|
||||
{
|
||||
[,,$destdir] = SEPARATED_PATH;
|
||||
|
||||
f_passthru(
|
||||
$this->builder->set_x . ' && ' .
|
||||
"cd {$this->source_dir} && " .
|
||||
"{$this->builder->configure_env} ./configure " .
|
||||
'--enable-static --disable-shared ' .
|
||||
'--prefix= && ' . // use prefix=/
|
||||
'make clean && ' .
|
||||
"make -j{$this->builder->concurrency} && " .
|
||||
'make install DESTDIR=' . $destdir
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,4 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
|
||||
*
|
||||
* lwmbs is licensed under Mulan PSL v2. You can use this
|
||||
* software according to the terms and conditions of the
|
||||
* Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
@ -77,8 +77,8 @@ class BuildCliCommand extends BuildCommand
|
||||
if ($input->getOption('debug')) {
|
||||
ExceptionHandler::getInstance()->handle($e);
|
||||
} else {
|
||||
logger()->emergency('Build failed, please check terminal output, or build with --debug option to see more details.');
|
||||
logger()->emergency($e->getMessage());
|
||||
logger()->critical('Build failed, please check terminal output, or build with --debug option to see more details.');
|
||||
logger()->critical($e->getMessage());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -214,6 +214,10 @@ class FetchSourceCommand extends BaseCommand
|
||||
*/
|
||||
private function doPatch(): void
|
||||
{
|
||||
// swow 需要软链接内部的文件夹才能正常编译
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/ext/swow')) {
|
||||
Patcher::patchSwow();
|
||||
}
|
||||
// patch 一些 PHP 的资源,以便编译
|
||||
Patcher::patchPHPDepFiles();
|
||||
|
||||
@ -228,11 +232,6 @@ class FetchSourceCommand extends BaseCommand
|
||||
Patcher::patchDarwinOpenssl11();
|
||||
}
|
||||
|
||||
// swow 需要软链接内部的文件夹才能正常编译
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/ext/swow')) {
|
||||
Patcher::patchSwow();
|
||||
}
|
||||
|
||||
// 标记 patch 完成,避免重复 patch
|
||||
file_put_contents(SOURCE_PATH . '/.patched', '');
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ class Downloader
|
||||
|
||||
public static function downloadGit(string $name, string $url, string $branch, ?string $path = null): void
|
||||
{
|
||||
if ($path) {
|
||||
if ($path !== null) {
|
||||
$path = SOURCE_PATH . "/{$path}";
|
||||
} else {
|
||||
$path = DOWNLOAD_PATH . "/{$name}";
|
||||
@ -229,7 +229,7 @@ class Downloader
|
||||
public static function fetchSource(string $name, array $source): void
|
||||
{
|
||||
// 避免重复 fetch
|
||||
if (is_dir(FileSystem::convertPath(SOURCE_PATH . "/{$name}")) || isset($source['path']) && is_dir(FileSystem::convertPath(SOURCE_PATH . "/{$source['path']}"))) {
|
||||
if (!isset($source['path']) && !is_dir(FileSystem::convertPath(DOWNLOAD_PATH . "/{$name}")) || isset($source['path']) && is_dir(FileSystem::convertPath(SOURCE_PATH . "/{$source['path']}"))) {
|
||||
logger()->notice("{$name} source already extracted");
|
||||
return;
|
||||
}
|
||||
@ -291,7 +291,8 @@ class Downloader
|
||||
// 从官网直接下载
|
||||
return [
|
||||
'type' => 'url',
|
||||
'url' => "https://www.php.net/distributions/php-{$version}.tar.gz",
|
||||
// 'url' => "https://www.php.net/distributions/php-{$version}.tar.gz",
|
||||
'url' => "https://mirrors.zhamao.xin/php/php-{$version}.tar.gz",
|
||||
];
|
||||
}
|
||||
|
||||
@ -316,6 +317,24 @@ class Downloader
|
||||
$headerArg = implode(' ', array_map(fn ($v) => '"-H' . $v . '"', $headers));
|
||||
|
||||
$cmd = "curl -sfSL {$methodArg} {$headerArg} \"{$url}\"";
|
||||
if (getenv('CACHE_API_EXEC') === 'yes') {
|
||||
if (!file_exists(SOURCE_PATH . '/.curl_exec_cache')) {
|
||||
$cache = [];
|
||||
} else {
|
||||
$cache = json_decode(file_get_contents(SOURCE_PATH . '/.curl_exec_cache'), true);
|
||||
}
|
||||
if (isset($cache[$cmd]) && $cache[$cmd]['expire'] >= time()) {
|
||||
return $cache[$cmd]['cache'];
|
||||
}
|
||||
f_exec($cmd, $output, $ret);
|
||||
if ($ret !== 0) {
|
||||
throw new DownloaderException('failed http fetch');
|
||||
}
|
||||
$cache[$cmd]['cache'] = implode("\n", $output);
|
||||
$cache[$cmd]['expire'] = time() + 3600;
|
||||
file_put_contents(SOURCE_PATH . '/.curl_exec_cache', json_encode($cache));
|
||||
return $cache[$cmd]['cache'];
|
||||
}
|
||||
f_exec($cmd, $output, $ret);
|
||||
if ($ret !== 0) {
|
||||
throw new DownloaderException('failed http fetch');
|
||||
|
||||
5
src/globals/tests/filter.php
Normal file
5
src/globals/tests/filter.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
exit(function_exists('filter_var') ? 0 : 1);
|
||||
5
src/globals/tests/zip.php
Normal file
5
src/globals/tests/zip.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
exit(class_exists('\\ZipArchive') ? 0 : 1);
|
||||
5
src/globals/tests/zlib.php
Normal file
5
src/globals/tests/zlib.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
exit(function_exists('gzcompress') ? 0 : 1);
|
||||
Loading…
x
Reference in New Issue
Block a user