refactor(build): encapsulate project build runner

master
韩天峰 3 weeks ago
parent a6cd47b8dc
commit 28413e0924
  1. 106
      src/Build/ProjectBuildRunner.php
  2. 66
      src/compiler.php

@ -0,0 +1,106 @@
<?php
/**
* This file is part of TypePHP(AOT).
*
* @link https://www.swoole.com/aot/
* @contact service@swoole.com
*/
namespace TypePhp\Build;
use TypePhp\Translator;
final readonly class ProjectBuildRunner
{
public function __construct(private Translator $translator)
{
}
/** @param list<string> $arguments */
public function run(array $arguments): void
{
$this->translator->setIndent(' ');
$sourceFiles = $this->generateProjectSources($arguments);
$sourceFiles = $this->appendInternalWasmInterface($sourceFiles);
if ($this->translator->isDryRun()) {
$this->finishDryRun($sourceFiles);
return;
}
$target = $this->compileAndLink($sourceFiles);
if ($this->translator->isRunRequested()) {
$this->translator->run($target);
}
}
/** @param list<string> $arguments @return list<string> */
private function generateProjectSources(array $arguments): array
{
$project = $this->translator->parseArgv($arguments);
$files = $this->translator->prepare($project);
return $this->translator->convert($files);
}
/** @param list<string> $sourceFiles @return list<string> */
private function appendInternalWasmInterface(array $sourceFiles): array
{
$manifest = $this->environmentValue('TYPEPHP_WASM_INTERFACE_MANIFEST');
if ($manifest === null) {
return $sourceFiles;
}
$adapter = $this->requiredEnvironmentValue('TYPEPHP_WASM_INTERFACE_ADAPTER');
$this->translator->writeWasmInterface(
$manifest,
$this->requiredEnvironmentValue('TYPEPHP_WASM_INTERFACE_WIT'),
$adapter,
$this->requiredEnvironmentValue('TYPEPHP_WASM_INTERFACE_ASYNC_EXPORTS'),
$this->requiredEnvironmentValue('TYPEPHP_WASM_PACKAGE'),
$this->requiredEnvironmentValue('TYPEPHP_WASM_WORLD'),
);
$sourceFiles[] = $adapter;
return $sourceFiles;
}
private function environmentValue(string $name): ?string
{
$value = getenv($name);
return is_string($value) && $value !== '' ? $value : null;
}
private function requiredEnvironmentValue(string $name): string
{
$value = $this->environmentValue($name);
if ($value === null) {
throw new \RuntimeException('Incomplete internal WASM interface configuration: ' . $name);
}
return $value;
}
/** @param list<string> $sourceFiles */
private function finishDryRun(array $sourceFiles): void
{
$sourceList = $this->environmentValue('TYPEPHP_GENERATED_SOURCE_LIST');
if ($sourceList !== null) {
AtomicFile::write($sourceList, implode(PHP_EOL, $sourceFiles) . PHP_EOL);
}
$count = count($sourceFiles);
$buildDir = $this->translator->getBuildDir();
$this->translator->output(
"Dry run completed: {$count} C++ source file(s) generated in {$buildDir}",
'lightBlue',
);
}
/** @param list<string> $sourceFiles */
private function compileAndLink(array $sourceFiles): string
{
$objectFiles = [
...$this->translator->compile($sourceFiles),
...$this->translator->getProjectObjectFiles(),
];
return $this->translator->build($objectFiles);
}
}

@ -5,6 +5,7 @@ use TypePhp\Build\WasiProjectConfig;
use TypePhp\Build\PhpxLocator; use TypePhp\Build\PhpxLocator;
use TypePhp\Build\NativeSourceProjectBuilder; use TypePhp\Build\NativeSourceProjectBuilder;
use TypePhp\Build\NativeSourceProjectConfig; use TypePhp\Build\NativeSourceProjectConfig;
use TypePhp\Build\ProjectBuildRunner;
use TypePhp\PythonTools\Command as PythonToolsCommand; use TypePhp\PythonTools\Command as PythonToolsCommand;
use TypePhp\Cli\CompletionCommand; use TypePhp\Cli\CompletionCommand;
@ -72,67 +73,7 @@ function main(int $argc, array $argv): void
return; return;
} }
$translator = Translator::getInstance(); (new ProjectBuildRunner(Translator::getInstance()))->run($argv);
$translator->setIndent(' ');
// Scan all PHP files and preprocess them.
$files = $translator->prepare($translator->parseArgv($argv));
// Generate the C++ source files.
$sourceFiles = $translator->convert($files);
$wasmManifest = getenv('TYPEPHP_WASM_INTERFACE_MANIFEST');
if (is_string($wasmManifest) && $wasmManifest !== '') {
$wasmWit = getenv('TYPEPHP_WASM_INTERFACE_WIT');
$wasmAdapter = getenv('TYPEPHP_WASM_INTERFACE_ADAPTER');
$wasmAsyncExports = getenv('TYPEPHP_WASM_INTERFACE_ASYNC_EXPORTS');
$wasmPackage = getenv('TYPEPHP_WASM_PACKAGE');
$wasmWorld = getenv('TYPEPHP_WASM_WORLD');
if (!is_string($wasmWit) || $wasmWit === ''
|| !is_string($wasmAdapter) || $wasmAdapter === ''
|| !is_string($wasmAsyncExports) || $wasmAsyncExports === ''
|| !is_string($wasmPackage) || $wasmPackage === ''
|| !is_string($wasmWorld) || $wasmWorld === '') {
throw new RuntimeException('Incomplete internal WASM interface configuration');
}
$translator->writeWasmInterface(
$wasmManifest,
$wasmWit,
$wasmAdapter,
$wasmAsyncExports,
$wasmPackage,
$wasmWorld,
);
$sourceFiles[] = $wasmAdapter;
}
// --dry mode: only generate the C++ code, without compiling.
if ($translator->isDryRun()) {
$buildDir = $translator->getBuildDir();
$count = count($sourceFiles);
$sourceListFile = getenv('TYPEPHP_GENERATED_SOURCE_LIST');
if (is_string($sourceListFile) && $sourceListFile !== '') {
$sourceListDir = dirname($sourceListFile);
if (!is_dir($sourceListDir) && !mkdir($sourceListDir, 0777, true) && !is_dir($sourceListDir)) {
throw new RuntimeException("Unable to create generated source manifest directory: {$sourceListDir}");
}
if (file_put_contents($sourceListFile, implode(PHP_EOL, $sourceFiles) . PHP_EOL) === false) {
throw new RuntimeException("Unable to write generated source manifest: {$sourceListFile}");
}
}
$translator->output("Dry run completed: {$count} C++ source file(s) generated in {$buildDir}", 'lightBlue');
return;
}
// Compile all C++ source files.
$objectFiles = [
...$translator->compile($sourceFiles),
...$translator->getProjectObjectFiles(),
];
// Link all object files to produce the executable.
$binaryFile = $translator->build($objectFiles);
// If --run / -r was specified, execute immediately after compilation.
if ($translator->isRunRequested()) {
$translator->run($binaryFile); // never returns
}
} }
function shouldCompileNativeSourceProject(array $argv): bool function shouldCompileNativeSourceProject(array $argv): bool
@ -321,9 +262,6 @@ function compileWasmProgram(array $argv): void
} }
$environment = getenv(); $environment = getenv();
if (!is_array($environment)) {
$environment = [];
}
$environment['TYPEPHP_WASI_CC'] = $tools['clang']; $environment['TYPEPHP_WASI_CC'] = $tools['clang'];
$environment['TYPEPHP_WASI_CXX'] = $tools['clang++']; $environment['TYPEPHP_WASI_CXX'] = $tools['clang++'];
$environment['TYPEPHP_WASI_AR'] = $tools['llvm-ar']; $environment['TYPEPHP_WASI_AR'] = $tools['llvm-ar'];

Loading…
Cancel
Save