Add Windows CGI SAPI build support

This commit is contained in:
crazywhalecc
2025-10-16 00:55:21 +08:00
parent 487c6da4ac
commit c711a3666e
5 changed files with 74 additions and 14 deletions

View File

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

View File

@@ -57,6 +57,7 @@ class WindowsBuilder extends BuilderBase
$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 @@ class WindowsBuilder extends BuilderBase
($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 @@ class WindowsBuilder extends BuilderBase
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 @@ class WindowsBuilder extends BuilderBase
$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 @@ class WindowsBuilder extends BuilderBase
}
}
}
// 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', '<?php echo "<h1>Hello, World!</h1>"; ?>');
[$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');
}
}
}
/**

View File

@@ -33,7 +33,7 @@ class BuildPHPCommand extends BuildCommand
$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');

View File

@@ -549,6 +549,31 @@ class SourcePatcher
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');