Add phpmicro win32 mode support (#478)

* Add phpmicro win32 mode support

* Bump version to 2.2.4

* Add micro win32 build tests for actions

* cs-fix and update deps
This commit is contained in:
Jerry Ma 2024-06-20 14:46:08 +08:00 committed by GitHub
parent 2d2607cd7f
commit 93cb7e9fbb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 229 additions and 193 deletions

View File

@ -186,4 +186,4 @@ jobs:
- name: "Run Build Tests (build, windows)"
if: matrix.os == 'windows-latest'
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $env:UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $env:UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --debug --enable-micro-win32

358
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -460,7 +460,9 @@ abstract class BuilderBase
'micro_ext_test' => [
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests()),
'conditions' => [
// program success
function ($ret) { return $ret === 0; },
// program returns expected output
function ($ret, $out) {
$raw_out = trim(implode('', $out));
return str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
@ -470,6 +472,7 @@ abstract class BuilderBase
'micro_zend_bug_test' => [
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "hello";' : file_get_contents(ROOT_DIR . '/src/globals/common-tests/micro_zend_mm_heap_corrupted.txt')),
'conditions' => [
// program success
function ($ret) { return $ret === 0; },
],
],

View File

@ -96,7 +96,7 @@ abstract class UnixBuilderBase extends BuilderBase
$support_lib_list = [];
$classes = FileSystem::getClassesPsr4(
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
'SPC\\builder\\' . osfamily2dir() . '\\library'
'SPC\builder\\' . osfamily2dir() . '\library'
);
foreach ($classes as $class) {
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {

View File

@ -102,6 +102,8 @@ class WindowsBuilder extends BuilderBase
$micro_logo = '';
}
$micro_w32 = $this->getOption('enable-micro-win32') ? ' --enable-micro-win32=yes' : '';
cmd()->cd(SOURCE_PATH . '\php-src')
->exec(
"{$this->sdk_prefix} configure.bat --task-args \"" .
@ -111,7 +113,7 @@ class WindowsBuilder extends BuilderBase
'--with-extra-includes=' . BUILD_INCLUDE_PATH . ' ' .
'--with-extra-libs=' . BUILD_LIB_PATH . ' ' .
($enableCli ? '--enable-cli=yes ' : '--enable-cli=no ') .
($enableMicro ? ('--enable-micro=yes ' . $micro_logo) : '--enable-micro=no ') .
($enableMicro ? ('--enable-micro=yes ' . $micro_logo . $micro_w32) : '--enable-micro=no ') .
($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
"{$this->makeExtensionArgs()} " .
$zts .
@ -132,6 +134,8 @@ class WindowsBuilder extends BuilderBase
if ($enableMicro) {
logger()->info('building micro');
$this->buildMicro();
SourcePatcher::unpatchMicroWin32();
}
if ($enableEmbed) {
logger()->warning('Windows does not currently support embed SAPI.');
@ -212,8 +216,8 @@ class WindowsBuilder extends BuilderBase
// search all supported libs
$support_lib_list = [];
$classes = FileSystem::getClassesPsr4(
ROOT_DIR . '\src\SPC\builder\\' . osfamily2dir() . '\\library',
'SPC\\builder\\' . osfamily2dir() . '\\library'
ROOT_DIR . '\src\SPC\builder\\' . osfamily2dir() . '\library',
'SPC\builder\\' . osfamily2dir() . '\library'
);
foreach ($classes as $class) {
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {

View File

@ -40,6 +40,7 @@ class BuildCliCommand extends BuildCommand
$this->addOption('without-micro-ext-test', null, null, 'Disable phpmicro with extension test code');
$this->addOption('with-upx-pack', null, null, 'Compress / pack binary using UPX tool (linux/windows only)');
$this->addOption('with-micro-logo', null, InputOption::VALUE_REQUIRED, 'Use custom .ico for micro.sfx (windows only)');
$this->addOption('enable-micro-win32', null, null, 'Enable win32 mode for phpmicro (Windows only)');
}
public function handle(): int

View File

@ -70,7 +70,7 @@ final class CheckListHandler
*/
private function loadCheckList(bool $include_manual = false): array
{
foreach (FileSystem::getClassesPsr4(__DIR__ . '/item', 'SPC\\doctor\\item') as $class) {
foreach (FileSystem::getClassesPsr4(__DIR__ . '/item', 'SPC\doctor\item') as $class) {
$ref = new \ReflectionClass($class);
foreach ($ref->getMethods() as $method) {
foreach ($method->getAttributes() as $a) {

View File

@ -337,7 +337,7 @@ class Downloader
);
break;
case 'custom': // Custom download method, like API-based download or other
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\\store\\source');
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\store\source');
foreach ($classes as $class) {
if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) {
(new $class())->fetch($force);
@ -437,7 +437,7 @@ class Downloader
);
break;
case 'custom': // Custom download method, like API-based download or other
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\\store\\source');
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\store\source');
foreach ($classes as $class) {
if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) {
(new $class())->fetch($force);

View File

@ -47,6 +47,12 @@ class SourcePatcher
''
);
}
if ($builder->getOption('enable-micro-win32')) {
SourcePatcher::patchMicroWin32();
} else {
SourcePatcher::unpatchMicroWin32();
}
}
/**
@ -368,4 +374,20 @@ class SourcePatcher
FileSystem::writeFile(SOURCE_PATH . '/php-src/main/main.c', $file);
}
}
public static function patchMicroWin32(): void
{
// patch micro win32
if (!file_exists(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak')) {
copy(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c', SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak');
FileSystem::replaceFileStr(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c', '#include "php_variables.h"', '#include "php_variables.h"' . "\n#define PHP_MICRO_WIN32_NO_CONSOLE 1");
}
}
public static function unpatchMicroWin32(): void
{
if (file_exists(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak')) {
rename(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak', SOURCE_PATH . '\php-src\sapi\micro\php_micro.c');
}
}
}

View File

@ -23,7 +23,7 @@ class CustomExt
*/
public static function loadCustomExt(): void
{
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\\builder\\extension');
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\builder\extension');
foreach ($classes as $class) {
$reflection = new \ReflectionClass($class);
foreach ($reflection->getAttributes(CustomExt::class) as $attribute) {

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
assert(class_exists('\\DOMDocument'));
assert(class_exists('\DOMDocument'));
$doc = new DOMDocument();
$doc->loadHtml('<html><head><meta charset="UTF-8"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body id="app">Hello</body></html>');
assert($doc->getElementById('app')->nodeValue === 'Hello');

View File

@ -2,4 +2,4 @@
declare(strict_types=1);
assert(class_exists('\\Redis'));
assert(class_exists('\Redis'));

View File

@ -2,4 +2,4 @@
declare(strict_types=1);
assert(class_exists('\\ZipArchive'));
assert(class_exists('\ZipArchive'));

View File

@ -56,7 +56,7 @@ function arch2gnu(string $arch): string
*/
function match_pattern(string $pattern, string $subject): bool
{
$pattern = str_replace(['\*', '\\\\.*'], ['.*', '\*'], preg_quote($pattern, '/'));
$pattern = str_replace(['\*', '\\\.*'], ['.*', '\*'], preg_quote($pattern, '/'));
$pattern = '/^' . $pattern . '$/i';
return preg_match($pattern, $subject) === 1;
}

View File

@ -94,7 +94,7 @@ class FileSystemTest extends TestCase
*/
public function testGetClassesPsr4()
{
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\\builder\\extension');
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\builder\extension');
foreach ($classes as $class) {
$this->assertIsString($class);
new \ReflectionClass($class);
@ -185,9 +185,9 @@ class FileSystemTest extends TestCase
public function testIsRelativePath()
{
$this->assertTrue(FileSystem::isRelativePath('.'));
$this->assertTrue(FileSystem::isRelativePath('.\\sdf'));
$this->assertTrue(FileSystem::isRelativePath('.\sdf'));
if (DIRECTORY_SEPARATOR === '\\') {
$this->assertFalse(FileSystem::isRelativePath('C:\\asdasd/fwe\asd'));
$this->assertFalse(FileSystem::isRelativePath('C:\asdasd/fwe\asd'));
} else {
$this->assertFalse(FileSystem::isRelativePath('/fwefwefewf'));
}