CMake and Protocol Buffers on Windows

Friday, May 25, 2018

Protocol buffers are Google’s language-neutral, platform-neutral approach for serializing structured data.

On linux, you can easily install it using package management. On Windows, you may build it from source and install it. Here is the instructions to install it on Windows.

Suppose it is installed under the install location, such as d:\pgk\protobuf, the directory structure is as follows:

+---bin
+---cmake
+---include
|   \---google
|       \---protobuf
|           +---compiler
|           |   +---cpp
|           |   +---csharp
|           |   +---java
|           |   +---javanano
|           |   +---js
|           |   +---objectivec
|           |   +---php
|           |   +---python
|           |   \---ruby
|           +---io
|           +---stubs
|           \---util
\---lib
    \---pkgconfig 

CMake

CMake is an excellent tool for building, testing and packaging. The following example shows how to use Protocol buffers in your project:

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_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto)
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS DESCRIPTORS PROTO_DESCS foo.proto)
protobuf_generate_python(PROTO_PY foo.proto)
add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
target_link_libraries(bar ${Protobuf_LIBRARIES})

However, the above CMake script will fail due to the error: “protobuf not found”. To let CMake successfully find the installed protobuf package, you can specify the install location as follows:

set(CMAKE_PREFIX_PATH
	"d:/pkg/protobuf"
	"${CMAKE_PREFIX_PATH}"
	)
 
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_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto)
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS DESCRIPTORS PROTO_DESCS foo.proto)
protobuf_generate_python(PROTO_PY foo.proto)
add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
target_link_libraries(bar ${Protobuf_LIBRARIES})