github项目地址https://github.com/protocolbuffers/protobuf.git
这里仅考虑用C++布置环境,首先查看官方readme文档protobuf/src/README.md at main · protocolbuffers/protobuf
使用最新版的protobuf需要bazel和abseil两个库。我使用的是https://github.com/protocolbuffers/protobuf/releases中下载的源码。
接下来开始安装依赖库
1.bazel
安装 Bazel官网上有ubuntu安装的介绍,建议使用方法二,方法一有个文件老是下载不下来
这个博主有详细流程(Ubuntu安装Bazel(最简单的方法)-CSDN博客)
2.abseil库
abseil库的安装-Ubuntu18.04_abseil安装-CSDN博客
接下来开始编译使用protobuf库
工作路径XXX/protobuf/cmake/build/release_shared
执行命令
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../../../install/release_static -Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_TESTS=OFF ../../.. -Dprotobuf_ABSL_PROVIDER=package -DCMAKE_PREFIX_PATH=/usr/local/abseil-cpp -DCMAKE_CXX_STANDARD=17
CMake 命令用于从源代码构建 Protocol Buffers 库,并且指定了使用已安装的 Abseil 库。这个命令配置了 Protocol Buffers 的构建,设置为构建静态库,并且指定了安装前缀、编译类型和其他一些配置选项。
以下是您的命令中一些关键选项的解释:
- `-G "Unix Makefiles"`:指定生成 Unix 风格的 Makefile。
- `-DCMAKE_BUILD_TYPE=Release`:设置构建类型为 Release。
- `-DCMAKE_INSTALL_PREFIX=../../../install/release_static`:设置安装前缀,即构建后的文件将被安装到的目录。
- `-Dprotobuf_BUILD_SHARED_LIBS=OFF:指定构建静态库(这份源码不支持动态库和静态库都构建,如果要构建静态库,这里改成ON)。
- `-Dprotobuf_WITH_ZLIB=OFF`:禁用 Protocol Buffers 对 zlib 的依赖。
- `-Dprotobuf_BUILD_TESTS=OFF`:不构建测试。
- `-Dprotobuf_ABSL_PROVIDER=package`:指定使用已安装的 Abseil 包。
- `-DCMAKE_PREFIX_PATH=/usr/local/abseil-cpp`:指定 Abseil 库的安装前缀。
- `-DCMAKE_CXX_STANDARD=17`:设置 C++ 标准为 C++17。
- `../../..`:指定 CMake 项目的根目录。
如果您希望同时构建静态库和共享库,通常需要为每种类型的库运行单独的 CMake 配置,或者在不同的构建目录中配置它们。但是,根据您的命令,您已经指定了不构建共享库。
在运行此命令之前,请确保:
1. Protocol Buffers 的源代码位于指定的目录结构中。
2. Abseil 库已经安装在 `/usr/local/abseil-cpp` 目录下,并且该目录包含 Abseil 的配置文件(如 `absl-config.cmake`)。
3. 您的系统上已经安装了 CMake,并且版本支持您使用的语法。
如果您遇到任何问题,例如找不到 Abseil 库或 Protocol Buffers 的源文件,您可能需要检查这些路径是否正确,或者确保相应的软件包已经正确安装。如果一切顺利,运行此命令后,您应该能够在 `../../../install/release_static` 目录下找到构建的静态库和头文件。
然后执行make -j4和make install
执行完了之后会把编译到XXX/protobuf/install/release_shared文件夹下,然后可以自己把项目移到别的地方
参考链接:https://zhuanlan.zhihu.com/p/641283776
syntax = "proto2";
package tutorial;
message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
2. /usr/local/protobuf/bin/protoc --cpp_out=. addressbook.proto(这个是绝对路径能保证你绝对不出错,绝对路径填上面自己把项目放的地方,我的放在/usr/local/protobuf)
3.编写reader.cpp
#include
#include
#include
#include "addressbook.pb.h"
using namespace std;
// Iterates though all people in the AddressBook and prints info about them.
void ListPeople(const tutorial::AddressBook& address_book) {
for (int i = 0; i < address_book.people_size(); i++) {
const tutorial::Person& person = address_book.people(i);
cout << "Person ID: " << person.id() << endl;
cout << " Name: " << person.name() << endl;
if (person.has_email()) {
cout << " E-mail address: " << person.email() << endl;
}
for (int j = 0; j < person.phones_size(); j++) {
const tutorial::Person::PhoneNumber& phone_number = person.phones(j);
switch (phone_number.type()) {
case tutorial::Person::MOBILE:
cout << " Mobile phone #: ";
break;
case tutorial::Person::HOME:
cout << " Home phone #: ";
break;
case tutorial::Person::WORK:
cout << " Work phone #: ";
break;
}
cout << phone_number.number() << endl;
}
}
}
// Main function: Reads the entire address book from a file and prints all
// the information inside.
int main(int argc, char* argv[]) {
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book;
{
// Read the existing address book.
fstream input(argv[1], ios::in | ios::binary);
if (!address_book.ParseFromIstream(&input)) {
cerr << "Failed to parse address book." << endl;
return -1;
}
}
ListPeople(address_book);
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
4.编写writer.cpp
#include
#include
#include
#include "addressbook.pb.h"
using namespace std;
// This function fills in a Person message based on user input.
void PromptForAddress(tutorial::Person* person) {
cout << "Enter person ID number: ";
int id;
cin >> id;
person->set_id(id);
cin.ignore(256, '\n');
cout << "Enter name: ";
getline(cin, *person->mutable_name());
cout << "Enter email address (blank for none): ";
string email;
getline(cin, email);
if (!email.empty()) {
person->set_email(email);
}
while (true) {
cout << "Enter a phone number (or leave blank to finish): ";
string number;
getline(cin, number);
if (number.empty()) {
break;
}
tutorial::Person::PhoneNumber* phone_number = person->add_phones();
phone_number->set_number(number);
cout << "Is this a mobile, home, or work phone? ";
string type;
getline(cin, type);
if (type == "mobile") {
phone_number->set_type(tutorial::Person::MOBILE);
} else if (type == "home") {
phone_number->set_type(tutorial::Person::HOME);
} else if (type == "work") {
phone_number->set_type(tutorial::Person::WORK);
} else {
cout << "Unknown phone type. Using default." << endl;
}
}
}
// Main function: Reads the entire address book from a file,
// adds one person based on user input, then writes it back out to the same
// file.
int main(int argc, char* argv[]) {
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book;
{
// Read the existing address book.
fstream input(argv[1], ios::in | ios::binary);
if (!input) {
cout << argv[1] << ": File not found. Creating a new file." << endl;
} else if (!address_book.ParseFromIstream(&input)) {
cerr << "Failed to parse address book." << endl;
return -1;
}
}
// Add an address.
PromptForAddress(address_book.add_people());
{
// Write the new address book back to disk.
fstream output(argv[1], ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
cerr << "Failed to write address book." << endl;
return -1;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
5.编译
g++ -std=c++17 reader.cpp addressbook.pb.cc -o reader-L/usr/local/protobuf/lib /usr/local/protobuf/lib/libprotobuf.a /usr/local/protobuf/lib/libutf8_range.a /usr/local/protobuf/lib/libutf8_validity.a -lpthread -I/usr/local/protobuf/include -labsl
g++ -std=c++17 writer.cpp addressbook.pb.cc -o writer -L/usr/local/protobuf/lib /usr/local/protobuf/lib/libprotobuf.a /usr/local/protobuf/lib/libutf8_range.a /usr/local/protobuf/lib/libutf8_validity.a -lpthread -I/usr/local/protobuf/include -labsl