Skip to content

Commit c711a36

Browse files
committed
Add Windows CGI SAPI build support
1 parent 487c6da commit c711a36

File tree

5 files changed

+74
-14
lines changed

5 files changed

+74
-14
lines changed

src/SPC/ConsoleApplication.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
*/
3535
final class ConsoleApplication extends Application
3636
{
37-
public const string VERSION = '2.7.5';
37+
public const string VERSION = '2.7.6';
3838

3939
public function __construct()
4040
{

src/SPC/builder/windows/WindowsBuilder.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
5757
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
5858
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
5959
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
60+
$enableCgi = ($build_target & BUILD_TARGET_CGI) === BUILD_TARGET_CGI;
6061

6162
SourcePatcher::patchBeforeBuildconf($this);
6263

@@ -109,6 +110,7 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
109110
($enableCli ? '--enable-cli=yes ' : '--enable-cli=no ') .
110111
($enableMicro ? ('--enable-micro=yes ' . $micro_logo . $micro_w32) : '--enable-micro=no ') .
111112
($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
113+
($enableCgi ? '--enable-cgi=yes ' : '--enable-cgi=no ') .
112114
$config_file_scan_dir .
113115
$opcache_jit_arg .
114116
"{$this->makeStaticExtensionArgs()} " .
@@ -127,6 +129,10 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
127129
if ($enableFpm) {
128130
logger()->warning('Windows does not support fpm SAPI, I will skip it.');
129131
}
132+
if ($enableCgi) {
133+
logger()->info('building cgi');
134+
$this->buildCgi();
135+
}
130136
if ($enableMicro) {
131137
logger()->info('building micro');
132138
$this->buildMicro();
@@ -159,6 +165,24 @@ public function buildCli(): void
159165
$this->deployBinary(BUILD_TARGET_CLI);
160166
}
161167

168+
public function buildCgi(): void
169+
{
170+
SourcePatcher::patchWindowsCGITarget();
171+
172+
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
173+
174+
// add nmake wrapper
175+
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= %*");
176+
177+
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe");
178+
179+
// deploy cgi binary
180+
logger()->info('Deploying cgi file');
181+
FileSystem::createDir(BUILD_ROOT_PATH . '\bin');
182+
183+
cmd()->exec('copy ' . escapeshellarg(SOURCE_PATH . "\\php-src\\x64\\Release" . ($this->zts ? '_TS' : '') . "\\php-cgi.exe") . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\\php-cgi.exe'));
184+
}
185+
162186
public function buildEmbed(): void
163187
{
164188
// TODO: add embed support for windows
@@ -298,6 +322,17 @@ public function sanityCheck(mixed $build_target): void
298322
}
299323
}
300324
}
325+
326+
// sanity check for php-cgi
327+
if (($build_target & BUILD_TARGET_CGI) === BUILD_TARGET_CGI) {
328+
logger()->info('running cgi sanity check');
329+
FileSystem::writeFile(SOURCE_PATH . '\\php-cgi-test.php', '<?php echo "<h1>Hello, World!</h1>"; ?>');
330+
[$ret, $output] = cmd()->execWithResult(BUILD_BIN_PATH . '\\php-cgi.exe -n -f ' . SOURCE_PATH . '\\php-cgi-test.php');
331+
$raw_output = implode("\n", $output);
332+
if ($ret !== 0 || !str_contains($raw_output, 'Hello, World!')) {
333+
throw new ValidationException("cgi failed sanity check. code: {$ret}, output: {$raw_output}", validation_module: 'php-cgi sanity check');
334+
}
335+
}
301336
}
302337

303338
/**

src/SPC/command/BuildPHPCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function configure(): void
3333
$this->addOption('build-fpm', null, null, 'Build fpm SAPI (not available on Windows)');
3434
$this->addOption('build-embed', null, null, 'Build embed SAPI (not available on Windows)');
3535
$this->addOption('build-frankenphp', null, null, 'Build FrankenPHP SAPI (not available on Windows)');
36-
$this->addOption('build-cgi', null, null, 'Build cgi SAPI (not available on Windows)');
36+
$this->addOption('build-cgi', null, null, 'Build cgi SAPI');
3737
$this->addOption('build-all', null, null, 'Build all SAPI');
3838
$this->addOption('no-strip', null, null, 'build without strip, keep symbols to debug');
3939
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');

src/SPC/store/SourcePatcher.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,31 @@ public static function patchWindowsCLITarget(): void
549549
FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines));
550550
}
551551

552+
/**
553+
* Patch cgi SAPI Makefile for Windows.
554+
*/
555+
public static function patchWindowsCGITarget(): void
556+
{
557+
// search Makefile code line contains "$(BUILD_DIR)\php.exe:"
558+
$content = FileSystem::readFile(SOURCE_PATH . '/php-src/Makefile');
559+
$lines = explode("\r\n", $content);
560+
$line_num = 0;
561+
$found = false;
562+
foreach ($lines as $v) {
563+
if (str_contains($v, '$(BUILD_DIR)\php-cgi.exe:')) {
564+
$found = $line_num;
565+
break;
566+
}
567+
++$line_num;
568+
}
569+
if ($found === false) {
570+
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');
571+
}
572+
$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';
573+
$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';
574+
FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines));
575+
}
576+
552577
public static function patchPhpLibxml212(): bool
553578
{
554579
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');

src/globals/test-extensions.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,28 @@
1313

1414
// test php version (8.1 ~ 8.4 available, multiple for matrix)
1515
$test_php_version = [
16-
// '8.1',
17-
// '8.2',
18-
// '8.3',
16+
'8.1',
17+
'8.2',
18+
'8.3',
1919
'8.4',
2020
// '8.5',
2121
// 'git',
2222
];
2323

2424
// test os (macos-15-intel, macos-15, ubuntu-latest, windows-latest are available)
2525
$test_os = [
26-
'macos-15-intel', // bin/spc for x86_64
27-
'macos-15', // bin/spc for arm64
26+
// 'macos-15-intel', // bin/spc for x86_64
27+
// 'macos-15', // bin/spc for arm64
2828
// 'ubuntu-latest', // bin/spc-alpine-docker for x86_64
29-
'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
30-
'ubuntu-24.04', // bin/spc for x86_64
31-
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
32-
'ubuntu-24.04-arm', // bin/spc for arm64
33-
// 'windows-latest', // .\bin\spc.ps1
29+
// 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
30+
// 'ubuntu-24.04', // bin/spc for x86_64
31+
// 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
32+
// 'ubuntu-24.04-arm', // bin/spc for arm64
33+
'windows-latest', // .\bin\spc.ps1
3434
];
3535

3636
// whether enable thread safe
37-
$zts = false;
37+
$zts = true;
3838

3939
$no_strip = false;
4040

@@ -208,7 +208,7 @@ function quote2(string $param): string
208208
passthru($prefix . $down_cmd, $retcode);
209209
break;
210210
case 'build_cmd':
211-
passthru($prefix . $build_cmd . ' --build-cli --build-micro', $retcode);
211+
passthru($prefix . $build_cmd . ' --build-cli --build-micro --build-cgi', $retcode);
212212
break;
213213
case 'build_embed_cmd':
214214
if ($frankenphp) {

0 commit comments

Comments
 (0)