diff --git a/bin/compiler.php b/bin/compiler.php index bf21073e..4a274398 100755 --- a/bin/compiler.php +++ b/bin/compiler.php @@ -68,7 +68,15 @@ if (empty($sourceFiles)) { } // 生成所有函数声明 -$translator->genFunctionDeclaration("./php_func_decl.h"); +$translator->genFunctionDeclaration($translator->getBuildDir() . "/include/php_func_decl.h"); + +// 生成所有全局变量源文件 +$globalVarsSourceFile = $translator->getBuildDir() . '/global_vars.cc'; +$translator->genGlobalVars($globalVarsSourceFile); +$sourceFiles[] = $globalVarsSourceFile; + +// 添加 main.cc 文件 +$sourceFiles[] = ROOT_PATH . '/src/cpp/main.cc'; // 编译所有 C++ 文件 foreach ($sourceFiles as $cppFile) { diff --git a/bin/linker.php b/bin/linker.php deleted file mode 100644 index de113c8a..00000000 --- a/bin/linker.php +++ /dev/null @@ -1,19 +0,0 @@ -compileBinary($info['filename'], $objectFile); -} catch (Error $error) { - echo "Parse error: {$error->getMessage()}\n"; - return; -} diff --git a/examples/const.php b/examples/const.php new file mode 100644 index 00000000..948a41a8 --- /dev/null +++ b/examples/const.php @@ -0,0 +1,19 @@ +climate->info('do convert: ' . $this->file); + $this->climate->info('convert: ' . $this->file); $parser = (new ParserFactory())->createForNewestSupportedVersion(); $ast = $parser->parse($phpCode); @@ -345,11 +346,7 @@ class Translator extends \PhpAot\Core\Translator public function save(string $code, string $file): void { - $dir = dirname($file); - if (!is_dir($dir)) { - mkdir($dir, 0777, true); - } - file_put_contents($file, $code); + $this->writeFile($file, $code); $this->formatCppCode($file); } @@ -524,7 +521,7 @@ class Translator extends \PhpAot\Core\Translator foreach ($params as $param) { // .stub 存根定义 C++ Native 函数,必须设置函数的参数类型 if ($this->stubFile and !$param->type) { - throw new \RuntimeException('No type for ' . $this->parseIdentifier($param->var)); + throw new RuntimeException('No type for ' . $this->parseIdentifier($param->var)); } $type = $this->parseType($param->type); $name = $this->parseIdentifier($param->var); @@ -1142,7 +1139,7 @@ class Translator extends \PhpAot\Core\Translator { $list = [ $this->phpxDir . '/include', - './', + $this->getBuildDir() . '/include', ]; $out = '$(php-config --includes) '; foreach ($list as $li) { @@ -1198,15 +1195,14 @@ class Translator extends \PhpAot\Core\Translator public function compileBinary(string $targetFile, array $objectFiles): void { - $this->genGlobalVars(); if ($this->climate->arguments->defined('output')) { $targetFile = $this->climate->arguments->get('output'); } - $objectFile = implode(' ', $objectFiles); - $cmd = $this->cppCompiler . ' main.cc global_vars.cc ' . $objectFile . ' -o ' . $targetFile . ' ' . $this->parseLdflags() . $this->parseLibs(); - $this->addCompilationOption($cmd); - $this->climate->comment($cmd); - shell_exec($cmd); + $objectList = implode(' ', $objectFiles); + $linkCmd = $this->cppCompiler . ' ' . $objectList . ' -o ' . $targetFile . ' ' . $this->parseLdflags() . $this->parseLibs(); + $this->addCompilationOption($linkCmd); + $this->climate->comment($linkCmd); + shell_exec($linkCmd); } private function parseBinaryOpConcat(mixed $expr): string @@ -2295,9 +2291,8 @@ class Translator extends \PhpAot\Core\Translator return array_key_exists($name, $this->globalVars); } - private function genGlobalVars(): void + public function genGlobalVars(string $file): void { - $file = 'global_vars.cc'; $code = $this->genIncludeHeaderFiles(); $lines = []; // 全局变量只能是 var 类型 @@ -2316,7 +2311,7 @@ class Translator extends \PhpAot\Core\Translator $this->indentLevel--; $code .= '};' . PHP_EOL; - // 生成全局常量 + // 生成常量表 $this->indentLevel++; foreach ($this->nativeConstants as $name => $constant) { $code .= $constant->type . ' ' . $name . ';' . PHP_EOL; @@ -2328,6 +2323,8 @@ class Translator extends \PhpAot\Core\Translator $lines = []; foreach ($this->nativeConstants as $name => $constant) { $lines[] = $this->getIndent() . $name . ' = ' . $constant->value . ';'; + // 注册到 PHP + $lines[] = $this->getIndent() . 'php::define("' . $name . '", ' . $name . ');'; } $this->indentLevel--; $code .= $this->genFunction(self::PREFIX . 'init_constant_vars', 'void', [], $lines); @@ -2358,7 +2355,8 @@ class Translator extends \PhpAot\Core\Translator $this->indentLevel--; $code .= $this->genFunction(self::PREFIX . 'unset_global_vars', 'void', [], $lines); - file_put_contents($file, $code); + $this->writeFile($file, $code); + $this->formatCppCode($file); } private function genFunction(string $name, string $returnType, array $args = [], array $lines = []): string @@ -2458,7 +2456,7 @@ class Translator extends \PhpAot\Core\Translator $code .= 'extern ' . $constant->type . ' ' . $name . ';' . PHP_EOL; } - file_put_contents($file, $code); + $this->writeFile($file, $code); } private function parseAssignRef(mixed $expr) @@ -2807,4 +2805,25 @@ class Translator extends \PhpAot\Core\Translator $this->stubFile = $this->isStubFile($file); return $phpCode; } + + /** + * @param string $file + * @param string $content + * @return void + */ + private function writeFile(string $file, string $content): void + { + $dir = dirname($file); + if (!is_dir($dir)) { + mkdir($dir, 0777, true); + } + if (!file_put_contents($file, $content)) { + throw new RuntimeException('Can not write file: ' . $file); + } + } + + public function getBuildDir(): string + { + return $this->buildDir; + } } diff --git a/main.cc b/src/cpp/main.cc similarity index 100% rename from main.cc rename to src/cpp/main.cc