Skip to content

Fix Windows --nano build: include entry declaration header in extension TU - #134

Merged
matyhtf merged 1 commit into
swoole:masterfrom
yangweijie:fix/windows-nano-policy-entry-header
Sep 28, 2026
Merged

matyhtf merged 1 commit into
swoole:masterfrom
yangweijie:fix/windows-nano-policy-entry-header

Conversation

@yangweijie

Copy link
Copy Markdown
Contributor

aot-compiler Windows --nano 编译修复

结论

--nano 在 Windows 上此前无法编译(MSVC C3861: php_main: identifier not found)。根因是代码生成缺口,已修复并提交到分支 fix/windows-nano-policy-entry-header(commit eb2f551e),改动仅 1 文件 +14 行。

根因(源码级)

  • --nano 在 Windows 走 nanoPolicyMode=true + nanoMode=false(即 bin + 策略,WINDOWS_DLL 后端),分流点 src/Translator.php:499-505(NanoBuildBackend::composesRuntimeSources('Windows') 为 false)。
  • RINIT 在 src/Translator.php:1865-1881 对 Windows --nano 直接生成 C++ 调用 php_main()(不走 ZendVM 解释 main()),但扩展翻译单元(TU)的 includes 由 genExtensionIncludeHeaderFiles() 组装,只收 stub 文件与 attribute-factory owner 的声明头,入口 main() 的源文件两者都不是 → 其声明头 php_*_decl.h(含 extern void php_main();`)从未被包含 → 未声明 → C3861。
  • 真 Nano 模式(非 Windows)走独立 nano-entry-*.cc(1194-1208,自带 func_decl.h)封装 php_main(),逻辑自洽;Windows 这条路径从未打通。

修复

在 genExtensionIncludeHeaderFiles() 内、nano-policy 模式且存在 main() 时,把入口函数的声明头加入扩展 TU 的 includes:

if ($this->isNanoPolicyMode() && $this->hasFunction(self::ENTRY_FUNCTION)) {
    $entryHeader = $this->declarationHeaderFiles[
        $this->getFunction(self::ENTRY_FUNCTION)->sourceFile
    ] ?? null;
    if ($entryHeader !== null && !in_array($entryHeader, $declarationHeaders, true)) {
        $declarationHeaders[] = $entryHeader;
    }
}

门控确保:非 nano 构建(无 --nano)完全不受影响;真 Nano(非 Windows)仅多 include 一个纯前向声明头,无副作用。

验证

从源码编译(php bin/tpc.php nano_min.php --nano -o nano_min_src.exe):

  • 生成的 extension-nano_min_src.cc 第 12 行已含 php_nano_min_src_nano_min_537d6b1434_decl.h;
  • 链接成功:Build successful: nano_min_src.exe;
  • 运行输出 nano-policy-build-ok(入口 php_main() 已被正确派发)。

源码构建环境要点(Windows):

  • cl 经 vcvars64.bat 提供 INCLUDE/LIB;Bash 工具禁 cmd,故用 PowerShell 触发 build.bat。
  • 设 PHP_HOME/PHPX_HOME 指向 tpc 发行包(如 D:/git/php/tpc_v0.9.3_windows_x64)。
  • 源码编译器预检要求 phpx\build\phpx.dll(发行包该文件在顶层),需复制到 phpx\build\phpx.dll。

…on TU

On Windows, --nano runs in nano-policy mode (nanoMode=false, nanoPolicyMode=true)
using the WINDOWS_DLL backend. RINIT then emits a direct C++ call to php_main()
instead of relying on ZendVM eval, but the extension translation unit never
included the entry function's declaration header, so the php_main() prototype
was missing and MSVC failed with C3861.

genExtensionIncludeHeaderFiles() only added declaration headers for stub files
and attribute-factory owners, never the entry's source file. Include the entry
function's declaration header when nano-policy mode is active so php_main() is
visible where RINIT references it.

Verified: a minimal --nano program now compiles, links and runs on Windows
(previously failed at extension-<target>.cc with 'php_main': identifier not
found).
@matyhtf
matyhtf merged commit 27371fa into swoole:master Sep 28, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants