支持开源,为了更好的后来者
———————————————————————————————————————————————————————By 我说的
以下是一个扩展后的脚本,支持生成 C++、Go、Python、Java 的 Protobuf 和 gRPC 代码,并包含详细的使用说明及复杂依赖处理:
#!/bin/bash
###
# @Author : Zry && [email protected]
# @Date : 2024-01-04 20:11:01
# @LastEditTime : 2024-01-18 16:30:00
# @FilePath : /zry/proto/test.sh
# @Description : 多语言 Protobuf 和 gRPC 代码生成脚本
#
# Copyright (c) 2024 by [email protected], All Rights Reserved.
###
# 默认参数
OUTDIR_PROTO="./gen" # 默认输出目录
LANGUAGES="cpp" # 默认生成 C++
PROTO_PATHS="proto" # 默认 Proto 搜索路径
INPUT_FILES="" # 输入的 Proto 文件或目录
# 使用说明
usage() {
echo "用法: $0 [选项] <输入文件或目录>"
echo "选项:"
echo " -o, --outdir <目录> 输出目录 (默认: ./gen)"
echo " -l, --lang <语言> 生成的语言,逗号分隔 (支持: cpp, go, python, java) (默认: cpp)"
echo " -I, --proto_path <路径> Proto 文件的搜索路径,逗号分隔 (默认: proto)"
echo " -h, --help 显示帮助信息"
echo ""
echo "示例:"
echo " # 生成所有语言的代码,指定输入文件和路径"
echo " $0 -l cpp,go,python,java -I proto,../common proto/example.proto"
echo ""
echo " # 生成 Go 代码并指定输出目录"
echo " $0 -l go -o gen/go proto/**/*.proto"
}
# 解析参数
while [[ "$#" -gt 0 ]]; do
case $1 in
-o|--outdir) OUTDIR_PROTO="$2"; shift ;;
-l|--lang) LANGUAGES="$2"; shift ;;
-I|--proto_path) PROTO_PATHS="$2"; shift ;;
-h|--help) usage; exit 0 ;;
*) INPUT_FILES="$INPUT_FILES $1" ;;
esac
shift
done
# 检查输入文件
if [ -z "$INPUT_FILES" ]; then
echo "错误: 必须指定至少一个输入文件或目录!"
usage
exit 1
fi
# 创建输出目录
mkdir -p "$OUTDIR_PROTO"
# 构造 --proto_path 参数
PROTO_PATH_CMD=""
IFS=',' read -ra PATHS <<< "$PROTO_PATHS"
for path in "${PATHS[@]}"; do
PROTO_PATH_CMD+=" --proto_path=$path"
done
# 遍历每个语言生成代码
IFS=',' read -ra LANGS <<< "$LANGUAGES"
for lang in "${LANGS[@]}"; do
case $lang in
cpp)
# 生成 C++ 和 gRPC 代码
echo "[+] 生成 C++ 代码到 $OUTDIR_PROTO/cpp"
protoc $PROTO_PATH_CMD \
--cpp_out="$OUTDIR_PROTO/cpp" \
--grpc_out="$OUTDIR_PROTO/cpp" \
--plugin=protoc-gen-grpc=/usr/local/bin/grpc_cpp_plugin \
$INPUT_FILES
;;
go)
# 生成 Go 和 gRPC 代码 (需安装 protoc-gen-go 和 protoc-gen-go-grpc)
echo "[+] 生成 Go 代码到 $OUTDIR_PROTO/go"
protoc $PROTO_PATH_CMD \
--go_out="$OUTDIR_PROTO/go" \
--go-grpc_out="$OUTDIR_PROTO/go" \
$INPUT_FILES
;;
python)
# 生成 Python 和 gRPC 代码
echo "[+] 生成 Python 代码到 $OUTDIR_PROTO/python"
protoc $PROTO_PATH_CMD \
--python_out="$OUTDIR_PROTO/python" \
--grpc_python_out="$OUTDIR_PROTO/python" \
$INPUT_FILES
# 修复 Python 包导入问题
touch "$OUTDIR_PROTO/python/__init__.py"
;;
java)
# 生成 Java 和 gRPC 代码 (需安装 protoc-gen-grpc-java)
echo "[+] 生成 Java 代码到 $OUTDIR_PROTO/java"
protoc $PROTO_PATH_CMD \
--java_out="$OUTDIR_PROTO/java" \
--grpc-java_out="$OUTDIR_PROTO/java" \
$INPUT_FILES
;;
*)
echo "错误: 不支持的语言 '$lang'"
exit 1
;;
esac
done
echo "生成完成! 输出目录: $OUTDIR_PROTO"
多语言支持
支持生成 C++、Go、Python、Java 的 Protobuf 和 gRPC 代码。
复杂依赖处理
通过 -I
参数指定多个 Proto 文件搜索路径,解决嵌套依赖问题。例如:
-I proto,../common # 同时搜索 proto/ 和 ../common/
批量编译文件
支持通配符 (*
/**
) 输入多个文件:
proto/**/*.proto # 编译 proto/ 下所有子目录的 .proto 文件
代码结构优化
__init__.py
文件,避免包导入错误。环境依赖检查
需提前安装语言对应的插件:
# C++
sudo apt install protobuf-compiler grpc-tools
# Go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# Python
pip install grpcio-tools
# Java
# 从 Maven 仓库下载 protoc-gen-grpc-java
./test.sh -l cpp,go,python,java -o gen proto/**/*.proto
./test.sh -l go -o gen/go proto/example.proto
若你的 Proto 文件依赖外部目录(如 ../common
):
./test.sh -l cpp -I proto,../common proto/service.proto
gen/
├── cpp/ # C++ 代码
├── go/ # Go 代码
├── python/ # Python 代码
└── java/ # Java 代码
如果提示 protoc-gen-xxx not found
,表示缺少对应语言插件,需按上述说明安装。
确保生成目录中有 __init__.py
,脚本已自动创建该文件。
在 .proto
文件中指定 Go 包路径:
option go_package = "github.com/yourname/project/gen/go";
通过此脚本,可一键生成多语言代码,适应复杂项目结构。
以下是使用 Mermaid 格式绘制的两张图表,用于辅助说明脚本的使用流程和项目结构:
graph TD
A[项目根目录] --> B[proto/]
A --> C[gen/]
B --> D[common/]
D --> D1[common.proto]
D --> D2[error.proto]
B --> E[positioning/]
E --> E1[location.proto]
E --> E2[gps.proto]
C --> F[cpp/]
F --> F1[common.pb.h]
F --> F2[common.pb.cc]
C --> G[go/]
G --> G1[common.pb.go]
G --> G2[location.pb.go]
C --> H[python/]
H --> H1[__init__.py]
H --> H2[common_pb2.py]
C --> I[java/]
I --> I1[Common.java]
I --> I2[Location.java]
说明:
proto/
目录存放原始的 .proto
文件(如 common.proto
和 location.proto
)。gen/
目录是生成的代码输出目录,按语言分为子目录(如 cpp/
、go/
)。.pb.cc
对应 C++,.pb.go
对应 Go)。说明:
-o
)、语言(-l
)和搜索路径(-I
)。.pb.h
和 .pb.cc
文件。protoc-gen-go
生成 .pb.go
文件。_pb2.py
文件,并自动创建 __init__.py
解决包导入问题。.java
文件。生成 C++ 代码:
./test.sh -l cpp -o gen proto/positioning/location.proto
生成多语言代码:
./test.sh -l cpp,go,python -I proto,../common proto/**/*.proto
这两张图表可以帮助用户直观理解脚本的目录结构和编译流程。