交叉编译 protobuf2.4 库 实现在arm平台上使用


本人菜鸟一只,如写的有误的地方请各位大神多多指正,谢谢

操作系统:ubuntu 12
protobuf版本:2.4
准备条件:需要安装arm-linux-gcc arm-linux-g++ protobuf2.4安装包

本想使用protobuf3.0版本实现交叉编译,但是经过多次进行尝试还是失败了,在执行make命令时,出现了以下错误,Google等均无结果,本身对protobuf不是特别熟悉,
./google/protobuf/metadata.h: In constructor 'google::protobuf::internal::InternalMetadataWithArena::InternalMetadataWithArena(google::protobuf::Arena*)':
./google/protobuf/metadata.h:176: error: class 'google::protobuf::internal::InternalMetadataWithArena' does not have any field named 'InternalMetadataWithArenaBase'

./google/protobuf/metadata.h: In constructor 'google::protobuf::internal::InternalMetadataWithArenaLite::InternalMetadataWithArenaLite(google::protobuf::Arena*)':
./google/protobuf/metadata.h:206: error: class 'google::protobuf::internal::InternalMetadataWithArenaLite' does not have any field named 'InternalMetadataWithArenaBase'

所以才采用了低版本的protobuf进行尝试,现将操作流程进行总结:
1、进行protobuf在ubuntu平台上的安装:
首先需要安装
  • autoconf
  • automake
  • libtool
  • curl (used to download gmock)
  • make
  • g++
  • unzip
等工具,执行命令: $ sudo apt-get install autoconf automake libtool curl make g++ unzip

然后将protobuf2.4安装包拷贝到自定义的目录下,进行解压,

进入到安装包中,执行 sudo ./autogen.sh 文件产生配置脚本configure,

产生configure文件成功后,执行 sudo ./configure --prefix=/usr , “--prefix=/usr”是配置安装目录,我是安装在/usr目录下,这样可以不用配置PATH环境变量,如不使用“--prefix”,则默认安装在/usr/local目录下,这里需要进行环境变量的配置。

成功执行configure后,会产生Makefile文件,然后执行 sudo make 命令,编译protobuf源码,执行完后就产生了protoc可执行文件以及需要的链接库文件,都放置在src/.libs目录下。

执行 sudo make check 命令,具体有啥用不是很清楚,猜测应该是检测编译后的文件是否正确,

执行成功后再执行 sudo make install 命令,将可执行文件protoc以及链接库移到./configure设定的安装目录下,

执行成功后,执行 protoc --version 命令,如出现libprotoc 2.4.1 则表示ubuntu平台下的protobuf安装成功。

ubuntu平台下的protobuf安装成功后,就进行protobuf的交叉编译。

2.实现protobuf的交叉编译,
实现protobuf的交叉编译,是想让在arm平台上运行protobuf。
首先是执行 make distclean 命令,将编译后的文件以及配置全部清除,

清除完成后,执行 ./configure --build=i686-pc-linux --host=arm-linux CC=arm-linux-gcc CXX=arm-linux-g++ --with-protoc=protoc --prefix=/opt/FriendlyARM/toolschain/4.4.3 命令;
--build表示编译的平台,i686表示64位x86,pc-linux表示系统为Linux系统,
--host表示所编译的库所运行的平台,这里是arm-linux平台,
CC:是指生成Makefile时,CC=arm-linux-gcc,CXX是指Makefile中的CXX为arm-linux-g++,编译protobuf的时候需要用到这两个编译器,
--with-protoc=protoc,进行交叉编译时必须使用此项,why?
--prefix:指定安装目录,这个目录需与ubuntu安装的目标不一致,否则将会把ubuntu下的protobuf库以及可执行文件protoc覆盖掉,所以这里我将此安装目录设置在了arm-linux-gcc的安装目录下,


执行configure命令成功后,再执行 sudo make 命令,进行编译,如提示arm-linux-gcc或arm-linux-g++不存在则,进入到root权限进行此命令的操作,
编译成功后,则会在src/.libs中产生可执行文件protoc和链接库,这些库以及protoc都是arm平台上的。

执行命令 sudo make check 命令,这条命令执行的结果时会产生6个错误,暂时不去理会,

执行完成后,执行命令 sudo make install ,执行成功,则arm平台的protobuf就成功安装在了设定的目录下了,

如要在ubuntu下进行protobuf的应用程序进行交叉编译,则需要将arm平台protobuf安装目录下的lib中的pkgconfig文件夹的protobuf.pc等内容拷贝到/usr/lib/pkgconfig目录下,这样就会将/usr/lib/pkgconfig中原有的protobuf.pc等文件覆盖掉。
protobuf.pc文件定义了protobuf的库的路径等内容,使用pkg-config命令时会查看该文件,找到链接库的位置。
但是当需要编译ubuntu平台下的Protobuf应用程序时,需要将ubuntu平台下的链接库路径文件protobuf.pc等文件拷贝到/usr/lib/pkgconfig文件夹中。


3、操作例程
这里以一个简单的例子来实现ubuntu平台下的操作以及arm平台下的操作
首先编写msg.proto文件:
  1. package lm;   
  2. message helloworld   
  3. {   
  4.     required int32     id = 1;  // ID     
  5.     required string    str = 2;  // str    
  6.     optional int32     opt = 3;  //optional field   
7.}

然后编写应用文件  read.cc
  1. #include "msg.pb.h"  
  2. #include   
  3. #include   
  4. using namespace std;  
  5.   
  6. void ListMsg(const lm::helloworld & msg) {    
  7.     cout << msg.id() << endl;   
  8.     cout << msg.str() << endl;   
  9. }   
  10.   
  11. int main(int argc, char* argv[]) {   
  12.   
  13.     lm::helloworld msg1;   
  14.   
  15.     {   
  16.         fstream input("./log", ios::in | ios::binary);   
  17.         if (!msg1.ParseFromIstream(&input)) {   
  18.             cerr << "Failed to parse address book." << endl;   
  19.             return -1;   
  20.         }         
  21.     }   
  22.   
  23.     ListMsg(msg1);   
  24. }  

将msg.proto消息文件映射为cpp文件,执行命令

protoc -I=. --cpp_out=. msg.proto
可以看到生成了
msg.pb.h 和msg.pb.cc

如在ubuntu平台下编译read.cc:
g++  msg.pb.cc reader.cc -o reader  `pkg-config --cflags --libs protobuf` -lpthread
执行./reader 输出 :
101
hello

如进行交叉编译read.cc
arm-linux-g++  msg.pb.cc reader.cc -o reader  `pkg-config --cflags --libs protobuf` -lpthread
在开发板上执行./reader
输出 :
101
hello

 `pkg-config --cflags --libs protobuf`:表示使用pkg-config命令对protobuf的库进行链接。




protobuf在arm平台上的实现就如上所述,暂时不清楚protobuf3.0为何不能编译通过,还需要去找找原因。
这里实现对应用程序的ubuntu平台编译和arm的交叉编译的方法是通过调换两平台的库链接路径文件protobuf.pc、protobuf-lite.pc来实现的,这种方式还不是很方便还需要考虑有没有更好的方法


实现protobuf的交叉编译参考了一下博文,在此感谢
http://www.xuebuyuan.com/626532.html

http://blog.csdn.net/nicebooks/article/details/17962335

http://blog.csdn.net/yuezhiren/article/details/8094755

http://blog.csdn.net/realxie/article/details/7456013






你可能感兴趣的:(交叉编译 protobuf2.4 库 实现在arm平台上使用)