Using protobuf in CMake as ExternalProject

Viewed 2370

Originally I had a copy of protobuf in VCS with which I completely disagree. I would like to use protobuf as an external dependency to my project.

Only libprotobuf.cmake and libprotobuf-lite.cmake are required for the library. These files can be included in a custom CMakeLists.txt like this:

cmake_minimum_required(VERSION 2.8.12)

project(protobuf C CXX)
# set protobuf_source_dir
# set protobuf_SHARED_OR_STATIC to "SHARED" or "STATIC"
include_directories(${protobuf_source_dir}/src)

include(${protobuf_source_dir}/cmake/libprotobuf-lite.cmake)
include(${protobuf_source_dir}/cmake/libprotobuf.cmake)

I've heard about CMake's ExternalProject, but CMake complains that it can't find any CMakeLists.txt in that project.

1 Answers

CMake's ExternalProject assumes that a CMakeLists.txt exists in the root directory. However, protobuf as of version 3.4 has some examples and a CMakeLists.txt in folder cmake.

An example usage without modifying the external library:

set(PROTOBUF_TAR_GZ https://github.com/google/protobuf/archive/v3.4.0.tar.gz)

ExternalProject_Add(
  protobuf-external
  PREFIX protobuf
  URL ${PROTOBUF_TAR_GZ}
  BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf
  CMAKE_CACHE_ARGS
    "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
    "-Dprotobuf_BUILD_TESTS:BOOL=OFF"
    "-Dprotobuf_BUILD_EXAMPLES:BOOL=OFF"
    "-Dprotobuf_WITH_ZLIB:BOOL=OFF"
    "-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}"
    # other project specific parameters
  SOURCE_SUBDIR cmake
  BUILD_ALWAYS 1
  STEP_TARGETS build
  INSTALL_COMMAND ""
)

EXternalProject_Get_Property(protobuf-external source_dir)
include_directories(${source_dir}/src)
link_directories(${CMAKE_CURRENT_BINARY_DIR}/protobuf)

The important part is to set SOURCE_SUBDIR to folder cmake.

Anyway I made the following assumptions (reflected in CMAKE_CACHE_ARGS), but they can be changed and currently perceived just as an example configuration:

  • Setting build type according to the project. Debug may be useful when inspecting inherited messages. I'd prefer Release for external libraries.
  • I don't want to test protobuf.
  • I don't need examples and compressed messages.
  • Optionally allow setting the compiler from the parent project if cross-compiling.
Related