Build protobuf with MSVC on Windows

最近有在VS中用到Protobuf,简单记录一下使用MSVC构建Protobuf的流程。

本文介绍的在windows上编译protobuf的方法有几个软件要求:

  1. Git
  2. cmake
  3. visual studio

首先拉取protobuf源码:

1
2
$ git clone -b 3.5.x git@github.com:google/protobuf.git protobuf-3.5.x
cd protobuf-3.5.x

再拉取googletest:

1
2
3
4
5
6
$ git clone git@github.com:google/googletest.git
# 注意,拉取完成后
# 1.将目录googlemock改名为gmock
# 2.将目录googletest改名为gtest
# 3.将gtest移动到gmock目录下
# 4.将此时的gmock复制到protobuf-3.5.x/下

然后目录跳转到protobuf-3.5.x/cmake下:

1
$ cd protobuf-3.5.x/cmake

执行下列命令,"Visual Studio 14 2015"根据实际情况改成你自己的visualstudio版本,具体的可以通过使用命令cmake -G查看,注意要指定架构[arch]信息,不指定Win64则默认为Win32DCMAKE_INSTALL_PREFIX指定的后续protobuf的安装目录(拷贝编译出的文件)。

1
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_INSTALL_PREFIX="~/protobuf"

不出错误的话执行如下:
protobuf-cmake
此时会在cmake下生成protobuf.sln以及extract_includes.bat等文件。
首先,执行extract_includes.bat会把protobuf需要用到的.h.cpp拷贝(include/google文件夹)到camke目录里来。
然后使用VS打开protobuf.sln,红框中改成Release,右键ALL_BUILD点生成(其实一般也就只需要protobufprotoc)。

注意:如果在Unreal中使用Protobuf的话,编译运行库选项需要修改为/MD(Release)和/MDd(Debug)。
protobuf-buildlibprotobuf-setting

protobuf-build
执行成功后,cmake目录下会有=产生一个Release目录。
build-resault-file
此时编译的工作已经搞定了。
但是编译出来的文件都在cmake目录下面,为了方便使用,需要把我们编译出来安装出来(也就只将编译出来的文件放到前面-DCMAKE_INSTALL_PREFIX="~/protobuf"中指定的目录)。
只需要在VS中对INSTALL项目执行生成:

然后此时的~/protobuf的目录结构应如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protobuf/
├─bin
├─cmake
├─include
│ └─google
│ └─protobuf
│ ├─compiler
│ │ ├─cpp
│ │ ├─csharp
│ │ ├─java
│ │ ├─javanano
│ │ ├─js
│ │ ├─objectivec
│ │ ├─php
│ │ ├─python
│ │ └─ruby
│ ├─io
│ ├─stubs
│ └─util
└─lib
libprotobuf-lite.lib
libprotobuf.lib
libprotoc.lib

然后把Protobuf/binProtobuf/lib以及Protobuf/include添加到系统PATH路径即可。

附上我编译好的protobuf_v3.5.1,其中的lib/MDlib/MT是不同的多线程运行时库,其中debug的为/MTd/MDd以及Release的/MD/MT

然后就可以写个简单的测试用例了:

1
2
3
4
5
6
7
8
// zlp.PeopleInfo.proto
syntax="proto2";
package zlp;
message PeopleInfo
{
required int32 year=1;
required string name=2;
}

使用protoc生成.h.cpp

1
$ protoc zlp.PeopleInfo.proto --cpp_out=./

会在当前zlp.PeopleInfo.proto目录下生成zlp.PeopleInfo.pb.cczlp.PeopleInfo.pb.h

  1. 然后使用VS新建一个控制台项目,并将上面生成的两个文件添加到项目中来。
  2. 在项目设置中添加protobuf的头文件包含目录,配置属性 > C/C++ > 常规 > 附加包含目录
    protobuf-add-include-folder
  3. 修改项目设置中的配置属性 > C/C++ > 代码生成 > 运行库/MT/MD(Release)或者/MD/MDd(Debug).
    protobuf-setting-libraray-thread-mode
  4. 在项目设置中添加protobuf链接库目录,配置属性 > 连接器 > 常规 > 附加库目录,注意要指定与你选定的运行库模式一样的(/MD//MT),不然会报错。
    protobuf-add-link-library-folder
  5. 在项目设置中添加protobuf链接文件,我们需要的是libprotobuf.liblibprotoc.lib,在配置属性 > 连接器 > 输入 > 附加依赖项
    protobuf-add-link-library-file

设置完成后,下面是一段简单的测试代码,从protobuf序列化为文件,再从文件中反序列化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#pragma once

#pragma warning(disable:4800)
#pragma warning(disable:4125)
#pragma warning(disable:4668)
#pragma warning(disable:4647)
#pragma warning(disable:4146)
#pragma warning(disable:4800)

#include "zlp.PeopleInfo.pb.h"
#include <iostream>
#include <fstream>

using namespace std;
void printMsg(const zlp::PeopleInfo & msg) {
std::cout << "name: " << msg.name() << endl;
std::cout << "year: " << msg.year() << endl;
}

int main(void)
{
zlp::PeopleInfo Msg_1;
Msg_1.set_year(24);
Msg_1.set_name("zhalipeng");

// Write the new address book back to disk.
fstream writer("./log", std::ios::out | std::ios::trunc | std::ios::binary);

if (!Msg_1.SerializeToOstream(&writer)) {
cerr << "Failed to write msg." << endl;
writer.close();
return -1;
}
else {
std::cout << "Write msg is Success!" << std::endl;
system("pause");
writer.close();
}

fstream input("./log", std::ios::in | std::ios::binary);
zlp::PeopleInfo reader;
if (!reader.ParseFromIstream(&input))
{
cerr << "Read msg Faild!" << endl;
input.close();
return -1;
}else{
printMsg(reader);
system("pause");
}
return 0;

}

注意:protobuf生成的代码可能会有一些语法或性能上的警告,可以根据实际情况关闭VS的某些警告,我使用的禁用的几个警告如下(放置在包含头文件的首部):

1
2
3
4
5
6
#pragma warning(disable:4800)
#pragma warning(disable:4125)
#pragma warning(disable:4668)
#pragma warning(disable:4647)
#pragma warning(disable:4146)
#pragma warning(disable:4800)

编译成功运行的结果如下:
protobuf-test-resault

全文完,若有不足之处请评论指正。

微信扫描二维码,关注我的公众号。

本文标题:Build protobuf with MSVC on Windows
文章作者:查利鹏
发布时间:2018年02月27日 10时01分
本文字数:本文一共有1.5k字
原始链接:https://imzlp.com/posts/9903/
许可协议: CC BY-NC-SA 4.0
文章禁止全文转载,摘要转发请保留原文链接及作者信息,谢谢!
您的捐赠将鼓励我继续创作!