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

如何在Yocto构建中使用构建版protoc而非主机版protoc?

问题:Yocto构建中Makefile调用主机protoc导致版本冲突

在Yocto 2.2(Morty)环境移植gRPC C++示例时,已成功集成protobuf 3.3.0和gRPC 1.4.3,但构建过程中Makefile始终调用主机系统的protoc 3.21.12版本,生成的代码依赖高版本protobuf头文件,出现以下编译错误:

| In file included from helloworld.pb.cc:4:0:
| helloworld.pb.h:10:10: fatal error: google/protobuf/port_def.inc: No such file or directory
| #include <google/protobuf/port_def.inc>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| compilation terminated.
| : recipe for target 'helloworld.pb.o' failed
| make: *** [helloworld.pb.o] Error 1
| WARNING: exit code 2 from a shell command.

以下是解决方法:

步骤1:修改hello.bb配方,传递Yocto构建工具路径

在配方中添加原生依赖,并通过环境变量传递Yocto构建的protoc和插件路径,确保构建时使用正确版本的工具:

DESCRIPTION = "Working example for grpc"
AUTHOR = ""
LICENSE = "Apache-2.0"
HOMEPAGE = ""
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"

# 添加原生依赖,获取主机端可用的protoc和grpc插件
DEPENDS = "grpc-native protobuf3-native grpc protobuf3 c-ares zlib openssl"
RDEPENDS_${PN} += "libstdc++"

SRCREV = "29a2a533c98aa21f05c8f598ef2b47321508d5da"
BRANCH = "v1.4.x"
SRC_URI = "gitsm://github.com/grpc/grpc.git;protocol=https;name=grpc;branch=${BRANCH}"

PR = "r0"

S = "${WORKDIR}/git"

EXTRA_OECMAKE = "-DRUN_HAVE_STD_REGEX=1 \
     -DRUN_HAVE_POSIX_REGEX=0 \
     -DRUN_HAVE_STEADY_CLOCK=0 \
     -DTHREADS_PTHREAD_ARG=2 \
     -DBUILD_DEPS=ON \
     -DHAVE_STD_REGEX=ON \
     -DRUN_HAVE_STD_REGEX=1 \
     "

do_compile() {
    # 导出环境变量,指定Yocto构建的工具路径
    export PROTOC="${STAGING_BINDIR_NATIVE}/protoc"
    export GRPC_CPP_PLUGIN="${STAGING_BINDIR_NATIVE}/grpc_cpp_plugin"
    export PKG_CONFIG_PATH="${STAGING_LIBDIR}/pkgconfig:${STAGING_DATADIR}/pkgconfig"
    
    cd ${S}/examples/cpp/helloworld/
    make all
}

FILES_${PN} += "${bindir}/*"

do_install() {
    install -d ${D}${bindir}
    install -m 0755 ${S}/examples/cpp/helloworld/greeter_client ${D}${bindir}
    install -m 0755 ${S}/examples/cpp/helloworld/greeter_server ${D}${bindir}
}

步骤2:修改Makefile,使用环境变量指定工具路径

移除硬编码的主机路径和工具检查逻辑,直接使用Yocto传递的环境变量:

HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = ${CXX}
# 使用Yocto提供的标准头文件路径,无需硬编码
CXXFLAGS += -I${STAGING_INCDIR} -pthread -std=c++11
LDFLAGS += -L${STAGING_LIBDIR} `pkg-config --libs grpc++ grpc`       \
           -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \
           -lprotobuf -lpthread -ldl

# 从环境变量获取工具路径,优先使用Yocto传递的值
PROTOC ?= protoc
GRPC_CPP_PLUGIN ?= grpc_cpp_plugin
PROTOS_PATH = ../../protos

vpath %.proto $(PROTOS_PATH)

all: greeter_client greeter_server

greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
        $(CXX) $^ $(LDFLAGS) -o $@

greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o
        $(CXX) $^ $(LDFLAGS) -o $@

.PRECIOUS: %.grpc.pb.cc
%.grpc.pb.cc: %.proto
        $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN) $<

.PRECIOUS: %.pb.cc
%.pb.cc: %.proto
        $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<

clean:
        rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server

关键说明

Yocto构建环境中,STAGING_BINDIR_NATIVE目录存放的是适配构建主机的工具(包括对应版本的protoc和grpc_cpp_plugin),通过将其路径导出为环境变量传递给Makefile,就能强制使用Yocto构建的工具版本,彻底避免与主机系统高版本工具的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 15:55:02