Protobuf use case under ubuntu [Command line -> cmake -> VS code -> bazel]

System: ubuntu 18.04

Click to download the sample program protobuf.tar.xz used in this blog

The directory tree after decompression of the protobuf.tar.xz file is as follows, download it as needed:
Insert picture description here

One, protobuf installation

sudo apt-get install autoconf automake libtool curl make g++ unzip git
git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure
make
sudo make install
sudo ldconfig
protoc --version

If a message similar to the following is output at the end, the protobuf installation is successful.
Insert picture description here

Second, use protobuf on the command line

2.1 Build the proto file

mkdir -p CSDN_ws/protobuf/teminal/
cd CSDN_ws/protobuf/teminal/
gedit AddressBook.proto

Copy the following text to AddressBook.proto and save it.

package tutorial;

message Person {
    required string name=1;
    required int32 id=2;
    optional string email=3;

    enum PhoneType {
        MOBILE=0;
        HOME=1;
        WORK=2;
    }

    message PhoneNumber {
        required string number=1;
        optional PhoneType type=2 [default=HOME];
    }

    repeated PhoneNumber phone=4;
}

message AddressBook {
    repeated Person person=1;
}

2.2 Generate c++ header files

protoc --cpp_out=./ AddressBook.proto
ls

At this time, it is found that there are two more files in the directory: AddressBook.pb.ccand AddressBook.pb.h.
Insert picture description here

2.3 Use protobuf header files

gedit main.cpp

Copy the following text to main.cpp and save it.

#include <iostream>
#include <fstream>
#include <vector>
#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_phone();
        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;
        }
    }
}


int main(int argc, char *argv[])
{
    
    
    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_person());

    {
    
    
    // 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;
}

Then execute the following command to compile on the command line:

g++ AddressBook.pb.cc main.cpp -o main `pkg-config --cflags --libs protobuf`
ls

If the compilation is successful, there will be an extra file named main .
Insert picture description hereExecuting main will let you enter information:

./main name.txt

Insert picture description hereThe above is all the process of using protobuf under teminal. After the end, your workspace should be as follows:
Insert picture description here

Three, use protobuf under cmake

3.1 Install cmake

sudo apt-get install cmake cmake-qt-qui

3.2 Writing CMakeLists files

mkdir -p CSDN_ws/protobuf/cmake/
cp CSDN_ws/protobuf/teminal/AddressBook.proto CSDN_ws/protobuf/cmake/AddressBook.proto
cp CSDN_ws/protobuf/teminal/main.cpp CSDN_ws/protobuf/cmake/main.cpp
cd CSDN_ws/protobuf/cmake/
gedit CMakeLists.txt

Copy the following content into the CMakeLists.txt file:

cmake_minimum_required(VERSION 3.10)
PROJECT (cppTest)
SET(SRC_LIST main.cpp)

# Find required protobuf package
find_package(Protobuf REQUIRED)
if(PROTOBUF_FOUND)
    message(STATUS "protobuf library found")
else()
    message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()

include_directories(${PROTOBUF_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS AddressBook.proto)

ADD_EXECUTABLE(cppTest ${SRC_LIST} ${PROTO_SRCS} ${PROTO_HDRS})

target_link_libraries(cppTest ${PROTOBUF_LIBRARIES})

3.3 cmake compile and run

cd CSDN_ws/protobuf/cmake/
cmake .
make 
./cppTest  name.txt

The result of the operation is the same as that of the terminal, and the final file directory is as follows:
Insert picture description here

Four, use protobuf under VS code

4.1 Install VS code

ubuntu 18.04 enter ubuntu software, enter visual studio code, install:

Insert picture description here

Go to VS Code's own store to download the plug-in, shortcut key: Ctrl+Shift+x, download various dependency packages, including: c/c++, c/c++ clang command adapter, c++ intellisense, CMake and CMake Tools as shown in the figure below :
Insert picture description here

4.2 Compile and execute

Build the vscode folder and open the vs code:

mkdir CSDN_ws/protobuf/vscode/
cp CSDN_ws/protobuf/cmake/AddressBook.proto CSDN_ws/protobuf/vscode/AddressBook.proto
cp CSDN_ws/protobuf/cmake/main.cpp CSDN_ws/protobuf/vscode/main.cpp
cp CSDN_ws/protobuf/cmake/CMakeLists.txt CSDN_ws/protobuf/vscode/CMakeLists.txt
cd CSDN_ws/protobuf/vscode/
code .

Click the Debug button on the left, select Add configuration, and then select C++ (GDB/LLDB), the launch.json file will be automatically generated as follows:

{
    
    
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
    
    
            "name": "g++ - Build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/cppTest",
            "args": ["name.txt"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
    
    
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: g++ build active file",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

Click F5 on the vs code interface, and you will be prompted to configure the task.json file. Copy the following text to the default task.json file:

{
    
    
	"version": "2.0.0",
	"tasks": [
		{
    
    
			"type": "shell",
			"label": "protobuf build",
			"command": "cmake . && make",
			"group": "build"
		}
	]
}

Go back to the main.cpp interface, click F5, the compilation message will be displayed, and finally the running result:
Insert picture description here

The final file directory is as follows:
Insert picture description here
If you miss this smoothness, you will probably find the following discordant wavy line:

Insert picture description here
Click on the small yellow light bulb in the picture, there will be several small tips ( this light bulb does not affect compilation, but the header file is not recognized by VS code and cannot be automatically completed ), click Add to "includePath":${workspaceFolder}and you will find that one more is born c_cpp_properties.json:

{
    
    
    "configurations": [
        {
    
    
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "${workspaceFolder}"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/clang",
            "cStandard": "c11",
            "cppStandard": "c++14",
            "intelliSenseMode": "clang-x64"
        }
    ],
    "version": 4
}

Finally, the VS code file directory is as follows:
Insert picture description here

Five, bazel

5.1 Install bazel

sudo apt install curl gnupg
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
sudo apt update && sudo apt install bazel

You can use Bazel to get started: compile C++ projects and get familiar with it.

5.2 Build the project

This part refers to the use of Bazel: compile protobuf .

mkdir -p CSDN_ws/protobuf/bazel/
cp CSDN_ws/protobuf/teminal/AddressBook.proto CSDN_ws/protobuf/bazel/AddressBook.proto
cp CSDN_ws/protobuf/teminal/main.cpp CSDN_ws/protobuf/bazel/main.cpp
cd CSDN_ws/protobuf/bazel/
gedit WORKSPACE

Enter the following in the WORKSPACE file:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# rules_cc defines rules for generating C++ code from Protocol Buffers.
http_archive(
    name = "rules_cc",
    sha256 = "35f2fb4ea0b3e61ad64a369de284e4fbbdcdba71836a5555abb5e194cf119509",
    strip_prefix = "rules_cc-624b5d59dfb45672d4239422fa1e3de1822ee110",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_cc/archive/624b5d59dfb45672d4239422fa1e3de1822ee110.tar.gz",
        "https://github.com/bazelbuild/rules_cc/archive/624b5d59dfb45672d4239422fa1e3de1822ee110.tar.gz",
    ],
)

# rules_proto defines abstract rules for building Protocol Buffers.
http_archive(
    name = "rules_proto",
    sha256 = "2490dca4f249b8a9a3ab07bd1ba6eca085aaf8e45a734af92aad0c42d9dc7aaf",
    strip_prefix = "rules_proto-218ffa7dfa5408492dc86c01ee637614f8695c45",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/218ffa7dfa5408492dc86c01ee637614f8695c45.tar.gz",
        "https://github.com/bazelbuild/rules_proto/archive/218ffa7dfa5408492dc86c01ee637614f8695c45.tar.gz",
    ],
)

load("@rules_cc//cc:repositories.bzl", "rules_cc_dependencies")
rules_cc_dependencies()

load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()

5.3 Writing BUILD

gedit BUILD
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")

cc_proto_library(
    name = "AddressBook_proto",
    deps = [":AddressBook_proto_lib"],
)

proto_library(
    name = "AddressBook_proto_lib",
    srcs = ["AddressBook.proto"],
)

cc_binary(
    name = "main",
    srcs = ["main.cpp"],
    deps = ["AddressBook_proto"],
)

5.4 Compile and execute the project

Execute the following command to compile the project

sudo bazel build :main

Get the following output information:
Insert picture description here

Execute the following command to execute the project

./bazel-bin/main name.txt

Get the following results:
Insert picture description here


END
by windSeS
2020-8-12

Guess you like

Origin blog.csdn.net/u013468614/article/details/107935741