feat(compiler): 添加对多种原生源文件格式的编译支持

- 实现了对 C、汇编、Objective-C、Objective-C++ 等源文件的识别和分类
- 为 Clang、GCC、MSVC 编译器后端添加了 buildNativeCompileCommand 方法
- 在编译命令中添加 -x 参数指定源文件语言类型
- 重构了文件扫描逻辑,统一处理多种原生源文件格式
- 为不同语言类型的源文件生成相应的编译选项配置
- 更新了翻译器逻辑,根据文件扩展名自动检测并选择合适的编译方法
pull/1/head
韩天峰 3 months ago
parent 519ad7b292
commit 0c2a25ea52
  1. 48
      src/Php/Backend/Clang.php
  2. 12
      src/Php/Backend/CompilerBackend.php
  3. 35
      src/Php/Backend/Gcc.php
  4. 35
      src/Php/Backend/Msvc.php
  5. 19
      src/Php/CompilerBase.php
  6. 20
      src/Php/FileScanner.php
  7. 49
      src/Php/Translator.php

@ -177,7 +177,7 @@ class Clang extends CompilerBackend
public function buildCCompileCommand(string $sourceFile, string $outputFile, array $options = []): string
{
$cmd = $this->getCompilerCommand();
// Windows 下需要 MSVC 兼容模式
if ($this->platform instanceof \PhpAot\Php\Platform\Windows) {
$cmd .= ' -fms-compatibility';
@ -185,30 +185,64 @@ class Clang extends CompilerBackend
$cmd .= ' -fdelayed-template-parsing';
$cmd .= ' -fms-extensions';
}
$cmd .= ' -c';
$cmd .= ' -x c';
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
if (!empty($options['include_paths'])) {
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']);
}
// 优化级别(C 文件通常使用较低的优化)
$optimizeLevel = $options['optimize'] ?? 0;
// 调试模式
if (!empty($options['debug'])) {
$cmd .= ' -O0 -g';
} else {
$cmd .= ' -O' . $optimizeLevel;
}
// 警告级别
$cmd .= ' -Wall';
// 注意:C 文件不使用 -std=c++17 等 C++ 特定选项
return $cmd;
}
/**
* 构建原生源文件的编译命令(汇编/Objective-C 等)
*
* @param string $language 语言标识(assembler, objective-c, objective-c++)
*/
public function buildNativeCompileCommand(string $sourceFile, string $outputFile, array $options = [], string $language = ''): string
{
$cmd = $this->getCompilerCommand();
// Windows 下需要 MSVC 兼容模式
if ($this->platform instanceof \PhpAot\Php\Platform\Windows) {
$cmd .= ' -fms-compatibility';
$cmd .= ' -fms-compatibility-version=19.40';
$cmd .= ' -fdelayed-template-parsing';
$cmd .= ' -fms-extensions';
}
$cmd .= ' -c';
if ($language !== '') {
$cmd .= ' -x ' . $language;
}
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
if (!empty($options['include_paths'])) {
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']);
}
$cmd .= $this->buildCompileOptions($options);
return $cmd;
}

@ -75,6 +75,18 @@ abstract class CompilerBackend
array $options = []
): string;
/**
* 构建原生源文件的编译命令(汇编/Objective-C 等,使用 -x 指定语言)
*
* @param string $language GCC/Clang 语言标识(assembler, objective-c, objective-c++ 等)
*/
abstract public function buildNativeCompileCommand(
string $sourceFile,
string $outputFile,
array $options = [],
string $language = ''
): string;
/**
* 构建完整的链接命令
*/

@ -119,27 +119,52 @@ class Gcc extends CompilerBackend
{
$cmd = $this->getCompilerCommand();
$cmd .= ' -c';
$cmd .= ' -x c';
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
if (!empty($options['include_paths'])) {
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']);
}
// 优化级别(C 文件通常使用较低的优化)
$optimizeLevel = $options['optimize'] ?? 0;
$cmd .= ' -O' . $optimizeLevel;
// 调试信息
if (!empty($options['debug'])) {
$cmd .= ' -g';
}
// 警告级别
$cmd .= ' -Wall';
// 注意:C 文件不使用 -std=c++17 等 C++ 特定选项
return $cmd;
}
/**
* 构建原生源文件的编译命令(汇编/Objective-C 等)
*
* @param string $language 语言标识(assembler, objective-c, objective-c++)
*/
public function buildNativeCompileCommand(string $sourceFile, string $outputFile, array $options = [], string $language = ''): string
{
$cmd = $this->getCompilerCommand();
$cmd .= ' -c';
if ($language !== '') {
$cmd .= ' -x ' . $language;
}
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' -o ' . escapeshellarg($outputFile);
if (!empty($options['include_paths'])) {
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']);
}
$cmd .= $this->buildCompileOptions($options);
return $cmd;
}

@ -120,43 +120,62 @@ class Msvc extends CompilerBackend
{
$cmd = $this->getCompilerCommand();
$cmd .= ' /c';
$cmd .= ' /TC';
$cmd .= ' ' . escapeshellarg($sourceFile);
$cmd .= ' /Fo' . escapeshellarg($outputFile);
if (!empty($options['include_paths'])) {
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']);
}
// 平台宏定义
$cmd .= ' /DZEND_WIN32 /DPHP_WIN32 /DZEND_DEBUG=0';
// ZTS 支持
if ($this->platform instanceof Windows && $this->platform->isZts()) {
$cmd .= ' /DZTS';
}
// 优化级别(C 文件通常使用较低的优化)
$optimizeLevel = $options['optimize'] ?? 0;
$optMap = [0 => '/Od', 1 => '/O1', 2 => '/O2', 3 => '/Ox'];
$cmd .= ' ' . ($optMap[$optimizeLevel] ?? '/O2');
// 警告级别
$cmd .= ' /W3';
// 禁用常见警告
$suppressedWarnings = $options['suppressed_warnings'] ?? ['4244', '4146'];
foreach ($suppressedWarnings as $code) {
$cmd .= " /wd{$code}";
}
// nologo
$cmd .= ' /nologo';
// 注意:C 文件不使用 /EHsc, /std:c++17, /MD 等 C++ 特定选项
return $cmd;
}
/**
* 构建原生源文件的编译命令
*
* MSVC 仅支持 C 文件(/TC),汇编和 ObjC 文件不受支持
*
* @param string $language 语言标识
*/
public function buildNativeCompileCommand(string $sourceFile, string $outputFile, array $options = [], string $language = ''): string
{
if ($language === 'c') {
return $this->buildCCompileCommand($sourceFile, $outputFile, $options);
}
throw new \RuntimeException(
"MSVC does not support compiling source file of language '{$language}': {$sourceFile}"
);
}
public function buildLinkCommand(array $objectFiles, string $outputFile, array $options = []): string
{
$cmd = $this->getLinkerCommand();

@ -2581,6 +2581,25 @@ class CompilerBase extends \PhpAot\Core\Translator
];
}
/**
* 获取原生源文件(汇编/ObjC 等)的编译选项,不含 C++ 特定标志.
*
* @param string $language 语言标识(assembler, objective-c, objective-c++)
*/
protected function getNativeCompileCommandOptions(string $language = ''): array
{
return [
'include_paths' => $this->getIncludePaths(),
'optimize' => $this->optimizeLevel,
'debug' => $this->debug,
'sanitize' => $this->sanitize,
'is_zts' => $this->isPhpZts,
'build_mode' => $this->buildMode,
'enable_profiler' => $this->enableProfiler,
'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [],
];
}
protected function getLinkCommandOptions(): array
{
$options = [

@ -13,6 +13,17 @@ class FileScanner
public const array PHP_EXT = ['php'];
public const array CPP_EXT = ['cpp', 'cxx', 'cc'];
public const array C_EXT = ['c'];
public const array ASM_EXT = ['s', 'S'];
public const array OBJC_EXT = ['m'];
public const array OBJCXX_EXT = ['mm'];
public const array NATIVE_SRC_EXT = ['cpp', 'cxx', 'cc', 'c', 's', 'S', 'm', 'mm'];
private string $directory;
private array $excludePatterns;
@ -46,6 +57,11 @@ class FileScanner
return in_array(self::getFileExt($file), self::CPP_EXT);
}
public static function isNativeSourceFile(string $file): bool
{
return in_array(self::getFileExt($file), self::NATIVE_SRC_EXT);
}
public function addExcludePattern(string $pattern): self
{
$this->excludePatterns[] = $pattern;
@ -74,9 +90,7 @@ class FileScanner
foreach ($iterator as $file) {
if ($file->isFile()) {
if (self::isPhpFile($file)) {
$filePath = $file->getPathname();
} elseif (self::isCppFile($file)) {
if (self::isPhpFile($file) || self::isNativeSourceFile($file)) {
$filePath = $file->getPathname();
} else {
continue;

@ -341,7 +341,7 @@ class Translator extends Preprocessor
try {
if (FileScanner::isPhpFile($file)) {
$cppFile = $this->convertFile($file);
} elseif (FileScanner::isCppFile($file)) {
} elseif (FileScanner::isNativeSourceFile($file)) {
$cppFile = $file;
} else {
continue;
@ -689,6 +689,33 @@ CODE;
return in_array($extension, ['cc', 'cpp', 'cxx'], true);
}
/**
* 根据文件扩展名获取语言类型标识(用于 -x 参数).
*
* @return string|null 语言标识(c, assembler, objective-c, objective-c++),
* 或 null 表示使用默认检测(C++ 文件)
*/
protected function getLanguageFromExtension(string $filePath): ?string
{
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
return match ($ext) {
'c' => 'c',
's', 'S' => 'assembler',
'm' => 'objective-c',
'mm' => 'objective-c++',
'cc', 'cpp', 'cxx' => null,
default => null,
};
}
/**
* 判断文件是否为原生编译型源文件(C/C++/汇编/ObjC 等).
*/
protected function isNativeSourceFile(string $filePath): bool
{
return FileScanner::isNativeSourceFile($filePath);
}
public function compileFile(string $cppFile, string $objectFile, bool $parallel = false): void
{
if ($this->hasObjectFileCache($cppFile)) {
@ -699,25 +726,33 @@ CODE;
return;
}
// 判断是否为 C++ 文件
$isCppFile = $this->isCppFile($cppFile);
// 检测文件语言类型
$language = $this->getLanguageFromExtension($cppFile);
// 使用 Backend 层构建编译命令
if ($isCppFile) {
if ($language === null) {
// C++ 文件:使用标准的编译命令构建
$cmd = $this->getCompilerBackend()->buildCompileCommand(
$cppFile,
$objectFile,
$this->getCompileCommandOptions()
);
} else {
// C 文件:不能使用 C++ 特定选项(/EHsc, /std:c++17 等)
// 使用 Backend 的 buildCCompileCommand() 方法
} elseif ($language === 'c') {
// C 文件:使用 buildCCompileCommand,后端自动添加 -x c 或 /TC
$cmd = $this->getCompilerBackend()->buildCCompileCommand(
$cppFile,
$objectFile,
$this->getCCompileCommandOptions()
);
} else {
// 其他原生源文件(assembler, objective-c, objective-c++)
// 使用 buildNativeCompileCommand,传入语言类型以添加 -x 标志
$cmd = $this->getCompilerBackend()->buildNativeCompileCommand(
$cppFile,
$objectFile,
$this->getNativeCompileCommandOptions($language),
$language
);
}
if (!$parallel) {

Loading…
Cancel
Save