You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复gRPC HelloWorld的BitBake编译错误:缺失grpc_cpp_plugin

问题描述

尝试通过BitBake Recipe编译gRPC helloworld示例(目标在嵌入式设备运行greeter-client/server),执行bitbake grpc-helloworld时触发CMake错误:

导入目标gRPC::grpc_cpp_plugin引用的文件/home/buildbot/oe-core/build/tmp/work/aarch64-tdx-linux/grpc-helloworld/1.0.0-r0/recipe-sysroot/usr/bin/grpc_cpp_plugin不存在

当前Recipe文件结构:

recipes-customer/
  grpc-helloworld_1.0.0.bb
  grpc-helloworld/
    CMakeLists.txt
    common.cmake
    greeter_client.cc
    greeter_server.cc
    helloworld.proto

CMakeLists.txt与gRPC官方示例基本一致,仅调整了proto文件和common.cmake路径;此前已将common.cmake中查找Protobuf的语句从find_package(Protobuf CONFIG REQUIRED)改为find_package(Protobuf REQUIRED),否则会出现无法找到Protobuf配置文件的错误。

当前BitBake Recipe内容:

SUMMARY = "gRPC Hello World"
LICENSE = "CLOSED"
DEPENDS += "protobuf grpc"
SRC_URI += "file://CMakeLists.txt file://*.cc file://*.h"
S = "${WORKDIR}"
inherit pkgconfig cmake
原因分析
  1. grpc_cpp_plugin是主机端工具,而非目标端文件:OpenEmbedded构建体系中,用于编译proto的grpc_cpp_plugin和protoc属于主机端编译工具,会安装在${STAGING_BINDIR_NATIVE}目录下;但当前CMake默认在目标端的sysroot(recipe-sysroot)中查找该工具,自然找不到。
  2. Protobuf查找逻辑混淆了主机/目标端:官方示例用find_package(Protobuf CONFIG REQUIRED)是针对主机端带配置文件的Protobuf,而目标端的Protobuf可能没有提供CMake配置文件;直接改为find_package(Protobuf REQUIRED)会让CMake优先查找目标端的Protobuf,导致编译proto时无法调用主机端的protoc工具。
修复方案

1. 调整BitBake Recipe的依赖与CMake参数

修改grpc-helloworld_1.0.0.bb,添加主机端依赖,并传递CMake参数明确区分主机/目标端工具与库:

SUMMARY = "gRPC Hello World"
LICENSE = "CLOSED"
# 同时添加目标端运行依赖和主机端编译依赖
DEPENDS += "protobuf grpc protobuf-native grpc-native"
# 明确列出所有需要的源文件,避免匹配不到common.cmake和proto
SRC_URI += " \
    file://CMakeLists.txt \
    file://common.cmake \
    file://greeter_client.cc \
    file://greeter_server.cc \
    file://helloworld.proto \
"
S = "${WORKDIR}"
inherit pkgconfig cmake

# 告诉CMake优先找主机端的编译工具,仅从目标sysroot找库和头文件
EXTRA_OECMAKE += " \
    -DPROTOBUF_PROTOC_EXECUTABLE=${STAGING_BINDIR_NATIVE}/protoc \
    -DgRPC_CPP_PLUGIN_EXECUTABLE=${STAGING_BINDIR_NATIVE}/grpc_cpp_plugin \
    -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
    -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
    -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
"

2. 修正common.cmake的查找逻辑

将common.cmake中Protobuf和gRPC的查找改为主机/目标端分离:

# 查找主机端的Protobuf和gRPC(用于编译proto文件)
find_package(Protobuf CONFIG REQUIRED PATHS "${STAGING_DIR_NATIVE}/usr/lib/cmake/Protobuf")
find_package(gRPC CONFIG REQUIRED PATHS "${STAGING_DIR_NATIVE}/usr/lib/cmake/gRPC")

# 查找目标端的Protobuf和gRPC库(用于链接最终可执行文件)
find_package(Protobuf REQUIRED PATHS "${STAGING_DIR_TARGET}/usr/lib/cmake/Protobuf" NO_DEFAULT_PATH)
find_package(gRPC REQUIRED PATHS "${STAGING_DIR_TARGET}/usr/lib/cmake/gRPC" NO_DEFAULT_PATH)

# 强制指定主机端的工具路径,避免CMake误判
set(PROTOBUF_PROTOC_EXECUTABLE "${STAGING_BINDIR_NATIVE}/protoc")
set(gRPC_CPP_PLUGIN_EXECUTABLE "${STAGING_BINDIR_NATIVE}/grpc_cpp_plugin")

3. 验证CMakeLists.txt的proto编译逻辑

确保CMakeLists.txt中生成proto代码的部分调用正确的主机工具,官方示例中的这段逻辑可保留(配合上面的参数即可正常工作):

get_filename_component(hw_proto "helloworld.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)

# Generate the code
protobuf_generate_cpp(hw_proto_srcs hw_proto_hdrs "${hw_proto}")
grpc_generate_cpp(hw_grpc_srcs hw_grpc_hdrs "${hw_proto}")

# Link the executables
add_executable(greeter_server greeter_server.cc ${hw_proto_srcs} ${hw_grpc_srcs})
target_link_libraries(greeter_server gRPC::grpc++ gRPC::grpc++_reflection protobuf::libprotobuf)

add_executable(greeter_client greeter_client.cc ${hw_proto_srcs} ${hw_grpc_srcs})
target_link_libraries(greeter_client gRPC::grpc++ gRPC::grpc++_reflection protobuf::libprotobuf)

内容的提问来源于stack exchange,提问作者mmnano50

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:45:37