本人菜鸟一只,如写的有误的地方请各位大神多多指正,谢谢
操作系统: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文件:
- package lm;
- message helloworld
- {
- required int32 id = 1; // ID
- required string str = 2; // str
- optional int32 opt = 3; //optional field
7.}
然后编写应用文件 read.cc
- #include "msg.pb.h"
- #include
- #include
- using namespace std;
-
- void ListMsg(const lm::helloworld & msg) {
- cout << msg.id() << endl;
- cout << msg.str() << endl;
- }
-
- int main(int argc, char* argv[]) {
-
- lm::helloworld msg1;
-
- {
- fstream input("./log", ios::in | ios::binary);
- if (!msg1.ParseFromIstream(&input)) {
- cerr << "Failed to parse address book." << endl;
- return -1;
- }
- }
-
- ListMsg(msg1);
- }
将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