compile_protos.php 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/env php
  2. <?php
  3. /**
  4. * 自动编译 protos 目录下所有 .proto 文件
  5. * 使用方法:php compile_protos.php [输出目录]
  6. */
  7. // 参数检查
  8. if ($argc < 2) {
  9. echo "Usage: php compile_protos.php <output_dir>\n";
  10. exit(1);
  11. }
  12. $protoDir = __DIR__ . '/protos';
  13. $outputDir = rtrim($argv[1], '/');
  14. // 检查 protoc 是否可用
  15. exec('protoc --version 2>&1', $output, $retval);
  16. if ($retval !== 0) {
  17. echo "Error: protoc compiler not found. Please install it first.\n";
  18. echo "On macOS: brew install protobuf\n";
  19. echo "On Linux: sudo apt-get install protobuf-compiler\n";
  20. echo "On Windows: choco install protoc\n";
  21. exit(1);
  22. }
  23. // 创建输出目录
  24. if (!file_exists($outputDir)) {
  25. mkdir($outputDir, 0755, true);
  26. }
  27. // 递归查找所有 .proto 文件
  28. $files = new RecursiveIteratorIterator(
  29. new RecursiveDirectoryIterator($protoDir),
  30. RecursiveIteratorIterator::LEAVES_ONLY
  31. );
  32. $protoFiles = [];
  33. foreach ($files as $file) {
  34. if ($file->getExtension() === 'proto') {
  35. $protoFiles[] = $file->getRealPath();
  36. }
  37. }
  38. if (empty($protoFiles)) {
  39. echo "No .proto files found in {$protoDir}\n";
  40. exit(0);
  41. }
  42. // 编译每个文件
  43. $successCount = 0;
  44. foreach ($protoFiles as $protoFile) {
  45. $relativePath = substr($protoFile, strlen($protoDir) + 1);
  46. echo "Compiling {$relativePath}... ";
  47. $command = sprintf(
  48. 'protoc --php_out=%s --proto_path=%s %s 2>&1',
  49. escapeshellarg($outputDir),
  50. escapeshellarg(dirname($protoFile)),
  51. escapeshellarg($protoFile)
  52. );
  53. exec($command, $output, $retval);
  54. if ($retval === 0) {
  55. echo "OK\n";
  56. $successCount++;
  57. } else {
  58. echo "FAILED\n";
  59. echo "Error output:\n" . implode("\n", $output) . "\n";
  60. }
  61. }
  62. echo "\nResult: {$successCount}/" . count($protoFiles) . " files compiled successfully\n";
  63. // 生成自动加载文件
  64. generateAutoload($outputDir);
  65. /**
  66. * 生成 composer 自动加载配置
  67. */
  68. function generateAutoload(string $outputDir) {
  69. $autoloadFile = $outputDir . '/composer.json';
  70. if (!file_exists($autoloadFile)) {
  71. file_put_contents($autoloadFile, json_encode([
  72. 'name' => 'generated/protobuf-messages',
  73. 'autoload' => [
  74. 'psr-4' => [
  75. '' => './'
  76. ]
  77. ]
  78. ], JSON_PRETTY_PRINT));
  79. echo "\nGenerated composer.json for autoloading. Run 'composer dump-autoload' if needed.\n";
  80. }
  81. }