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:
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.
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.cc
and AddressBook.pb.h
.
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 .
Executing main will let you enter information:
./main name.txt
The above is all the process of using protobuf under teminal. After the end, your workspace should be as follows:
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:
Four, use protobuf under VS code
4.1 Install VS code
ubuntu 18.04 enter ubuntu software, enter visual studio code, install:
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 :
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:
The final file directory is as follows:
If you miss this smoothness, you will probably find the following discordant wavy line:
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:
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:
Execute the following command to execute the project
./bazel-bin/main name.txt
Get the following results:
END
by windSeS
2020-8-12