编译Protobuf至C++时CMake报错目录不存在的问题求助
问题分析
错误提示-I/home/dbn/work/seal/cmd: No such file or directory,但你确认该目录存在,结合你的CMake代码和操作,问题出在两个核心点:
CMake条件语句语法错误:你的if语句存在路径拼接错误和代码截断:
if(EXISTS "${CMAKE_BINARY_DIR}cmd/proto" AND IS_DIRECTORY "${CMAKE_BINARY_DIR}/cmd/pro这里
${CMAKE_BINARY_DIR}后缺少斜杠,且IS_DIRECTORY的参数未写完(应为${CMAKE_BINARY_DIR}/cmd/proto),导致CMake解析异常,可能干扰后续变量赋值逻辑。Protoc参数与生成路径逻辑混乱:
- 你指定
-I${CMAKE_SOURCE_DIR}作为proto搜索路径,但实际.proto文件存放在proto子目录下,搜索路径应指向该子目录而非根目录; - 原代码将生成的
.pb.cc/.pb.h放到源文件目录proto下,既容易污染源码,也可能和protoc的路径解析逻辑冲突。
- 你指定
修复后的完整CMakeLists.txt
cmake_minimum_required(VERSION 3.25) # 指定proto生成文件的输出目录 SET(MESSAGE_DIR "${CMAKE_SOURCE_DIR}/protogen") # 修正条件语句的路径拼接与语法完整性 if(EXISTS "${CMAKE_BINARY_DIR}/cmd/proto" AND IS_DIRECTORY "${CMAKE_BINARY_DIR}/cmd/proto") SET(PROTO_META_BASE_DIR ${MESSAGE_DIR}) else() file(MAKE_DIRECTORY ${MESSAGE_DIR}) SET(PROTO_META_BASE_DIR ${MESSAGE_DIR}) endif() # 设置proto文件的正确搜索路径 LIST(APPEND PROTO_FLAGS -I${CMAKE_SOURCE_DIR}/proto) # 递归查找所有proto文件 file(GLOB_RECURSE MSG_PROTOS "${CMAKE_SOURCE_DIR}/proto/*.proto") set(MESSAGE_SRC "") set(MESSAGE_HDRS "") foreach(msg ${MSG_PROTOS}) get_filename_component(FIL_WE ${msg} NAME_WE) # 生成文件路径指向专门的protogen目录 list(APPEND MESSAGE_SRC "${PROTO_META_BASE_DIR}/${FIL_WE}.pb.cc") list(APPEND MESSAGE_HDRS "${PROTO_META_BASE_DIR}/${FIL_WE}.pb.h") add_custom_command( OUTPUT "${PROTO_META_BASE_DIR}/${FIL_WE}.pb.cc" "${PROTO_META_BASE_DIR}/${FIL_WE}.pb.h" COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} # 修正protoc的搜索路径参数,指向proto文件实际所在目录 ARGS --cpp_out=${PROTO_META_BASE_DIR} -I${CMAKE_SOURCE_DIR}/proto ${msg} DEPENDS ${msg} COMMENT "Running C++ protocol buffer compiler on ${msg}" VERBATIM ) endforeach() # 添加自定义目标触发protoc编译(原代码缺失此关键步骤) add_custom_target(generate_proto ALL DEPENDS ${MESSAGE_SRC} ${MESSAGE_HDRS})
关键修改说明
- 修复条件语句:补全路径拼接的斜杠和未完成的参数,确保CMake能正确判断目录存在性;
- 调整生成路径:将编译产物放到独立的
protogen目录,避免污染源码目录; - 修正protoc搜索路径:将
-I指向.proto文件实际所在的proto子目录,匹配你的目录结构; - 添加触发目标:原代码没有触发自定义命令的入口,
add_custom_target确保CMake执行protoc编译流程。
验证操作步骤
- 清理旧构建目录(如果存在):
rm -rf build && mkdir build && cd build - 重新执行CMake配置与构建:
cmake .. && make
内容的提问来源于stack exchange,提问作者ri yo
相关产品推荐
相关产品推荐

