Compare commits

...

9 Commits

Author SHA1 Message Date
crazywhalecc
3c438914c2
update ext-support.md doc 2023-03-19 01:20:16 +08:00
crazywhalecc
d8a1a3c838
adjust swow patch time 2023-03-19 01:17:16 +08:00
crazywhalecc
6b0baa8365
add more extensions support 2023-03-19 01:16:54 +08:00
crazywhalecc
c93a4e843f
fix mbstring support 2023-03-19 00:15:13 +08:00
crazywhalecc
3daafa0b0e
add freetype support for gd 2023-03-18 21:40:07 +08:00
crazywhalecc
9ce92e39d5
add micro php version limit 2023-03-18 20:08:54 +08:00
crazywhalecc
4edd05f4df
update mcrypt bugs 2023-03-18 19:58:36 +08:00
crazywhalecc
3af2811951
remove some copyright 2023-03-18 19:09:59 +08:00
crazywhalecc
cfa89e3003
add gmp extension for macOS 2023-03-18 18:46:10 +08:00
17 changed files with 273 additions and 86 deletions

View File

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

View File

@ -49,7 +49,7 @@ chmod +x spc
- [X] macOS 支持
- [ ] Windows 支持
- [ ] Linux 支持
- [ ] PHP 7.4 支持
- [X] PHP 7.4 支持
## 支持的扩展情况WIP

View File

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

View File

@ -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": [

View File

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

View File

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

View File

@ -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() . '" ';

View File

@ -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]);
}
}

View 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
);
}
}

View 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
);
}
}

View File

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

View File

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

View File

@ -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', '');
}

View File

@ -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');

View File

@ -0,0 +1,5 @@
<?php
declare(strict_types=1);
exit(function_exists('filter_var') ? 0 : 1);

View File

@ -0,0 +1,5 @@
<?php
declare(strict_types=1);
exit(class_exists('\\ZipArchive') ? 0 : 1);

View File

@ -0,0 +1,5 @@
<?php
declare(strict_types=1);
exit(function_exists('gzcompress') ? 0 : 1);