Linux环境下Clion整合Protobuf小结

2020-08-25  本文已影响0人  chjxidian

一、安装Protobuf环境

#安装依赖项目
sudo apt-get install autoconf automake libtool curl make g++ unzip
#下载最新源码
git clone https://github.com/google/protobuf.git
#进入目录
cd protobuf
#更新源
git submodule update --init --recursive
#生成依赖项目
./autogen.sh
#配置
./configure
#编译
make
#编译确认
make check
#安装
sudo make install
 # refresh shared library cache(刷新共享库配置)
sudo ldconfig
#查看版本
protoc --version

二、工程整合

1. 新建***.proto文件

proto文件
/*****PbTest.proto******/

syntax = "proto3";   //设定proto版本,不同版本语法不一样

package tutorial;

message Person {
  string name = 1;
  int32 id = 2;   //整型
  string email = 3;

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

  message PhoneNumber {  //定义类,也可以另起到外部message
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;  //关键字repeated代表不定长链表,对标list类
}

message AddressBook {
   Person people = 1;  //类嵌套
}

2. 开始转换

语法: protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/XXXX.proto
案例: protoc --cpp_out=. XXXX.proto

3. 文件加入工程

加入工程目录
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

...

include(FindProtobuf)
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIR})

target_link_libraries(
        ${PROTOBUF_LIBRARY}
)

4. 编译运行

    TuneParamsModel para;
    para.set_cad(5);

    /******************Stream***********************/
    // fstream out("out.txt", ios::out | ios::trunc);
    ofstream out("out.txt", ios::out | ios::trunc);
    para.SerializeToOstream(&out);
    out.close();
    TuneParamsModel ret;
    ifstream src ("out.txt", ios::in);
    ret.ParsePartialFromIstream(&src);
    src.close();
    /*******************Array***********************/
    size_t len =  para.ByteSizeLong();
    char buf[len];
    para.SerializeToArray( buf,len);

    TuneParamsModel ret;
    ifstream src ("out.txt");
    if (! src.is_open())
    { cout << "Error opening file"; exit (1); }
    while (! src.eof() ) {
        src.read (buf, len);
    }
    ret.ParseFromArray(buf, len);

    printf("Value Compare Result: %d", ret.cad() == para.cad());
    /*******************File***********************/
    TuneParamsModel _ret;
    ifstream _src ("protoBufferTest", ios::in);
    _ret.ParsePartialFromIstream(&_src);
    _src.close();

三、常见故障处理

1. 提示如下错误:

CMakeFiles/MedianMachine.dir/frame/MyProto.pb.cc.o: In function InitDefaultsscc_info_MyProto_MyProto_2eproto()': /media/chj/Code/MassHunter/MedianMachine/frame/MyProto.pb.cc:29: undefined reference togoogle::protobuf::internal::VerifyVersion(int, int, char const)'
CMakeFiles/MedianMachine.dir/frame/MyProto.pb.cc.o: In function InitDefaultsscc_info_MyType_MyProto_2eproto()': /media/chj/Code/MassHunter/MedianMachine/frame/MyProto.pb.cc:47: undefined reference togoogle::protobuf::internal::VerifyVersion(int, int, char const
)'
CMakeFiles/MedianMachine.dir/frame/MyProto.pb.cc.o: In function test::MyProto_MessageType_descriptor()': /media/chj/Code/MassHunter/MedianMachine/frame/MyProto.pb.cc:123: undefined reference togoogle::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const, bool)'
CMakeFiles/MedianMachine.dir/frame/MyProto.pb.cc.o: In function test::MyType::_InternalParse(char const*, google::protobuf::internal::ParseContext*)': /media/chj/Code/MassHunter/MedianMachine/frame/MyProto.pb.cc:231: undefined reference togoogle::protobuf::internal::UnknownFieldParse(unsigned long, google::protobuf::UnknownFieldSet
, char const, google::protobuf::internal::ParseContext)'
CMakeFiles/MedianMachine.dir/frame/MyProto.pb.cc.o: In function `test::MyType::_InternalSerialize(unsigned char, google::protobuf::io::EpsCopyOutputStream) const':

...

CMakeFiles/MedianMachine.dir/frame/MyProto.pb.cc.o:(.data.rel.ro._ZTIN4test6MyTypeE[_ZTIN4test6MyTypeE]+0x10): undefined reference to `typeinfo for google::protobuf::Message'
collect2: error: ld returned 1 exit status
CMakeFiles/MedianMachine.dir/build.make:233: recipe for target 'MedianMachine' failed
make[3]: *** [MedianMachine] Error 1
CMakeFiles/Makefile2:75: recipe for target 'CMakeFiles/MedianMachine.dir/all' failed
make[2]: *** [CMakeFiles/MedianMachine.dir/all] Error 2
CMakeFiles/Makefile2:82: recipe for target 'CMakeFiles/MedianMachine.dir/rule' failed
make[1]: *** [CMakeFiles/MedianMachine.dir/rule] Error 2
Makefile:118: recipe for target 'MedianMachine' failed
make: *** [MedianMachine] Error 2

include(FindProtobuf)
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIR})

...

target_link_libraries(

...

    ${PROTOBUF_LIBRARY}
)

2. 定制化编译与安装

./configure --prefix=/usr/local/protobuf
make
make check
make install
####### add protobuf lib path ########
#(动态库搜索路径) 程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib/
#(静态库搜索路径) 程序编译期间查找动态链接库时指定查找共享库的路径
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib/
#执行程序搜索路径
export PATH=$PATH:/usr/local/protobuf/bin/
#c程序头文件搜索路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/protobuf/include/
#c++程序头文件搜索路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/protobuf/include/
#pkg-config 路径
export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/
######################################

3. 版本升级

sudo apt-get --purge remove libprotobuf-dev
sudo apt-get --purge remove protobuf-compiler
sudo apt-get --fix-broken install

4.交叉编译

./configure --host=<HOST_NAME> CC=<YOUR_COMPILER_PATH>/<COMPILER_GCC> CXX=<YOUR_COMPILER_PATH>/<COMPILER_G++> --disable-protoc --prefix=<TARGET_INSTALL_PATH>

# aarch64-linux-gnu平台
./configure --host=aarch64-linux-gnu CC=/usr/local/gcc-arm-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc CXX=/usr/local/gcc-arm-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ --disable-protoc --prefix=/usr/local/protobuf-aarch64-linux-gnu
# arm-none-linux-gnueabihf 平台
./configure --host=arm-none-linux-gnueabihf CC=/usr/local/gcc-arm-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc CXX=/usr/local/gcc-arm-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-g++ --disable-protoc --prefix=/usr/local/protobuf-arm-none-linux-gnueabihf
# 32位arm-linux-gnueabi平台
./configure --host=arm-linux-gnueabi CC=/usr/local/gcc-linaro-arm-linux-gnueabihf-4.7/bin/arm-linux-gnueabihf-gcc CXX=/usr/local/gcc-linaro-arm-linux-gnueabihf-4.7/bin/arm-linux-gnueabihf-g++ --disable-protoc --prefix=/usr/local/protobuf-arm-linux-gnueabi
#  host: arm-none-linux-gnueabihf 
# protobuf 路径配置
SET(PROTOBUF_FOUND                /usr/local/protobuf-arm-none-linux-gnueabihf/)
# protobuf 库路径配置
SET(PROTOBUF_LIBRARY              /usr/local/protobuf-arm-none-linux-gnueabihf/lib/libprotobuf.so)
# protobuf 头文件配置
SET(PROTOBUF_INCLUDE_DIR          /usr/local/protobuf-arm-none-linux-gnueabihf/include/)
# protobuf 执行文件配置
SET(PROTOBUF_PROTOC_EXECUTABLE    /usr/local/protobuf-arm-none-linux-gnueabihf/bin/protoc)

# host: aarch64-linux-gnu
SET(PROTOBUF_FOUND                /usr/local/protobuf-aarch64-linux-gnu/)
SET(PROTOBUF_LIBRARY              /usr/local/protobuf-aarch64-linux-gnu/lib/libprotobuf.so)
SET(PROTOBUF_INCLUDE_DIR          /usr/local/protobuf-aarch64-linux-gnu/include/)
SET(PROTOBUF_PROTOC_EXECUTABLE    /usr/local/protobuf-aarch64-linux-gnu/bin/protoc)

5. protobuf 系统帮助

cmake --help-module FindProtobuf

Locate and configure the Google Protocol Buffers library.

The following variables can be set and are optional:

PROTOBUF_SRC_ROOT_FOLDER
When compiling with MSVC, if this cache variable is set
the protobuf-default VS project build locations
(vsprojects/Debug and vsprojects/Release
or vsprojects/x64/Debug and vsprojects/x64/Release)
will be searched for libraries and binaries.
PROTOBUF_IMPORT_DIRS
List of additional directories to be searched for
imported .proto files.

Defines the following variables:

PROTOBUF_FOUND
Found the Google Protocol Buffers library
(libprotobuf & header files)
PROTOBUF_INCLUDE_DIRS
Include directories for Google Protocol Buffers
PROTOBUF_LIBRARIES
The protobuf libraries
PROTOBUF_PROTOC_LIBRARIES
The protoc libraries
PROTOBUF_LITE_LIBRARIES
The protobuf-lite libraries

The following cache variables are also available to set or use:

PROTOBUF_LIBRARY
The protobuf library
PROTOBUF_PROTOC_LIBRARY
The protoc library
PROTOBUF_INCLUDE_DIR
The include directory for protocol buffers
PROTOBUF_PROTOC_EXECUTABLE
The protoc compiler
PROTOBUF_LIBRARY_DEBUG
The protobuf library (debug)
PROTOBUF_PROTOC_LIBRARY_DEBUG
The protoc library (debug)
PROTOBUF_LITE_LIBRARY
The protobuf lite library
PROTOBUF_LITE_LIBRARY_DEBUG
The protobuf lite library (debug)

Example:

find_package(Protobuf REQUIRED)
include_directories({PROTOBUF_INCLUDE_DIRS}) include_directories({CMAKE_CURRENT_BINARY_DIR})
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
protobuf_generate_python(PROTO_PY foo.proto)
add_executable(bar bar.cc {PROTO_SRCS}{PROTO_HDRS})
target_link_libraries(bar ${PROTOBUF_LIBRARIES})

.. note::
The protobuf_generate_cpp and protobuf_generate_python
functions and add_executable() or add_library()
calls only work properly within the same directory.

.. command:: protobuf_generate_cpp

Add custom commands to process .proto files to C++::

protobuf_generate_cpp (<SRCS> <HDRS> [<ARGN>...])

SRCS
Variable to define with autogenerated source files
HDRS
Variable to define with autogenerated header files
ARGN
.proto files

.. command:: protobuf_generate_python

Add custom commands to process .proto files to Python::

protobuf_generate_python (<PY> [<ARGN>...])

PY
Variable to define with autogenerated Python files
ARGN
.proto filess

6. C语言兼容

# 执行指令:
./configure && make && make install
# 或者执行指令:
./autogen.sh && ./configure && make && make install
protoc --c_out=. example.proto

参考文献:


C语言使用Demo
MakeList文件故障处理
文件流处理
纯C语言实现方案
应用案例
交叉编译protobuf
入门手册
类型说明
参考手册
常用序列化函数
C语言使用案例
C语言源码仓库

上一篇下一篇

猜你喜欢

热点阅读