feat(compiler): 添加编译后运行功能支持

- 实现命令行参数解析功能,支持路径和选项参数
- 添加 --run/-r 选项用于编译完成后立即执行二进制文件
- 更新帮助信息显示新的运行选项
- 修改 build 方法返回目标文件路径而不是 void
- 实现 run 方法执行编译后的二进制文件
- 添加目标参数获取功能支持传递给执行程序
- 移除简单的文件参数检查逻辑
pull/1/head
韩天峰 3 months ago
parent 4a2b2ef201
commit 3045259ae0
  1. 13
      bin/compiler.php
  2. 6
      src/Php/Constants.php
  3. 54
      src/Php/Translator.php

@ -6,18 +6,17 @@ require __DIR__ . '/../src/gen_stub.php';
use PhpAot\Php\Translator;
if (empty($argv[1])) {
die("php compiler.php [file]\n");
}
$path = $argv[1];
$translator = new Translator(ROOT_PATH);
$translator->setIndent(' ');
// 扫描所有 PHP 文件,预处理
$files = $translator->prepare($path);
$files = $translator->prepare($translator->parseArgv($argv));
// 生成 C++ 文件
$sourceFiles = $translator->convert($files);
// 编译所有 C++ 文件
$objectFiles = $translator->compile($sourceFiles);
// 连接所有目标文件,生成可执行文件
$translator->build($objectFiles);
$binaryFile = $translator->build($objectFiles);
// 如果指定了 --run / -r,编译完成后立即执行
if ($translator->isRunRequested()) {
$translator->run($binaryFile); // never returns
}

@ -118,6 +118,12 @@ class Constants
'required' => false,
'defaultValue' => CompilerBase::BUILD_MODE_BIN,
],
'run' => [
'prefix' => 'r',
'longPrefix' => 'run',
'description' => 'Run the compiled binary after build',
'noValue' => true,
],
// 内部开发选项,用于定位特定行的翻译问题,请勿写入用户文档
'debug-line' => [
'longPrefix' => 'debug-line',

@ -78,6 +78,22 @@ class Translator extends Preprocessor
$this->detectPlatform();
}
public function parseArgv(array $argv)
{
$path = null;
for ($i = 1; $i < count($argv); $i++) {
if ($argv[$i] !== '' && $argv[$i][0] !== '-') {
$path = $argv[$i];
break;
}
}
if (empty($path)) {
$this->showUsage();
exit(1);
}
return $path;
}
public function showUsage(): void
{
$climate = $this->climate;
@ -105,6 +121,7 @@ class Translator extends Preprocessor
$climate->tab()->out('-h, --help Show this help message');
$climate->tab()->out('-f, --force Force compile even if cache exists');
$climate->tab()->out('-m, --mode <mode> Compilation mode, -m bin(binary) or -m ext(extension), default: bin');
$climate->tab()->out('-r, --run Run the compiled binary after build');
$climate->tab()->out('-j, --job <num> Number of parallel compilation jobs (default: 4)');
$climate->tab()->out('--no-literal-strings Disable literal strings optimization');
$climate->tab()->out('--no-console Hide console window (Windows only, GUI application)');
@ -121,6 +138,7 @@ class Translator extends Preprocessor
$climate->tab()->out($cmd . ' app.php --sanitize=address (Enable AddressSanitizer)');
$climate->tab()->out($cmd . ' app.php --cxx-std=c++17 (Use C++17 standard)');
$climate->tab()->out($cmd . ' app.php --no-literal-strings (Disable string optimization)');
$climate->tab()->out($cmd . ' app.php -r -O2 -- --flag1 value1');
$climate->br();
}
@ -1039,7 +1057,7 @@ CODE;
}
}
public function build(array $objectFiles): void
public function build(array $objectFiles): string
{
$targetFile = $this->getTargetFileName();
@ -1075,6 +1093,40 @@ CODE;
}
$this->climate->green('Build successful: ' . $targetFile);
return $targetFile;
}
public function isRunRequested(): bool
{
return $this->climate->arguments->defined('run');
}
public function run(string $targetFile): never
{
if ($this->buildMode !== self::BUILD_MODE_BIN) {
$this->climate->error('--run is only supported in binary mode (-m bin), not extension mode (-m ext)');
exit(1);
}
if (DIRECTORY_SEPARATOR !== '\\' && !str_starts_with($targetFile, '/')) {
$targetFile = './' . $targetFile;
}
$targetArgs = $this->getTargetArgs();
$command = escapeshellcmd($targetFile);
if (!empty($targetArgs)) {
$command .= ' ' . implode(' ', array_map('escapeshellarg', $targetArgs));
}
fwrite(STDERR, "Running: {$command}\n");
passthru($command, $exitCode);
exit($exitCode);
}
public function getTargetArgs(): array
{
return $this->climate->arguments->trailingArray() ?? [];
}
public function genFunctionDeclaration(string $file): void

Loading…
Cancel
Save