|
|
|
|
@ -2687,6 +2687,11 @@ class CompilerBase extends \PhpAot\Core\Translator |
|
|
|
|
$libraries[] = '"' . $this->windowsPhpCoreLib . '"'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 添加 Windows API 库(Win32 GUI 程序需要) |
|
|
|
|
$libraries[] = 'user32.lib'; // Windows UI 函数(CreateWindow, MessageBox 等) |
|
|
|
|
$libraries[] = 'gdi32.lib'; // GDI 图形函数 |
|
|
|
|
$libraries[] = 'kernel32.lib'; // 核心 Windows API |
|
|
|
|
} else { |
|
|
|
|
// Linux/macOS: extension 和 bin 模式都需要添加 php 库 |
|
|
|
|
$libraries[] = 'php'; |
|
|
|
|
@ -2695,74 +2700,11 @@ class CompilerBase extends \PhpAot\Core\Translator |
|
|
|
|
return $this->platform->getLibraryFlags($libraries); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 旧的库文件解析逻辑(保持兼容) |
|
|
|
|
*/ |
|
|
|
|
protected function parseLibsLegacy(): string |
|
|
|
|
{ |
|
|
|
|
if ($this->isWindows()) { |
|
|
|
|
return $this->parseWindowsLibs(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$list = ['phpx']; |
|
|
|
|
if ($this->buildMode === 'bin') { |
|
|
|
|
$list[] = 'php'; |
|
|
|
|
} |
|
|
|
|
$out = ''; |
|
|
|
|
foreach ($list as $li) { |
|
|
|
|
$out .= '-l' . $li . ' '; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function parseWindowsLibs(): string |
|
|
|
|
{ |
|
|
|
|
$list = []; |
|
|
|
|
|
|
|
|
|
// 优先使用 .lib 导入库 |
|
|
|
|
$phpxLib = $this->getPhpxDir() . '\lib\phpx.lib'; |
|
|
|
|
if (file_exists($phpxLib)) { |
|
|
|
|
$list[] = '"' . $phpxLib . '"'; |
|
|
|
|
} else { |
|
|
|
|
$this->error('phpx.lib not found'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($this->buildMode === 'bin') { |
|
|
|
|
// Windows 下 PHP 库文件的链接策略: |
|
|
|
|
// 需要同时链接 php8embed.lib + (php8.lib 或 php8ts.lib) |
|
|
|
|
// - php8embed.lib: 提供嵌入模式的主入口 |
|
|
|
|
// - php8.lib/php8ts.lib: 提供内存管理等核心符号(_efree, _emalloc 等) |
|
|
|
|
// |
|
|
|
|
// 注意:库文件路径已在 detectWindowsPhpLibs() 中检测并保存 |
|
|
|
|
|
|
|
|
|
// 直接使用检测阶段保存的库文件路径 |
|
|
|
|
if (!empty($this->windowsPhpEmbedLib)) { |
|
|
|
|
$list[] = '"' . $this->windowsPhpEmbedLib . '"'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!empty($this->windowsPhpCoreLib)) { |
|
|
|
|
$list[] = '"' . $this->windowsPhpCoreLib . '"'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$out = ''; |
|
|
|
|
foreach ($list as $li) { |
|
|
|
|
$out .= $li . ' '; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function addCompilationOption(string &$cmd, bool $link): void |
|
|
|
|
{ |
|
|
|
|
// 优先使用新架构 |
|
|
|
|
if ($this->compilerBackend !== null) { |
|
|
|
|
$this->addCompilationOptionNew($cmd, $link); |
|
|
|
|
} else { |
|
|
|
|
// 回退到旧逻辑 |
|
|
|
|
$this->addCompilationOptionLegacy($cmd, $link); |
|
|
|
|
} |
|
|
|
|
// 使用新架构(Platform + Backend) |
|
|
|
|
$this->addCompilationOptionNew($cmd, $link); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
@ -2773,17 +2715,8 @@ class CompilerBase extends \PhpAot\Core\Translator |
|
|
|
|
if (!$link) { |
|
|
|
|
// 编译时选项 |
|
|
|
|
|
|
|
|
|
// 先添加包含路径(平台相关,parseIncludesNew 内部已处理平台差异) |
|
|
|
|
if ($this->platform !== null) { |
|
|
|
|
$cmd .= ' ' . $this->parseIncludesNew(); |
|
|
|
|
} else { |
|
|
|
|
// 回退到旧方法 |
|
|
|
|
if ($this->isWindows()) { |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsIncludes(); |
|
|
|
|
} else { |
|
|
|
|
$cmd .= ' ' . $this->parseUnixIncludes(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 先添加包含路径(平台相关) |
|
|
|
|
$cmd .= ' ' . $this->parseIncludesNew(); |
|
|
|
|
|
|
|
|
|
// 再添加编译选项(编译器相关) |
|
|
|
|
$config = [ |
|
|
|
|
@ -2802,17 +2735,8 @@ class CompilerBase extends \PhpAot\Core\Translator |
|
|
|
|
} else { |
|
|
|
|
// 链接时选项 |
|
|
|
|
|
|
|
|
|
// 先添加库路径(平台相关,parseLdflagsNew 内部已处理平台差异) |
|
|
|
|
if ($this->platform !== null) { |
|
|
|
|
$cmd .= ' ' . $this->parseLdflagsNew(); |
|
|
|
|
} else { |
|
|
|
|
// 回退到旧方法 |
|
|
|
|
if ($this->isWindows()) { |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsLdflags(); |
|
|
|
|
} else { |
|
|
|
|
$cmd .= ' ' . $this->parseUnixLdflags(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 先添加库路径(平台相关) |
|
|
|
|
$cmd .= ' ' . $this->parseLdflagsNew(); |
|
|
|
|
|
|
|
|
|
// 再添加链接选项(编译器相关) |
|
|
|
|
$config = [ |
|
|
|
|
@ -2836,528 +2760,10 @@ class CompilerBase extends \PhpAot\Core\Translator |
|
|
|
|
$cmd .= $this->compilerBackend->buildLinkOptions($config); |
|
|
|
|
|
|
|
|
|
// 最后添加库文件(平台相关,必须在链接选项之后) |
|
|
|
|
if ($this->platform !== null) { |
|
|
|
|
$cmd .= ' ' . $this->parseLibsNew(); |
|
|
|
|
} else { |
|
|
|
|
// 回退到旧方法 |
|
|
|
|
if ($this->isWindows()) { |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsLibs(); |
|
|
|
|
} else { |
|
|
|
|
$cmd .= ' ' . $this->parseUnixLibs(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 旧版添加编译选项(回退逻辑) |
|
|
|
|
*/ |
|
|
|
|
protected function addCompilationOptionLegacy(string &$cmd, bool $link): void |
|
|
|
|
{ |
|
|
|
|
if ($this->isWindows()) { |
|
|
|
|
// Windows 下根据编译器类型选择 |
|
|
|
|
if ($this->cppCompiler === 'clang++' || $this->cppCompiler === 'clang') { |
|
|
|
|
// Windows Clang 编译选项(类似 GCC) |
|
|
|
|
$this->addWindowsClangCompilationOption($cmd, $link); |
|
|
|
|
} else { |
|
|
|
|
// Windows MSVC 编译选项 |
|
|
|
|
$this->addWindowsCompilationOption($cmd, $link); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
// Unix/Linux/macOS GCC 编译选项 |
|
|
|
|
$this->addUnixCompilationOption($cmd, $link); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Windows MSVC 编译选项配置 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsCompilationOption(string &$cmd, bool $link): void |
|
|
|
|
{ |
|
|
|
|
// 编译时选项 |
|
|
|
|
if (!$link) { |
|
|
|
|
$this->addWindowsCompileOptions($cmd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 通用选项 |
|
|
|
|
$cmd .= ' /nologo'; |
|
|
|
|
|
|
|
|
|
// 扩展模块特定选项 |
|
|
|
|
$this->addWindowsExtensionOptions($cmd, $link); |
|
|
|
|
|
|
|
|
|
// 链接时选项 |
|
|
|
|
if ($link) { |
|
|
|
|
$this->addWindowsLinkOptions($cmd); |
|
|
|
|
} else { |
|
|
|
|
// 编译时使用动态多线程 CRT |
|
|
|
|
$cmd .= ' /MD'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 性能分析宏 |
|
|
|
|
if (!$link && $this->enableProfiler) { |
|
|
|
|
$cmd .= ' /DPPROF_ON=1'; |
|
|
|
|
$cmd .= ' ' . $this->parseLibsNew(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows MSVC 编译时选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsCompileOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
// 包含路径 |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsIncludes(); |
|
|
|
|
|
|
|
|
|
// 平台宏定义 |
|
|
|
|
$this->addWindowsPlatformDefines($cmd); |
|
|
|
|
|
|
|
|
|
// Sanitizer 支持 |
|
|
|
|
$this->addWindowsSanitizerOptions($cmd); |
|
|
|
|
|
|
|
|
|
// 优化和调试选项 |
|
|
|
|
$this->addWindowsOptimizationOptions($cmd); |
|
|
|
|
|
|
|
|
|
// 警告设置 |
|
|
|
|
$this->addWindowsWarningOptions($cmd); |
|
|
|
|
|
|
|
|
|
// C++ 标准和异常处理 |
|
|
|
|
$this->addWindowsCppOptions($cmd); |
|
|
|
|
|
|
|
|
|
// 用户自定义编译选项 |
|
|
|
|
if ($this->cxxflags) { |
|
|
|
|
$cmd .= ' ' . $this->cxxflags; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows 平台宏定义 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsPlatformDefines(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
$cmd .= ' /DZEND_WIN32'; // 标识 Windows 平台 |
|
|
|
|
$cmd .= ' /DPHP_WIN32'; // 标识 Windows 平台 |
|
|
|
|
$cmd .= ' /DZEND_DEBUG=0'; // 禁用调试模式 |
|
|
|
|
|
|
|
|
|
// ZTS 线程安全宏 |
|
|
|
|
if ($this->isPhpZts) { |
|
|
|
|
$cmd .= ' /DZTS'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Sanitizer 选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsSanitizerOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
if (!$this->sanitize) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MSVC 仅支持 AddressSanitizer |
|
|
|
|
if ($this->sanitize === 'address' || $this->sanitize === 'addr') { |
|
|
|
|
$cmd .= ' /fsanitize=address'; |
|
|
|
|
$this->climate->info('AddressSanitizer enabled (MSVC)'); |
|
|
|
|
} else { |
|
|
|
|
$this->climate->warning( |
|
|
|
|
"Unsupported sanitizer type: {$this->sanitize} (MSVC only supports 'address')" |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows 优化和调试选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsOptimizationOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
if ($this->debugInfo) { |
|
|
|
|
// 调试模式:禁用优化,生成调试信息 |
|
|
|
|
$cmd .= ' /Od'; // 禁用优化 |
|
|
|
|
$cmd .= ' /Zi'; // 生成完整调试信息 |
|
|
|
|
$this->climate->info('Debug mode enabled: optimizations disabled, debug info generated'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 非调试模式:根据优化级别设置 |
|
|
|
|
$optimizationMap = [ |
|
|
|
|
0 => '/Od', // 禁用优化 |
|
|
|
|
1 => '/O2', // 最大速度优化 |
|
|
|
|
2 => '/O2', // 最大速度优化 |
|
|
|
|
3 => '/Ox', // 完全优化 |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
$optLevel = $this->optimizeLevel; |
|
|
|
|
$optFlag = $optimizationMap[$optLevel] ?? '/O2'; |
|
|
|
|
$cmd .= ' ' . $optFlag; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows 警告选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsWarningOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
// 基础警告级别 |
|
|
|
|
$cmd .= ' /W3'; |
|
|
|
|
|
|
|
|
|
// 禁用常见警告(从 Constants 配置读取) |
|
|
|
|
foreach (Constants::MSVC_SUPPRESSED_WARNINGS as $code => $description) { |
|
|
|
|
$cmd .= " /wd{$code}"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows C++ 选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsCppOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
// 启用 C++ 异常处理 |
|
|
|
|
$cmd .= ' /EHsc'; |
|
|
|
|
|
|
|
|
|
// C++ 标准(如果 cxxflags 中未指定) |
|
|
|
|
if (!str_contains($this->cxxflags, '/std:')) { |
|
|
|
|
$cmd .= ' /std:' . $this->cxxStd; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows 扩展模块选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsExtensionOptions(string &$cmd, bool $link): void |
|
|
|
|
{ |
|
|
|
|
if ($this->buildMode !== 'ext') { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($link) { |
|
|
|
|
$cmd .= ' /DLL'; // 生成 DLL |
|
|
|
|
} |
|
|
|
|
// 注意:MSVC 不需要 -fPIC,默认就是位置无关代码 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows 链接时选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsLinkOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
// 链接器标志 |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsLdflags(); |
|
|
|
|
|
|
|
|
|
// 调试信息 |
|
|
|
|
if ($this->debugInfo) { |
|
|
|
|
$cmd .= ' /DEBUG'; // 生成 PDB 文件 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Windows 子系统配置 |
|
|
|
|
$this->addWindowsSubsystemOptions($cmd); |
|
|
|
|
|
|
|
|
|
// CRT 库配置 |
|
|
|
|
$cmd .= ' /NODEFAULTLIB:LIBCMT'; |
|
|
|
|
|
|
|
|
|
// 链接库 |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsLibs(); |
|
|
|
|
|
|
|
|
|
// 用户自定义链接标志 |
|
|
|
|
if ($this->ldflags) { |
|
|
|
|
$cmd .= ' ' . $this->ldflags; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows 子系统选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsSubsystemOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
if ($this->buildMode !== 'bin' || !$this->noConsole) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 使用 Windows 子系统(不显示控制台窗口) |
|
|
|
|
$cmd .= ' /SUBSYSTEM:WINDOWS'; |
|
|
|
|
$cmd .= ' /ENTRY:mainCRTStartup'; |
|
|
|
|
// 注意:使用 WINDOWS 子系统后,程序将没有控制台窗口 |
|
|
|
|
// 所有输出需要通过 GUI 元素(如消息框)显示 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Windows Clang 编译选项配置(使用 GCC 风格语法,MSVC 链接器) |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangCompilationOption(string &$cmd, bool $link): void |
|
|
|
|
{ |
|
|
|
|
// 编译时选项 |
|
|
|
|
if (!$link) { |
|
|
|
|
$this->addWindowsClangCompileOptions($cmd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 扩展模块特定选项 |
|
|
|
|
$this->addWindowsClangExtensionOptions($cmd, $link); |
|
|
|
|
|
|
|
|
|
// 链接时选项(Clang on Windows 仍使用 MSVC 链接器) |
|
|
|
|
if ($link) { |
|
|
|
|
$this->addWindowsClangLinkOptions($cmd); |
|
|
|
|
} else { |
|
|
|
|
// 编译时使用动态多线程 CRT |
|
|
|
|
$cmd .= ' -MD'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 性能分析宏 |
|
|
|
|
if (!$link && $this->enableProfiler) { |
|
|
|
|
$cmd .= ' -DPPROF_ON=1'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang 编译时选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangCompileOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
// 包含路径 |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsIncludes(); |
|
|
|
|
|
|
|
|
|
// MSVC 兼容性选项 |
|
|
|
|
$this->addWindowsClangCompatibilityOptions($cmd); |
|
|
|
|
|
|
|
|
|
// 平台宏定义 |
|
|
|
|
$this->addWindowsClangPlatformDefines($cmd); |
|
|
|
|
|
|
|
|
|
// Sanitizer 支持 |
|
|
|
|
$this->addWindowsClangSanitizerOptions($cmd); |
|
|
|
|
|
|
|
|
|
// 优化和调试选项 |
|
|
|
|
$this->addWindowsClangOptimizationOptions($cmd); |
|
|
|
|
|
|
|
|
|
// 警告设置 |
|
|
|
|
$cmd .= ' -Wall'; |
|
|
|
|
|
|
|
|
|
// C++ 标准 |
|
|
|
|
$this->addWindowsClangCppOptions($cmd); |
|
|
|
|
|
|
|
|
|
// 用户自定义编译选项 |
|
|
|
|
if ($this->cxxflags) { |
|
|
|
|
$cmd .= ' ' . $this->cxxflags; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang MSVC 兼容性选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangCompatibilityOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
$cmd .= ' -fms-compatibility'; // 启用 MSVC 兼容性 |
|
|
|
|
$cmd .= ' -fms-compatibility-version=19.40'; // MSVC 版本兼容性(VS2022) |
|
|
|
|
$cmd .= ' -fdelayed-template-parsing'; // 延迟模板解析(MSVC 特性) |
|
|
|
|
$cmd .= ' -fms-extensions'; // 启用 MSVC 扩展 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang 平台宏定义 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangPlatformDefines(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
$cmd .= ' -DZEND_WIN32'; // 标识 Windows 平台 |
|
|
|
|
$cmd .= ' -DPHP_WIN32'; // 标识 Windows 平台 |
|
|
|
|
$cmd .= ' -DZEND_DEBUG=0'; // 禁用调试模式 |
|
|
|
|
|
|
|
|
|
// ZTS 线程安全宏 |
|
|
|
|
if ($this->isPhpZts) { |
|
|
|
|
$cmd .= ' -DZTS'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang Sanitizer 选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangSanitizerOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
if (!$this->sanitize) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$sanitizers = explode(',', $this->sanitize); |
|
|
|
|
$validSanitizers = ['address', 'undefined', 'thread', 'memory', 'leak']; |
|
|
|
|
$enabledSanitizers = []; |
|
|
|
|
|
|
|
|
|
foreach ($sanitizers as $san) { |
|
|
|
|
$san = trim($san); |
|
|
|
|
if (in_array($san, $validSanitizers)) { |
|
|
|
|
$enabledSanitizers[] = $san; |
|
|
|
|
} else { |
|
|
|
|
$this->climate->warning("Unsupported sanitizer: {$san}"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!empty($enabledSanitizers)) { |
|
|
|
|
$sanitizerFlag = '-fsanitize=' . implode(',', $enabledSanitizers); |
|
|
|
|
$cmd .= ' ' . $sanitizerFlag; |
|
|
|
|
|
|
|
|
|
// AddressSanitizer 需要额外的链接选项 |
|
|
|
|
if (in_array('address', $enabledSanitizers)) { |
|
|
|
|
$cmd .= ' -fsanitize=address'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$this->climate->info('Sanitizers enabled (Clang): ' . implode(', ', $enabledSanitizers)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang 优化和调试选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangOptimizationOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
if ($this->debugInfo) { |
|
|
|
|
// 调试模式:禁用优化,生成调试信息 |
|
|
|
|
$cmd .= ' -O0'; // 禁用优化 |
|
|
|
|
$cmd .= ' -g'; // 生成调试信息 |
|
|
|
|
$this->climate->info('Debug mode enabled (Clang): optimizations disabled (-O0), debug info generated (-g)'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 非调试模式:使用用户指定的优化级别 |
|
|
|
|
$cmd .= ' -O' . $this->optimizeLevel; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang C++ 选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangCppOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
// C++ 标准(如果 cxxflags 中未指定) |
|
|
|
|
if (!str_contains($this->cxxflags, ' -std=')) { |
|
|
|
|
$cmd .= ' -std=' . $this->cxxStd; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang 扩展模块选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangExtensionOptions(string &$cmd, bool $link): void |
|
|
|
|
{ |
|
|
|
|
if ($this->buildMode !== 'ext') { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($link) { |
|
|
|
|
$cmd .= ' -shared'; |
|
|
|
|
} else { |
|
|
|
|
$cmd .= ' -fPIC'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang 链接时选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangLinkOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
// 链接器标志 |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsLdflags(); |
|
|
|
|
|
|
|
|
|
// 调试信息 |
|
|
|
|
if ($this->debugInfo) { |
|
|
|
|
$cmd .= ' /DEBUG'; // 生成 PDB 文件 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Windows 子系统配置 |
|
|
|
|
$this->addWindowsClangSubsystemOptions($cmd); |
|
|
|
|
|
|
|
|
|
// CRT 库配置 |
|
|
|
|
$cmd .= ' /NODEFAULTLIB:LIBCMT'; |
|
|
|
|
|
|
|
|
|
// 链接库 |
|
|
|
|
$cmd .= ' ' . $this->parseWindowsLibs(); |
|
|
|
|
|
|
|
|
|
// 用户自定义链接标志 |
|
|
|
|
if ($this->ldflags) { |
|
|
|
|
$cmd .= ' ' . $this->ldflags; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 添加 Windows Clang 子系统选项 |
|
|
|
|
*/ |
|
|
|
|
protected function addWindowsClangSubsystemOptions(string &$cmd): void |
|
|
|
|
{ |
|
|
|
|
if ($this->buildMode !== 'bin' || !$this->noConsole) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 使用 Windows 子系统(不显示控制台窗口) |
|
|
|
|
$cmd .= ' /SUBSYSTEM:WINDOWS'; |
|
|
|
|
$cmd .= ' /ENTRY:mainCRTStartup'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function addUnixCompilationOption(string &$cmd, bool $link): void |
|
|
|
|
{ |
|
|
|
|
$cmd .= ' ' . $this->parseIncludes(); |
|
|
|
|
|
|
|
|
|
// 调试模式:当启用 --debug-info 时,自动禁用优化并添加调试信息 |
|
|
|
|
if ($this->debugInfo) { |
|
|
|
|
$cmd .= ' -O0'; // 禁用优化(类似 MSVC /Od) |
|
|
|
|
$cmd .= ' -g'; // 生成调试信息 |
|
|
|
|
$this->climate->info('Debug mode enabled: optimizations disabled (-O0), debug info generated (-g)'); |
|
|
|
|
} else { |
|
|
|
|
// 非调试模式:使用用户指定的优化级别 |
|
|
|
|
$cmd .= ' -O' . $this->optimizeLevel; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$cmd .= ' -Wall'; |
|
|
|
|
|
|
|
|
|
// Sanitizer 支持(GCC/Clang 使用 -fsanitize) |
|
|
|
|
if ($this->sanitize && !$link) { |
|
|
|
|
$sanitizers = explode(',', $this->sanitize); |
|
|
|
|
$validSanitizers = ['address', 'undefined', 'thread', 'memory', 'leak']; |
|
|
|
|
$enabledSanitizers = []; |
|
|
|
|
|
|
|
|
|
foreach ($sanitizers as $san) { |
|
|
|
|
$san = trim($san); |
|
|
|
|
if (in_array($san, $validSanitizers)) { |
|
|
|
|
$enabledSanitizers[] = $san; |
|
|
|
|
} else { |
|
|
|
|
$this->climate->warning("Unsupported sanitizer: {$san}"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!empty($enabledSanitizers)) { |
|
|
|
|
$sanitizerFlag = '-fsanitize=' . implode(',', $enabledSanitizers); |
|
|
|
|
$cmd .= ' ' . $sanitizerFlag; |
|
|
|
|
// AddressSanitizer 需要额外的链接选项 |
|
|
|
|
if (in_array('address', $enabledSanitizers)) { |
|
|
|
|
$cmd .= ' -fsanitize=address'; |
|
|
|
|
} |
|
|
|
|
$this->climate->info('Sanitizers enabled: ' . implode(', ', $enabledSanitizers)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($this->enableProfiler) { |
|
|
|
|
$cmd .= ' -lprofiler'; |
|
|
|
|
$cmd .= ' -DPPROF_ON=1'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($this->buildMode === 'ext') { |
|
|
|
|
if ($link) { |
|
|
|
|
$cmd .= ' -shared'; |
|
|
|
|
} else { |
|
|
|
|
$cmd .= ' -fPIC'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($link) { |
|
|
|
|
$cmd .= ' ' . $this->parseLdflags(); |
|
|
|
|
$cmd .= ' ' . $this->parseLibs(); |
|
|
|
|
if ($this->ldflags) { |
|
|
|
|
$cmd .= ' ' . $this->ldflags; |
|
|
|
|
} |
|
|
|
|
// macos 没有 ldconfig ,只能配置 rpath 绝对路径 |
|
|
|
|
if ($this->isMacos()) { |
|
|
|
|
$cmd .= ' -Wl,-rpath,' . $this->getPhpDir() . '/lib'; |
|
|
|
|
$cmd .= ' -Wl,-rpath,' . $this->getPhpxDir() . '/lib'; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if ($this->cxxflags) { |
|
|
|
|
$cmd .= ' ' . $this->cxxflags; |
|
|
|
|
} |
|
|
|
|
// C++ 标准(从 cxxStd 属性读取,如果 cxxflags 中没有指定) |
|
|
|
|
if (!str_contains($this->cxxflags, ' -std=')) { |
|
|
|
|
$cmd .= ' -std=' . $this->cxxStd; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected function parseBinaryOpConcat(Expr\BinaryOp\Concat $expr): string |
|
|
|
|
{ |
|
|
|
|
|