From c711a3666ead345ce8f9875bbf1ebd8cf0c0745e Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 00:55:21 +0800 Subject: [PATCH 01/20] Add Windows CGI SAPI build support --- src/SPC/ConsoleApplication.php | 2 +- src/SPC/builder/windows/WindowsBuilder.php | 35 ++++++++++++++++++++++ src/SPC/command/BuildPHPCommand.php | 2 +- src/SPC/store/SourcePatcher.php | 25 ++++++++++++++++ src/globals/test-extensions.php | 24 +++++++-------- 5 files changed, 74 insertions(+), 14 deletions(-) diff --git a/src/SPC/ConsoleApplication.php b/src/SPC/ConsoleApplication.php index ba2d38e0b..da143de1a 100644 --- a/src/SPC/ConsoleApplication.php +++ b/src/SPC/ConsoleApplication.php @@ -34,7 +34,7 @@ */ final class ConsoleApplication extends Application { - public const string VERSION = '2.7.5'; + public const string VERSION = '2.7.6'; public function __construct() { diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index 3f21f639b..cb215f1a0 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -57,6 +57,7 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void $enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM; $enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO; $enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED; + $enableCgi = ($build_target & BUILD_TARGET_CGI) === BUILD_TARGET_CGI; SourcePatcher::patchBeforeBuildconf($this); @@ -109,6 +110,7 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void ($enableCli ? '--enable-cli=yes ' : '--enable-cli=no ') . ($enableMicro ? ('--enable-micro=yes ' . $micro_logo . $micro_w32) : '--enable-micro=no ') . ($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') . + ($enableCgi ? '--enable-cgi=yes ' : '--enable-cgi=no ') . $config_file_scan_dir . $opcache_jit_arg . "{$this->makeStaticExtensionArgs()} " . @@ -127,6 +129,10 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void if ($enableFpm) { logger()->warning('Windows does not support fpm SAPI, I will skip it.'); } + if ($enableCgi) { + logger()->info('building cgi'); + $this->buildCgi(); + } if ($enableMicro) { logger()->info('building micro'); $this->buildMicro(); @@ -159,6 +165,24 @@ public function buildCli(): void $this->deployBinary(BUILD_TARGET_CLI); } + public function buildCgi(): void + { + SourcePatcher::patchWindowsCGITarget(); + + $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; + + // add nmake wrapper + FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo LIBS_CGI=\"ws2_32.lib shell32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*"); + + cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe"); + + // deploy cgi binary + logger()->info('Deploying cgi file'); + FileSystem::createDir(BUILD_ROOT_PATH . '\bin'); + + cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . "\\php-src\\x64\\Release" . ($this->zts ? '_TS' : '') . "\\php-cgi.exe") . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\\php-cgi.exe')); + } + public function buildEmbed(): void { // TODO: add embed support for windows @@ -298,6 +322,17 @@ public function sanityCheck(mixed $build_target): void } } } + + // sanity check for php-cgi + if (($build_target & BUILD_TARGET_CGI) === BUILD_TARGET_CGI) { + logger()->info('running cgi sanity check'); + FileSystem::writeFile(SOURCE_PATH . '\\php-cgi-test.php', 'Hello, World!"; ?>'); + [$ret, $output] = cmd()->execWithResult(BUILD_BIN_PATH . '\\php-cgi.exe -n -f ' . SOURCE_PATH . '\\php-cgi-test.php'); + $raw_output = implode("\n", $output); + if ($ret !== 0 || !str_contains($raw_output, 'Hello, World!')) { + throw new ValidationException("cgi failed sanity check. code: {$ret}, output: {$raw_output}", validation_module: 'php-cgi sanity check'); + } + } } /** diff --git a/src/SPC/command/BuildPHPCommand.php b/src/SPC/command/BuildPHPCommand.php index 3ffc54cef..b57a91997 100644 --- a/src/SPC/command/BuildPHPCommand.php +++ b/src/SPC/command/BuildPHPCommand.php @@ -33,7 +33,7 @@ public function configure(): void $this->addOption('build-fpm', null, null, 'Build fpm SAPI (not available on Windows)'); $this->addOption('build-embed', null, null, 'Build embed SAPI (not available on Windows)'); $this->addOption('build-frankenphp', null, null, 'Build FrankenPHP SAPI (not available on Windows)'); - $this->addOption('build-cgi', null, null, 'Build cgi SAPI (not available on Windows)'); + $this->addOption('build-cgi', null, null, 'Build cgi SAPI'); $this->addOption('build-all', null, null, 'Build all SAPI'); $this->addOption('no-strip', null, null, 'build without strip, keep symbols to debug'); $this->addOption('disable-opcache-jit', null, null, 'disable opcache jit'); diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index c08204f5d..541c04be7 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -549,6 +549,31 @@ public static function patchWindowsCLITarget(): void FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines)); } + /** + * Patch cgi SAPI Makefile for Windows. + */ + public static function patchWindowsCGITarget(): void + { + // search Makefile code line contains "$(BUILD_DIR)\php.exe:" + $content = FileSystem::readFile(SOURCE_PATH . '/php-src/Makefile'); + $lines = explode("\r\n", $content); + $line_num = 0; + $found = false; + foreach ($lines as $v) { + if (str_contains($v, '$(BUILD_DIR)\php-cgi.exe:')) { + $found = $line_num; + break; + } + ++$line_num; + } + if ($found === false) { + throw new PatchException('Windows Makefile patching for php-cgi.exe target', 'Cannot patch windows CGI Makefile, Makefile does not contain "$(BUILD_DIR)\php-cgi.exe:" line'); + } + $lines[$line_num] = '$(BUILD_DIR)\php-cgi.exe: generated_files $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest'; + $lines[$line_num + 1] = "\t" . '@"$(LINK)" /nologo $(PHP_GLOBAL_OBJS_RESP) $(CGI_GLOBAL_OBJS_RESP) $(STATIC_EXT_OBJS_RESP) $(STATIC_EXT_LIBS) $(ASM_OBJS) $(LIBS) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) /ltcg /nodefaultlib:msvcrt /nodefaultlib:msvcrtd /ignore:4286'; + FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines)); + } + public static function patchPhpLibxml212(): bool { $file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h'); diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 99e4e31ba..7f3131d56 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -13,9 +13,9 @@ // test php version (8.1 ~ 8.4 available, multiple for matrix) $test_php_version = [ - // '8.1', - // '8.2', - // '8.3', + '8.1', + '8.2', + '8.3', '8.4', // '8.5', // 'git', @@ -23,18 +23,18 @@ // test os (macos-15-intel, macos-15, ubuntu-latest, windows-latest are available) $test_os = [ - 'macos-15-intel', // bin/spc for x86_64 - 'macos-15', // bin/spc for arm64 + // 'macos-15-intel', // bin/spc for x86_64 + // 'macos-15', // bin/spc for arm64 // 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 - 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 - 'ubuntu-24.04', // bin/spc for x86_64 - 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64 - 'ubuntu-24.04-arm', // bin/spc for arm64 - // 'windows-latest', // .\bin\spc.ps1 + // 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 + // 'ubuntu-24.04', // bin/spc for x86_64 + // 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64 + // 'ubuntu-24.04-arm', // bin/spc for arm64 + 'windows-latest', // .\bin\spc.ps1 ]; // whether enable thread safe -$zts = false; +$zts = true; $no_strip = false; @@ -208,7 +208,7 @@ function quote2(string $param): string passthru($prefix . $down_cmd, $retcode); break; case 'build_cmd': - passthru($prefix . $build_cmd . ' --build-cli --build-micro', $retcode); + passthru($prefix . $build_cmd . ' --build-cli --build-micro --build-cgi', $retcode); break; case 'build_embed_cmd': if ($frankenphp) { From b62f029da72c04f87920f1b9492bbce71bab2a78 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 00:56:28 +0800 Subject: [PATCH 02/20] cs fix --- src/SPC/builder/windows/WindowsBuilder.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index cb215f1a0..8ab746489 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -180,7 +180,7 @@ public function buildCgi(): void logger()->info('Deploying cgi file'); FileSystem::createDir(BUILD_ROOT_PATH . '\bin'); - cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . "\\php-src\\x64\\Release" . ($this->zts ? '_TS' : '') . "\\php-cgi.exe") . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\\php-cgi.exe')); + cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . '\\php-src\\x64\\Release' . ($this->zts ? '_TS' : '') . '\\php-cgi.exe') . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\php-cgi.exe')); } public function buildEmbed(): void @@ -326,8 +326,8 @@ public function sanityCheck(mixed $build_target): void // sanity check for php-cgi if (($build_target & BUILD_TARGET_CGI) === BUILD_TARGET_CGI) { logger()->info('running cgi sanity check'); - FileSystem::writeFile(SOURCE_PATH . '\\php-cgi-test.php', 'Hello, World!"; ?>'); - [$ret, $output] = cmd()->execWithResult(BUILD_BIN_PATH . '\\php-cgi.exe -n -f ' . SOURCE_PATH . '\\php-cgi-test.php'); + FileSystem::writeFile(SOURCE_PATH . '\php-cgi-test.php', 'Hello, World!"; ?>'); + [$ret, $output] = cmd()->execWithResult(BUILD_BIN_PATH . '\php-cgi.exe -n -f ' . SOURCE_PATH . '\php-cgi-test.php'); $raw_output = implode("\n", $output); if ($ret !== 0 || !str_contains($raw_output, 'Hello, World!')) { throw new ValidationException("cgi failed sanity check. code: {$ret}, output: {$raw_output}", validation_module: 'php-cgi sanity check'); From 9c8fd4d45de4ce2bb0c9b05e3c7ecbc69490c288 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 00:59:33 +0800 Subject: [PATCH 03/20] cs fix --- src/SPC/builder/windows/WindowsBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index 8ab746489..df0357b13 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -180,7 +180,7 @@ public function buildCgi(): void logger()->info('Deploying cgi file'); FileSystem::createDir(BUILD_ROOT_PATH . '\bin'); - cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . '\\php-src\\x64\\Release' . ($this->zts ? '_TS' : '') . '\\php-cgi.exe') . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\php-cgi.exe')); + cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . '\php-src\x64\Release' . ($this->zts ? '_TS' : '') . '\php-cgi.exe') . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\php-cgi.exe')); } public function buildEmbed(): void From 4b28d1c2dfda3c874cb9ab0807ed26d131c032f6 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:04:42 +0800 Subject: [PATCH 04/20] test --- src/globals/test-extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 7f3131d56..fd3f5dfff 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -30,7 +30,7 @@ // 'ubuntu-24.04', // bin/spc for x86_64 // 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64 // 'ubuntu-24.04-arm', // bin/spc for arm64 - 'windows-latest', // .\bin\spc.ps1 + 'windows-2022', // .\bin\spc.ps1 ]; // whether enable thread safe From 1d960a9084fd38d115e6dbff505a4b9ee9ec9bb2 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:05:06 +0800 Subject: [PATCH 05/20] test --- src/globals/test-extensions.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index fd3f5dfff..037a99926 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -27,10 +27,11 @@ // 'macos-15', // bin/spc for arm64 // 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 // 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 - // 'ubuntu-24.04', // bin/spc for x86_64 + 'ubuntu-24.04', // bin/spc for x86_64 // 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64 // 'ubuntu-24.04-arm', // bin/spc for arm64 'windows-2022', // .\bin\spc.ps1 + 'windows-2025', ]; // whether enable thread safe From 572bf919aac555f7157c8c3b4cff5f0026733694 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:13:26 +0800 Subject: [PATCH 06/20] test --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8accd62fb..811079d75 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -179,7 +179,7 @@ jobs: key: php-dependencies-${{ matrix.os }} - name: "Install Dependencies" - run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + run: composer update -vvv --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist - name: "Run Build Tests (doctor)" run: php src/globals/test-extensions.php doctor_cmd ${{ matrix.os }} ${{ matrix.php }} From 5b319b0df199b9b08c07e9ce9093841a7fb1e4d2 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:16:22 +0800 Subject: [PATCH 07/20] test --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 811079d75..a94bd64f6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -179,7 +179,7 @@ jobs: key: php-dependencies-${{ matrix.os }} - name: "Install Dependencies" - run: composer update -vvv --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + run: composer update -vvv --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-plugins - name: "Run Build Tests (doctor)" run: php src/globals/test-extensions.php doctor_cmd ${{ matrix.os }} ${{ matrix.php }} From 9b53133ba49dbdbdf16e9747adb1b051bc687a3e Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:19:10 +0800 Subject: [PATCH 08/20] test --- src/globals/test-extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 037a99926..c17aa2507 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -62,7 +62,7 @@ }; // If you want to test lib-suggests for all extensions and libraries, set it to true. -$with_suggested_libs = true; +$with_suggested_libs = false; // If you want to test extra libs for extensions, add them below (comma separated, example `libwebp,libavif`). Unnecessary, when $with_suggested_libs is true. $with_libs = match (PHP_OS_FAMILY) { From 6a98a6bf5e7f392063cbf70aab7669d2615e9625 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:32:56 +0800 Subject: [PATCH 09/20] Use BUILD_BIN_PATH instead --- src/SPC/builder/windows/WindowsBuilder.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index df0357b13..9633b2e91 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -178,9 +178,9 @@ public function buildCgi(): void // deploy cgi binary logger()->info('Deploying cgi file'); - FileSystem::createDir(BUILD_ROOT_PATH . '\bin'); + FileSystem::createDir(BUILD_BIN_PATH); - cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . '\php-src\x64\Release' . ($this->zts ? '_TS' : '') . '\php-cgi.exe') . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\php-cgi.exe')); + cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . '\php-src\x64\Release' . ($this->zts ? '_TS' : '') . '\php-cgi.exe') . ' ' . escapeshellarg(BUILD_BIN_PATH . '\php-cgi.exe')); } public function buildEmbed(): void @@ -289,7 +289,7 @@ public function sanityCheck(mixed $build_target): void // sanity check for php-cli if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { logger()->info('running cli sanity check'); - [$ret, $output] = cmd()->execWithResult(BUILD_ROOT_PATH . '\bin\php.exe -n -r "echo \"hello\";"'); + [$ret, $output] = cmd()->execWithResult(BUILD_BIN_PATH . '\php.exe -n -r "echo \"hello\";"'); if ($ret !== 0 || trim(implode('', $output)) !== 'hello') { throw new ValidationException('cli failed sanity check', validation_module: 'php-cli function check'); } @@ -308,7 +308,7 @@ public function sanityCheck(mixed $build_target): void if (file_exists($test_file)) { @unlink($test_file); } - file_put_contents($test_file, file_get_contents(BUILD_ROOT_PATH . '\bin\micro.sfx') . $task['content']); + file_put_contents($test_file, file_get_contents(BUILD_BIN_PATH . '\micro.sfx') . $task['content']); chmod($test_file, 0755); [$ret, $out] = cmd()->execWithResult($test_file); foreach ($task['conditions'] as $condition => $closure) { @@ -357,9 +357,9 @@ public function deployBinary(int $type): bool } logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file'); - FileSystem::createDir(BUILD_ROOT_PATH . '\bin'); + FileSystem::createDir(BUILD_BIN_PATH); - cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\\')); + cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_BIN_PATH . '\\')); return true; } From e559dce9d5a042f637702bffd7dd7a20db753690 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:35:30 +0800 Subject: [PATCH 10/20] Reduce tests --- src/globals/test-extensions.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index c17aa2507..a73adde20 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -27,10 +27,10 @@ // 'macos-15', // bin/spc for arm64 // 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 // 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 - 'ubuntu-24.04', // bin/spc for x86_64 + // 'ubuntu-24.04', // bin/spc for x86_64 // 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64 // 'ubuntu-24.04-arm', // bin/spc for arm64 - 'windows-2022', // .\bin\spc.ps1 + // 'windows-2022', // .\bin\spc.ps1 'windows-2025', ]; @@ -51,7 +51,7 @@ // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { 'Linux', 'Darwin' => 'pdo_pgsql', - 'Windows' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pdo,pdo_mysql,pdo_sqlite,phar,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip', + 'Windows' => 'bcmath,bz2,calendar,ctype,mbstring,mbregex', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). From 70bda268e5815d24fe1979d250c845987dfdb09c Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 01:51:22 +0800 Subject: [PATCH 11/20] Fix patches, add more debug comments --- src/SPC/store/SourcePatcher.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index 541c04be7..8deeeeeef 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -569,8 +569,13 @@ public static function patchWindowsCGITarget(): void if ($found === false) { throw new PatchException('Windows Makefile patching for php-cgi.exe target', 'Cannot patch windows CGI Makefile, Makefile does not contain "$(BUILD_DIR)\php-cgi.exe:" line'); } + // cli: $(BUILD_DIR)\php.exe: $(DEPS_CLI) $(CLI_GLOBAL_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php.exe.res $(BUILD_DIR)\php.exe.manifest + // $lines[$line_num] = '$(BUILD_DIR)\php.exe: generated_files $(DEPS_CLI) $(CLI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\php.exe.res $(BUILD_DIR)\php.exe.manifest'; + // cgi: $(BUILD_DIR)\php-cgi.exe: $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest $lines[$line_num] = '$(BUILD_DIR)\php-cgi.exe: generated_files $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest'; - $lines[$line_num + 1] = "\t" . '@"$(LINK)" /nologo $(PHP_GLOBAL_OBJS_RESP) $(CGI_GLOBAL_OBJS_RESP) $(STATIC_EXT_OBJS_RESP) $(STATIC_EXT_LIBS) $(ASM_OBJS) $(LIBS) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) /ltcg /nodefaultlib:msvcrt /nodefaultlib:msvcrtd /ignore:4286'; + + // cli: @"$(LINK)" /nologo $(CGI_GLOBAL_OBJS_RESP) $(BUILD_DIR)\$(PHPLIB) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) + $lines[$line_num + 1] = "\t" . '@"$(LINK)" /nologo $(PHP_GLOBAL_OBJS_RESP) $(CGI_GLOBAL_OBJS_RESP) $(BUILD_DIR)\$(PHPLIB) $(STATIC_EXT_OBJS_RESP) $(STATIC_EXT_LIBS) $(ASM_OBJS) $(LIBS) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) /ltcg /nodefaultlib:msvcrt /nodefaultlib:msvcrtd /ignore:4286'; FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines)); } From 4f8b9d0f818d3906d98ff03fac767bf340b6f448 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 02:18:24 +0800 Subject: [PATCH 12/20] Fix patches --- src/SPC/builder/windows/WindowsBuilder.php | 2 +- src/SPC/store/SourcePatcher.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index 9633b2e91..bd218fb5c 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -172,7 +172,7 @@ public function buildCgi(): void $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; // add nmake wrapper - FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo LIBS_CGI=\"ws2_32.lib shell32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*"); + FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo LIBS_CGI=\"ws2_32.lib kernel32.lib advapi32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*"); cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe"); diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index 8deeeeeef..b9dcf1a09 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -572,10 +572,10 @@ public static function patchWindowsCGITarget(): void // cli: $(BUILD_DIR)\php.exe: $(DEPS_CLI) $(CLI_GLOBAL_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php.exe.res $(BUILD_DIR)\php.exe.manifest // $lines[$line_num] = '$(BUILD_DIR)\php.exe: generated_files $(DEPS_CLI) $(CLI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\php.exe.res $(BUILD_DIR)\php.exe.manifest'; // cgi: $(BUILD_DIR)\php-cgi.exe: $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest - $lines[$line_num] = '$(BUILD_DIR)\php-cgi.exe: generated_files $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest'; + $lines[$line_num] = '$(BUILD_DIR)\php-cgi.exe: $(DEPS_CGI) $(CGI_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\php-cgi.exe.res $(BUILD_DIR)\php-cgi.exe.manifest'; // cli: @"$(LINK)" /nologo $(CGI_GLOBAL_OBJS_RESP) $(BUILD_DIR)\$(PHPLIB) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) - $lines[$line_num + 1] = "\t" . '@"$(LINK)" /nologo $(PHP_GLOBAL_OBJS_RESP) $(CGI_GLOBAL_OBJS_RESP) $(BUILD_DIR)\$(PHPLIB) $(STATIC_EXT_OBJS_RESP) $(STATIC_EXT_LIBS) $(ASM_OBJS) $(LIBS) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) /ltcg /nodefaultlib:msvcrt /nodefaultlib:msvcrtd /ignore:4286'; + $lines[$line_num + 1] = "\t" . '@"$(LINK)" /nologo $(PHP_GLOBAL_OBJS_RESP) $(CGI_GLOBAL_OBJS_RESP) $(STATIC_EXT_OBJS_RESP) $(STATIC_EXT_LIBS) $(ASM_OBJS) $(LIBS) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) /ltcg /nodefaultlib:msvcrt /nodefaultlib:msvcrtd /ignore:4286'; FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines)); } From bf7913440568634ec83e3ad043ff3270fcd3bbfb Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 20:42:26 +0800 Subject: [PATCH 13/20] Fix tsrmls cache define patches --- src/SPC/store/SourcePatcher.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index b9dcf1a09..694d87ef1 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -577,6 +577,9 @@ public static function patchWindowsCGITarget(): void // cli: @"$(LINK)" /nologo $(CGI_GLOBAL_OBJS_RESP) $(BUILD_DIR)\$(PHPLIB) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) $lines[$line_num + 1] = "\t" . '@"$(LINK)" /nologo $(PHP_GLOBAL_OBJS_RESP) $(CGI_GLOBAL_OBJS_RESP) $(STATIC_EXT_OBJS_RESP) $(STATIC_EXT_LIBS) $(ASM_OBJS) $(LIBS) $(LIBS_CGI) $(BUILD_DIR)\php-cgi.exe.res /out:$(BUILD_DIR)\php-cgi.exe $(LDFLAGS) $(LDFLAGS_CGI) /ltcg /nodefaultlib:msvcrt /nodefaultlib:msvcrtd /ignore:4286'; FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines)); + + // Patch cgi-static, comment ZEND_TSRMLS_CACHE_DEFINE() + FileSystem::replaceFileRegex(SOURCE_PATH . '\php-src\sapi\cgi\cgi_main.c', '/^ZEND_TSRMLS_CACHE_DEFINE\(\)/m', '// ZEND_TSRMLS_CACHE_DEFINE()'); } public static function patchPhpLibxml212(): bool From dc4dd6ffa47eb80a6b2c846dbb9513c8c2832751 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Oct 2025 20:52:20 +0800 Subject: [PATCH 14/20] Full test --- src/globals/test-extensions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index a73adde20..bea497beb 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -17,7 +17,7 @@ '8.2', '8.3', '8.4', - // '8.5', + '8.5', // 'git', ]; @@ -51,7 +51,7 @@ // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { 'Linux', 'Darwin' => 'pdo_pgsql', - 'Windows' => 'bcmath,bz2,calendar,ctype,mbstring,mbregex', + 'Windows' => 'bcmath,bz2,calendar,ctype,curl,dba,dom,ds,exif,ffi,fileinfo,filter,ftp,gd,iconv,igbinary,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yaml,zip,zlib', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). From 6440863ce416c16f414ecabd819008f399483124 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 17 Oct 2025 09:25:44 +0800 Subject: [PATCH 15/20] Remove igbinary --- src/globals/test-extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index bea497beb..99dbb78e6 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -51,7 +51,7 @@ // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { 'Linux', 'Darwin' => 'pdo_pgsql', - 'Windows' => 'bcmath,bz2,calendar,ctype,curl,dba,dom,ds,exif,ffi,fileinfo,filter,ftp,gd,iconv,igbinary,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yaml,zip,zlib', + 'Windows' => 'bcmath,bz2,calendar,ctype,curl,dba,dom,ds,exif,ffi,fileinfo,filter,ftp,gd,iconv,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yaml,zip,zlib', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). From 4be894bc1099f2bb0e30066e36e9cfd73d5000da Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 17 Oct 2025 10:15:05 +0800 Subject: [PATCH 16/20] Remove ds and gd test --- src/globals/test-extensions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index 99dbb78e6..f5855dc8d 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -51,7 +51,7 @@ // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { 'Linux', 'Darwin' => 'pdo_pgsql', - 'Windows' => 'bcmath,bz2,calendar,ctype,curl,dba,dom,ds,exif,ffi,fileinfo,filter,ftp,gd,iconv,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yaml,zip,zlib', + 'Windows' => 'bcmath,bz2,calendar,ctype,curl,dba,dom,exif,ffi,fileinfo,filter,ftp,iconv,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yaml,zip,zlib', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). From b59a06facebeb35e4476374c1cc7943604079eb3 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 25 Oct 2025 02:56:38 +0800 Subject: [PATCH 17/20] Add backward patches for win32 --- src/SPC/store/SourcePatcher.php | 17 ++++ src/globals/patch/php_win32_time.patch | 110 +++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/globals/patch/php_win32_time.patch diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index 7b72ad1b7..d9bae08b5 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -23,6 +23,7 @@ public static function init(): void FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchPhpLibxml212']); FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchGDWin32']); FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchFfiCentos7FixO3strncmp']); + FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchWin32Time']); FileSystem::addSourceExtractHook('sqlsrv', [__CLASS__, 'patchSQLSRVWin32']); FileSystem::addSourceExtractHook('pdo_sqlsrv', [__CLASS__, 'patchSQLSRVWin32']); FileSystem::addSourceExtractHook('yaml', [__CLASS__, 'patchYamlWin32']); @@ -500,6 +501,22 @@ public static function patchFfiCentos7FixO3strncmp(): bool return true; } + public static function patchWin32Time(): bool + { + if (PHP_OS_FAMILY !== 'Windows') { + return false; + } + if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) { + return false; + } + $file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h'); + if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0 && intval($match[1]) < 80400) { + self::patchFile('php_win32_time.patch', SOURCE_PATH . '/php-src'); + return true; + } + return false; + } + public static function patchPkgConfigForGcc15(): bool { self::patchFile('pkg-config_gcc15.patch', SOURCE_PATH . '/pkg-config'); diff --git a/src/globals/patch/php_win32_time.patch b/src/globals/patch/php_win32_time.patch new file mode 100644 index 000000000..28766378f --- /dev/null +++ b/src/globals/patch/php_win32_time.patch @@ -0,0 +1,110 @@ +From d919783778c6d2310285e657fd0c3612238bf6ac Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Wed, 14 Aug 2024 13:02:12 +0200 +Subject: [PATCH 1/2] GetSystemTimePreciseAsFileTime() is now always available + +As of PHP 8.3.0, we require Windows Server 2012 or Windows 8 as bare +minimum. Since GetSystemTimePreciseAsFileTime() is always available on +these Windows versions[1], there is no more need for the workaround +described in dllmain.c; we just can call the function directly. + +[1] +--- + win32/dllmain.c | 14 -------------- + win32/time.c | 29 +---------------------------- + 2 files changed, 1 insertion(+), 42 deletions(-) + +diff --git a/win32/dllmain.c b/win32/dllmain.c +index a507f1e169246..ab625bf3e597b 100644 +--- a/win32/dllmain.c ++++ b/win32/dllmain.c +@@ -38,20 +38,6 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID dummy) + switch (reason) + { + case DLL_PROCESS_ATTACH: +- /* +- * We do not need to check the return value of php_win32_init_gettimeofday() +- * because the symbol bare minimum symbol we need is always available on our +- * lowest supported platform. +- * +- * On Windows 8 or greater, we use a more precise symbol to obtain the system +- * time, which is dynamically. The fallback allows us to proper support +- * Vista/7/Server 2003 R2/Server 2008/Server 2008 R2. +- * +- * Instead simply initialize the global in win32/time.c for gettimeofday() +- * use later on +- */ +- php_win32_init_gettimeofday(); +- + ret = ret && php_win32_ioutil_init(); + if (!ret) { + fprintf(stderr, "ioutil initialization failed"); +diff --git a/win32/time.c b/win32/time.c +index d1fe51458ec57..af02ee96a10e7 100644 +--- a/win32/time.c ++++ b/win32/time.c +@@ -25,40 +25,13 @@ + + typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); + +-static MyGetSystemTimeAsFileTime timefunc = NULL; +- +-#ifdef PHP_EXPORTS +-static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void) +-{/*{{{*/ +- MyGetSystemTimeAsFileTime timefunc = NULL; +- HMODULE hMod = GetModuleHandle("kernel32.dll"); +- +- if (hMod) { +- /* Max possible resolution <1us, win8/server2012 */ +- timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); +- } +- +- if(!timefunc) { +- /* 100ns blocks since 01-Jan-1641 */ +- timefunc = (MyGetSystemTimeAsFileTime) GetSystemTimeAsFileTime; +- } +- +- return timefunc; +-}/*}}}*/ +- +-void php_win32_init_gettimeofday(void) +-{/*{{{*/ +- timefunc = get_time_func(); +-}/*}}}*/ +-#endif +- + static zend_always_inline int getfilesystemtime(struct timeval *tv) + {/*{{{*/ + FILETIME ft; + unsigned __int64 ff = 0; + ULARGE_INTEGER fft; + +- timefunc(&ft); ++ GetSystemTimePreciseAsFileTime(&ft); + + /* + * Do not cast a pointer to a FILETIME structure to either a + +From b357bc794b0dafe9cee3f09972ba596ac4610d01 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Wed, 14 Aug 2024 13:12:24 +0200 +Subject: [PATCH 2/2] Remove now unused typedef + +--- + win32/time.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/win32/time.c b/win32/time.c +index af02ee96a10e7..57db914e6a8f6 100644 +--- a/win32/time.c ++++ b/win32/time.c +@@ -23,8 +23,6 @@ + #include + #include "php_win32_globals.h" + +-typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); +- + static zend_always_inline int getfilesystemtime(struct timeval *tv) + {/*{{{*/ + FILETIME ft; From bab330b64eae068d47f6bb67784ce0d768b2a7f6 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 25 Oct 2025 03:03:40 +0800 Subject: [PATCH 18/20] Unify CGI deploy functions --- src/SPC/builder/windows/WindowsBuilder.php | 9 +++------ src/SPC/store/SourcePatcher.php | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index bd218fb5c..76489b02b 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -176,11 +176,7 @@ public function buildCgi(): void cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe"); - // deploy cgi binary - logger()->info('Deploying cgi file'); - FileSystem::createDir(BUILD_BIN_PATH); - - cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . '\php-src\x64\Release' . ($this->zts ? '_TS' : '') . '\php-cgi.exe') . ' ' . escapeshellarg(BUILD_BIN_PATH . '\php-cgi.exe')); + $this->deployBinary(BUILD_TARGET_CGI); } public function buildEmbed(): void @@ -346,12 +342,13 @@ public function deployBinary(int $type): bool $src = match ($type) { BUILD_TARGET_CLI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php.exe", BUILD_TARGET_MICRO => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\micro.sfx", + BUILD_TARGET_CGI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php-cgi.exe", default => throw new SPCInternalException("Deployment does not accept type {$type}"), }; // with-upx-pack for cli and micro if ($this->getOption('with-upx-pack', false)) { - if ($type === BUILD_TARGET_CLI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) { + if ($type === BUILD_TARGET_CLI || $type === BUILD_TARGET_CGI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) { cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src)); } } diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index d9bae08b5..1ffe98ead 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -571,7 +571,7 @@ public static function patchWindowsCLITarget(): void */ public static function patchWindowsCGITarget(): void { - // search Makefile code line contains "$(BUILD_DIR)\php.exe:" + // search Makefile code line contains "$(BUILD_DIR)\php-cgi.exe:" $content = FileSystem::readFile(SOURCE_PATH . '/php-src/Makefile'); $lines = explode("\r\n", $content); $line_num = 0; From f426ced78997d148905765848e31ca18edeae5ba Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 25 Oct 2025 13:42:04 +0800 Subject: [PATCH 19/20] Use phpmicro patches instead --- config/env.ini | 2 +- config/source.json | 2 +- src/SPC/store/SourcePatcher.php | 17 ---- src/globals/patch/php_win32_time.patch | 110 ------------------------- 4 files changed, 2 insertions(+), 129 deletions(-) delete mode 100644 src/globals/patch/php_win32_time.patch diff --git a/config/env.ini b/config/env.ini index 044de07b7..a1f149c59 100644 --- a/config/env.ini +++ b/config/env.ini @@ -65,7 +65,7 @@ PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools" ; upx executable path UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe" ; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches -SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static +SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static,win32_api [linux] ; Linux can use different build toolchains. diff --git a/config/source.json b/config/source.json index 349ba68cf..fd0301be7 100644 --- a/config/source.json +++ b/config/source.json @@ -762,7 +762,7 @@ "micro": { "type": "git", "path": "php-src/sapi/micro", - "rev": "php-85-win", + "rev": "master", "url": "https://github.com/static-php/phpmicro", "license": { "type": "file", diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index 1ffe98ead..f628544fe 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -23,7 +23,6 @@ public static function init(): void FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchPhpLibxml212']); FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchGDWin32']); FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchFfiCentos7FixO3strncmp']); - FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchWin32Time']); FileSystem::addSourceExtractHook('sqlsrv', [__CLASS__, 'patchSQLSRVWin32']); FileSystem::addSourceExtractHook('pdo_sqlsrv', [__CLASS__, 'patchSQLSRVWin32']); FileSystem::addSourceExtractHook('yaml', [__CLASS__, 'patchYamlWin32']); @@ -501,22 +500,6 @@ public static function patchFfiCentos7FixO3strncmp(): bool return true; } - public static function patchWin32Time(): bool - { - if (PHP_OS_FAMILY !== 'Windows') { - return false; - } - if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) { - return false; - } - $file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h'); - if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0 && intval($match[1]) < 80400) { - self::patchFile('php_win32_time.patch', SOURCE_PATH . '/php-src'); - return true; - } - return false; - } - public static function patchPkgConfigForGcc15(): bool { self::patchFile('pkg-config_gcc15.patch', SOURCE_PATH . '/pkg-config'); diff --git a/src/globals/patch/php_win32_time.patch b/src/globals/patch/php_win32_time.patch deleted file mode 100644 index 28766378f..000000000 --- a/src/globals/patch/php_win32_time.patch +++ /dev/null @@ -1,110 +0,0 @@ -From d919783778c6d2310285e657fd0c3612238bf6ac Mon Sep 17 00:00:00 2001 -From: "Christoph M. Becker" -Date: Wed, 14 Aug 2024 13:02:12 +0200 -Subject: [PATCH 1/2] GetSystemTimePreciseAsFileTime() is now always available - -As of PHP 8.3.0, we require Windows Server 2012 or Windows 8 as bare -minimum. Since GetSystemTimePreciseAsFileTime() is always available on -these Windows versions[1], there is no more need for the workaround -described in dllmain.c; we just can call the function directly. - -[1] ---- - win32/dllmain.c | 14 -------------- - win32/time.c | 29 +---------------------------- - 2 files changed, 1 insertion(+), 42 deletions(-) - -diff --git a/win32/dllmain.c b/win32/dllmain.c -index a507f1e169246..ab625bf3e597b 100644 ---- a/win32/dllmain.c -+++ b/win32/dllmain.c -@@ -38,20 +38,6 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID dummy) - switch (reason) - { - case DLL_PROCESS_ATTACH: -- /* -- * We do not need to check the return value of php_win32_init_gettimeofday() -- * because the symbol bare minimum symbol we need is always available on our -- * lowest supported platform. -- * -- * On Windows 8 or greater, we use a more precise symbol to obtain the system -- * time, which is dynamically. The fallback allows us to proper support -- * Vista/7/Server 2003 R2/Server 2008/Server 2008 R2. -- * -- * Instead simply initialize the global in win32/time.c for gettimeofday() -- * use later on -- */ -- php_win32_init_gettimeofday(); -- - ret = ret && php_win32_ioutil_init(); - if (!ret) { - fprintf(stderr, "ioutil initialization failed"); -diff --git a/win32/time.c b/win32/time.c -index d1fe51458ec57..af02ee96a10e7 100644 ---- a/win32/time.c -+++ b/win32/time.c -@@ -25,40 +25,13 @@ - - typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); - --static MyGetSystemTimeAsFileTime timefunc = NULL; -- --#ifdef PHP_EXPORTS --static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void) --{/*{{{*/ -- MyGetSystemTimeAsFileTime timefunc = NULL; -- HMODULE hMod = GetModuleHandle("kernel32.dll"); -- -- if (hMod) { -- /* Max possible resolution <1us, win8/server2012 */ -- timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); -- } -- -- if(!timefunc) { -- /* 100ns blocks since 01-Jan-1641 */ -- timefunc = (MyGetSystemTimeAsFileTime) GetSystemTimeAsFileTime; -- } -- -- return timefunc; --}/*}}}*/ -- --void php_win32_init_gettimeofday(void) --{/*{{{*/ -- timefunc = get_time_func(); --}/*}}}*/ --#endif -- - static zend_always_inline int getfilesystemtime(struct timeval *tv) - {/*{{{*/ - FILETIME ft; - unsigned __int64 ff = 0; - ULARGE_INTEGER fft; - -- timefunc(&ft); -+ GetSystemTimePreciseAsFileTime(&ft); - - /* - * Do not cast a pointer to a FILETIME structure to either a - -From b357bc794b0dafe9cee3f09972ba596ac4610d01 Mon Sep 17 00:00:00 2001 -From: "Christoph M. Becker" -Date: Wed, 14 Aug 2024 13:12:24 +0200 -Subject: [PATCH 2/2] Remove now unused typedef - ---- - win32/time.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/win32/time.c b/win32/time.c -index af02ee96a10e7..57db914e6a8f6 100644 ---- a/win32/time.c -+++ b/win32/time.c -@@ -23,8 +23,6 @@ - #include - #include "php_win32_globals.h" - --typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime); -- - static zend_always_inline int getfilesystemtime(struct timeval *tv) - {/*{{{*/ - FILETIME ft; From 09198b431f37a6307c7dbdee450a8e58f1c06c3a Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 25 Oct 2025 15:41:48 +0800 Subject: [PATCH 20/20] Use unified configure args format --- src/SPC/builder/windows/WindowsBuilder.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index 76489b02b..1892d8014 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -103,14 +103,13 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void ->exec( "{$this->sdk_prefix} configure.bat --task-args \"" . '--disable-all ' . - '--disable-cgi ' . '--with-php-build=' . BUILD_ROOT_PATH . ' ' . '--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 . $micro_w32) : '--enable-micro=no ') . - ($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') . - ($enableCgi ? '--enable-cgi=yes ' : '--enable-cgi=no ') . + ($enableCli ? '--enable-cli ' : '--disable-cli ') . + ($enableMicro ? ('--enable-micro ' . $micro_logo . $micro_w32) : '--disable-micro ') . + ($enableEmbed ? '--enable-embed ' : '--disable-embed ') . + ($enableCgi ? '--enable-cgi ' : '--disable-cgi ') . $config_file_scan_dir . $opcache_jit_arg . "{$this->makeStaticExtensionArgs()} " .