Build protobuf with MSVC on Windows

Recently, I have been using Protobuf in VS, and I will briefly record the process of building Protobuf using MSVC.

The method for compiling protobuf on Windows introduced in this article has several software requirements:

  1. Git
  2. cmake
  3. visual studio

First, pull the protobuf source code:

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

Then pull googletest:

1
2
3
4
5
6
$ git clone git@github.com:google/googletest.git
# Note, after pulling
# 1. Rename the directory googlemock to gmock
# 2. Rename the directory googletest to gtest
# 3. Move gtest into the gmock directory
# 4. Copy the current gmock to protobuf-3.5.x/

Then, change the directory to protobuf-3.5.x/cmake:

1
$ cd protobuf-3.5.x/cmake

Execute the following command, changing "Visual Studio 14 2015" to the version of Visual Studio you are using; you can check this by using the command cmake -G. Note that you need to specify the architecture [arch] information; if you do not specify Win64, it defaults to Win32. The DCMAKE_INSTALL_PREFIX specifies the directory for installing protobuf (copying the compiled files).

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

If there are no errors, execute the following:
protobuf-cmake
At this point, it will generate protobuf.sln and extract_includes.bat and other files under the cmake directory.
First, executing extract_includes.bat will copy the .h and .cpp files needed by protobuf (in the include/google folder) to the cmake directory.
Then use VS to open protobuf.sln, change the red box to Release, right-click ALL_BUILD to compile (generally you only need protobuf and protoc).

Note: If you are using Protobuf in Unreal, the runtime library options need to be changed to /MD (Release) and /MDd (Debug).
protobuf-buildlibprotobuf-setting

protobuf-build
After a successful execution, there will be a generated Release directory in the cmake directory.
build-resault-file
At this point, the compilation work is done.
However, the compiled files are all in the cmake directory, and for convenience, we need to install the compiled files (moving the compiled files to the directory specified earlier with -DCMAKE_INSTALL_PREFIX="~/protobuf").
You just need to execute the build on the INSTALL project in VS:

Then the directory structure of ~/protobuf should be as follows:

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

Then add Protobuf/bin, Protobuf/lib, and Protobuf/include to the system PATH.

Attached is my compiled protobuf_v3.5.1, where the lib/MD and lib/MT are different multithreading runtime libraries, with debug being /MTd and /MDd and release being /MD and /MT.

Then you can write a simple test case:

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;
}

Use protoc to generate .h and .cpp:

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

This will generate zlp.PeopleInfo.pb.cc and zlp.PeopleInfo.pb.h in the current directory of zlp.PeopleInfo.proto.

  1. Then create a new console project in VS and add the two generated files to the project.
  2. In the project settings, add the protobuf header file include directory, Properties > C/C++ > General > Additional Include Directories.
    protobuf-add-include-folder
  3. Modify the project settings under Properties > C/C++ > Code Generation > Runtime Library to be /MT or /MD (Release) or /MD or /MDd (Debug).
    protobuf-setting-libraray-thread-mode
  4. In the project settings, add the protobuf link library directory, Properties > Linker > General > Additional Library Directories, noting to specify the same runtime library mode as selected (/MD//MT), or it will report an error.
    protobuf-add-link-library-folder
  5. In the project settings, add the protobuf link files, we need libprotobuf.lib and libprotoc.lib, under Properties > Linker > Input > Additional Dependencies.
    protobuf-add-link-library-file

Once the settings are complete, here is a simple test code that serializes from protobuf to a file and then deserializes from the file:

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;

}

Note: The code generated by protobuf may have some syntax or performance warnings, and you can disable certain VS warnings according to your needs. The warnings I disabled are as follows (placed at the top of the included header files):

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)

The result of successfully compiling and running is as follows:
protobuf-test-resault

The article is finished. If you have any questions, please comment and communicate.

Scan the QR code on WeChat and follow me.

Title:Build protobuf with MSVC on Windows
Author:LIPENGZHA
Publish Date:2018/02/27 10:01
World Count:3k Words
Link:https://en.imzlp.com/posts/9903/
License: CC BY-NC-SA 4.0
Reprinting of the full article is prohibited.
Your donation will encourage me to keep creating!