ubuntu使用protobuf28.3

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文件夹下,然后可以自己把项目移到别的地方

PART2 撰写测试用例

参考链接:https://zhuanlan.zhihu.com/p/641283776

  1. 在本地新建一个文件:addressbook.proto并填充内容:
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

执行ubuntu使用protobuf28.3_第1张图片

你可能感兴趣的:(ubuntu,linux,运维,服务器)