diff --git a/.gitignore b/.gitignore index ace7fe76..a41bb9db 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ /projects/laravel /projects/tmp /.php-cs-fixer.cache -*.o \ No newline at end of file +*.o +*.dll +*.exe \ No newline at end of file diff --git a/examples/hello.php b/examples/hello.php index 4e117cee..1abfd2fa 100644 --- a/examples/hello.php +++ b/examples/hello.php @@ -5,8 +5,6 @@ function main(): void echo "Hello World!"; var_dump(PHP_VERSION); var_dump(php_uname()); - var_dump($_ENV); - global $argv; var_dump($argv); } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 311ce6a3..2bb7f5b5 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -290,7 +290,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->detectPlatform(); // 检测 PHP 是否为线程安全版本(ZTS) - $this->isPhpZts = defined('PHP_ZTS') && PHP_ZTS === 1; + $this->isPhpZts = defined('PHP_ZTS'); } protected function detectPlatform(): void @@ -2304,11 +2304,12 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->buildMode === 'bin') { // Windows 下 PHP 库文件和 DLL 的查找顺序: - // 1. SDK/lib/php8.lib + // 1. SDK/lib/php8embed.lib (嵌入模式首选) // 2. SDK/lib/php8ts.lib - // 3. lib/php8.lib - // 4. lib/php8ts.lib - // 5. 根目录/php8.dll + // 3. SDK/lib/php8.lib + // 4. lib/php8embed.lib + // 5. lib/php8ts.lib + // 6. lib/php8.lib $phpDirs = [ $this->getPhpDir() . '\\SDK\\lib', // 优先从 SDK/lib 查找 @@ -2319,18 +2320,26 @@ class CompilerBase extends \PhpAot\Core\Translator foreach ($phpDirs as $phpDir) { if (!is_dir($phpDir)) continue; - // 尝试 php8.lib - $phpLib = $phpDir . '\\php8.lib'; - if (file_exists($phpLib)) { - $list[] = '"' . $phpLib . '"'; + // 尝试 php8embed.lib (嵌入模式) + $phpEmbedLib = $phpDir . '\\php8embed.lib'; + if (file_exists($phpEmbedLib)) { + $list[] = '"' . $phpEmbedLib . '"'; $found = true; break; } // 尝试 php8ts.lib - $altPhpLib = $phpDir . '\\php8ts.lib'; - if (file_exists($altPhpLib)) { - $list[] = '"' . $altPhpLib . '"'; + $phpTsLib = $phpDir . '\\php8ts.lib'; + if (file_exists($phpTsLib)) { + $list[] = '"' . $phpTsLib . '"'; + $found = true; + break; + } + + // 尝试 php8.lib + $phpLib = $phpDir . '\\php8.lib'; + if (file_exists($phpLib)) { + $list[] = '"' . $phpLib . '"'; $found = true; break; } @@ -2340,19 +2349,29 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$found) { $phpDll = $this->getPhpDir() . '\\php8.dll'; if (file_exists($phpDll)) { - $this->climate->magenta('php8.lib not found, using php8.dll directly'); + $this->climate->magenta('php8embed.lib not found, using php8.dll directly'); $this->climate->info('Note: This may require additional setup'); $list[] = '"' . $phpDll . '"'; } else { // 尝试 php8ts.dll $phpTsDll = $this->getPhpDir() . '\\php8ts.dll'; if (file_exists($phpTsDll)) { - $this->climate->magenta('php8.lib not found, using php8ts.dll directly'); + $this->climate->magenta('php8embed.lib not found, using php8ts.dll directly'); $this->climate->info('Note: This may require additional setup'); $list[] = '"' . $phpTsDll . '"'; } } } + +// // 添加 Windows 系统库(PHP 嵌入模式必需) +// $list[] = 'ws2_32.lib'; // Winsock +// $list[] = 'advapi32.lib'; // 高级 API +// $list[] = 'user32.lib'; // 用户界面 +// $list[] = 'shell32.lib'; // Shell API +// $list[] = 'ole32.lib'; // OLE +// $list[] = 'oleaut32.lib'; // OLE Automation +// $list[] = 'crypt32.lib'; // 加密 API + } $out = ''; @@ -2381,52 +2400,60 @@ class CompilerBase extends \PhpAot\Core\Translator $cmd .= ' ' . $this->parseWindowsIncludes(); } - // Windows 平台必需的宏定义(参考 CMakeLists.txt) - $cmd .= ' /DZEND_WIN32'; // 标识 Windows 平台 - $cmd .= ' /DPHP_WIN32'; // 标识 Windows 平台 - $cmd .= ' /DZEND_DEBUG=0'; // 禁用调试模式 - - // 根据 PHP 是否为线程安全版本决定是否添加 ZTS 宏 - if ($this->isPhpZts) { - $cmd .= ' /DZTS'; // 启用线程安全 - } - - $cmd .= ' /DZEND_ENABLE_STATIC_TSRMLS_CACHE'; // 启用静态 TSRM 缓存 - - // 优化级别 - switch ($this->optimizeLevel) { - case 0: - $cmd .= ' /Od'; // 禁用优化 - break; - case 1: - case 2: - $cmd .= ' /O2'; // 最大速度优化 - break; - case 3: - $cmd .= ' /Ox'; // 完全优化 - break; - } + // Windows 平台必需的宏定义(参考 CMakeLists.txt)- 仅在编译时 + if (!$link) { + $cmd .= ' /DZEND_WIN32'; // 标识 Windows 平台 + $cmd .= ' /DPHP_WIN32'; // 标识 Windows 平台 + $cmd .= ' /DZEND_DEBUG=0'; // 禁用调试模式 + + // 根据 PHP 是否为线程安全版本决定是否添加 ZTS 宏 + if ($this->isPhpZts) { + $cmd .= ' /DZTS'; // 启用线程安全 + } + + // 优化级别 + switch ($this->optimizeLevel) { + case 0: + $cmd .= ' /Od'; // 禁用优化 + break; + case 1: + case 2: + $cmd .= ' /O2'; // 最大速度优化 + break; + case 3: + $cmd .= ' /Ox'; // 完全优化 + break; + } - // 调试信息 - if ($this->debugInfo) { - $cmd .= ' /Zi'; // 生成完整调试信息 - } + // 调试信息 + if ($this->debugInfo) { + $cmd .= ' /Zi'; // 生成完整调试信息 + } - // 警告级别 - $cmd .= ' /W3'; - - // 禁用 PHP SDK 头文件中的常见警告 - $cmd .= ' /wd4244'; // 禁用类型转换警告(__int64 到 int) - $cmd .= ' /wd4146'; // 禁用一元负运算符应用于无符号类型的警告 + // 警告级别 + $cmd .= ' /W3'; + + // 禁用 PHP SDK 头文件中的常见警告 + $cmd .= ' /wd4244'; // 禁用类型转换警告(__int64 到 int) + $cmd .= ' /wd4146'; // 禁用一元负运算符应用于无符号类型的警告 + + // 启用 C++ 异常处理(消除 C4530 警告) + $cmd .= ' /EHsc'; + + // C++ 标准 + if (!str_contains($this->cxxflags, '/std:')) { + $cmd .= ' /std:c++17'; + } + + // 编译时的额外选项 + if ($this->cxxflags) { + $cmd .= ' ' . $this->cxxflags; + } + } // 禁用编译器版权信息输出 $cmd .= ' /nologo'; - // C++ 标准(仅在编译时) - if (!$link && !str_contains($this->cxxflags, '/std:')) { - $cmd .= ' /std:c++17'; - } - // 扩展模块特定选项 if ($this->buildMode === 'ext') { if ($link) { @@ -2444,14 +2471,11 @@ class CompilerBase extends \PhpAot\Core\Translator $cmd .= ' ' . $this->ldflags; } } else { - // 编译时的额外选项 - if ($this->cxxflags) { - $cmd .= ' ' . $this->cxxflags; - } + $cmd .= ' /MD'; } - // 定义宏 - if ($this->enableProfiler) { + // 定义宏(仅在编译时) + if (!$link && $this->enableProfiler) { $cmd .= ' /DPPROF_ON=1'; } } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index b7dff04a..d7ca7b3c 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -405,11 +405,12 @@ class Translator extends Preprocessor if ($this->buildMode === 'bin') { $cliHeaders = [ - '#include "ps_title.h"', '#include "php_cli_process_title.h"', '#include "php_cli_process_title_arginfo.h"', ]; + $code .= 'extern "C" {' . PHP_EOL; $code .= implode(PHP_EOL, $cliHeaders) . PHP_EOL; + $code .= '}'; } $code .= "// global vars \n"; @@ -663,12 +664,31 @@ CODE; if ($this->isWindows()) { // Windows MSVC 编译命令 $cmd = $this->cppCompiler . ' /c ' . $cppFile . ' /Fo' . $objectFile; + + // C 文件和 C++ 文件使用不同的选项 + $isCppFile = (pathinfo($cppFile, PATHINFO_EXTENSION) === 'cc' || + pathinfo($cppFile, PATHINFO_EXTENSION) === 'cpp' || + pathinfo($cppFile, PATHINFO_EXTENSION) === 'cxx'); + + // 添加编译选项(C 文件不需要 /EHsc 和 /std:c++17) + if ($isCppFile) { + $this->addCompilationOption($cmd, false); + } else { + // C 文件:只添加基本选项,不添加 C++ 特定选项 + $cmd .= ' ' . $this->parseWindowsIncludes(); + $cmd .= ' /DZEND_WIN32 /DPHP_WIN32 /DZEND_DEBUG=0'; + if ($this->isPhpZts) { + $cmd .= ' /DZTS'; + } + $cmd .= ' /DZEND_ENABLE_STATIC_TSRMLS_CACHE'; + $cmd .= ' /Od /W3 /wd4244 /wd4146 /nologo'; + } } else { // Unix/Linux/macOS GCC 编译命令 $cmd = $this->cppCompiler . ' -c ' . $cppFile . ' -o ' . $objectFile; + $this->addCompilationOption($cmd, false); } - $this->addCompilationOption($cmd, false); if (!$parallel) { $this->climate->comment($cmd); } @@ -871,9 +891,9 @@ CODE; // 根据平台构建链接命令 if ($this->isWindows()) { - // Windows MSVC 链接命令 + // Windows 使用 link.exe 进行链接 $objectList = implode(' ', $objectFiles); - $linkCmd = $this->cppCompiler . ' ' . $objectList . ' /Fe' . $targetFile; + $linkCmd = 'link /nologo ' . $objectList . ' /OUT:' . $targetFile; } else { // Unix/Linux/macOS GCC 链接命令 $objectList = implode(' ', $objectFiles);