我正在尝试创建一个使用 protobuf 和 cmake 构建系统的小型 C++ 测试项目。
我设法通过单个目录和单个 来使所有内容正常工作CMakeLists.txt
。
然而,这不是一个可扩展的结构。
我尝试的下一个更改是创建一个proto
目录,并将文件移动*.proto
到该目录中。
该项目不再构建,我不知道如何修复它。
我在网上搜索解决方案,也尝试询问 ChatGPT。ChatGPT 转了好几圈,通过搜索我在网上能找到的有限资源,我发现了似乎变化很大的解决方案。我不清楚在众多变化中哪一个可能是正确的方法,但这很可能是因为我不是这方面的专家cmake
,所以无法弄清楚如何将各个部分组合在一起。
这是我目前拥有的:
protobuf-example/
proto/
CMakeLists.txt
message.proto
CMakeLists.txt
main.cpp
proto/CMakeLists.txt
我不太确定下面需要什么。我对每行代码的作用有一些了解,但理解得不是太透彻。
set(PROTO_FILES message.proto)
set(GENERATED_PROTO_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
file(MAKE_DIRECTORY ${GENERATED_PROTO_DIR})
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES})
add_library(proto_files STATIC ${PROTO_SRCS})
target_include_directories(proto_files PUBLIC ${Protobuf_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(proto_files PUBLIC ${Protobuf_LIBRARIES})
set(PROTO_GEN_SRCS ${PROTO_SRCS} PARENT_SCOPE)
set(PROTO_GEN_HDRS ${PROTO_HDRS} PARENT_SCOPE)
set(PROTO_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
message.proto
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
string email = 3;
}
CMakeLists.txt
另一方面,我熟悉这些语句,并且我确信我知道每个语句的作用。
cmake_minimum_required(VERSION 3.10)
project(ProtobufExample LANGUAGES CXX)
find_package(Protobuf REQUIRED)
add_subdirectory(proto)
add_executable(protobuf_example main.cpp ${PROTO_GEN_SRCS})
target_include_directories(protobuf_example PRIVATE ${Protobuf_INCLUDE_DIR})
target_link_libraries(protobuf_example PRIVATE ${proto_files})
main.cpp
据我所知,这只是一个标准的例子。
#include <iostream>
#include <fstream>
#include "message.pb.h"
void serializePerson(const std::string& filename) {
Person person;
person.set_name("John Doe");
person.set_age(30);
person.set_email("[email protected]");
std::ofstream output(filename, std::ios::binary);
if (!person.SerializeToOstream(&output)) {
std::cerr << "Failed to serialize data." << std::endl;
}
}
void deserializePerson(const std::string& filename) {
Person person;
std::ifstream input(filename, std::ios::binary);
if (!person.ParseFromIstream(&input)) {
std::cerr << "Failed to parse data." << std::endl;
} else {
std::cout << "Name: " << person.name() << "\n"
<< "Age: " << person.age() << "\n"
<< "Email: " << person.email() << std::endl;
}
}
int main() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
const std::string filename = "person.data";
serializePerson(filename);
deserializePerson(filename);
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
错误
具体的错误信息为:
Cannot find source file:
/home/user/cmake-protobuf-test/protobuf-example/build/proto/message.pb.cc
这很可能是因为build/proto/generated
目录是空的。
看起来好像protobuf_generate_cpp
没有执行任何操作。但是没有产生与此相关的错误或警告。
有两个问题。第一个:
必须是
因为
${PROTO_GEN_SRCS}
是的来源proto_files
。并且拼写错误:
必须是
因为目标不是变量。
有点吹毛求疵。这没有必要
因为进一步
target_link_libraries
将#include 带到了protobuf_example
。这也导致这也是不必要的