4

I want to use protobuf in my C++ library. All dependencies so far are included using cmake's FetchContent module. I want to do the same with protobuf. However, I run into the following problem: Unknown CMake command "protobuf_generate_cpp". Any hints on how to solve this?

Excerpt of my CMakeLists.txt:

FetchContent_Declare(fmt
        GIT_REPOSITORY https://github.com/fmtlib/fmt.git
        GIT_TAG 9.0.0)

FetchContent_Declare(protobuf
        GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
        GIT_TAG v21.4)

FetchContent_MakeAvailable(fmt protobuf)

include_directories(${Protobuf_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS message.proto)
bit4fox
  • 2,021
  • 2
  • 13
  • 8

2 Answers2

1

This works for me:

FetchContent_Declare(protobuf
  GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
  GIT_TAG        v21.4
  SOURCE_SUBDIR  cmake
  FIND_PACKAGE_ARGS NAMES protobuf
)
FetchContent_MakeAvailable(protobuf)

On the consumer end do this

include(FindProtobuf)
find_package(protobuf CONFIG REQUIRED)

Note: This has only been tested on CMake v3.25

yashC
  • 887
  • 7
  • 20
  • Does it build protobuf, or you supposed to call `make protoc` (or whatever build system you use)? – erzya Dec 31 '22 at 16:51
  • 1
    @erzya It builds the protobuf. – yashC Jan 01 '23 at 10:32
  • are you sure you don't have separate `execute_process` command in your cmake for building protobuf compiler? – erzya Jan 05 '23 at 19:06
  • 1
    yes. i am sure. I think the idea is that we clone the proto and then specify the `SOURCE_SUBDIR` i.e. the root cmake of that project. And that project is supposed to export all the required definations. – yashC Jan 09 '23 at 11:05
  • 1
    AFIU `SOURCE_SUBDIR` is now deprecated as `protobuf` now puts `CMakeLists.txt` into repository root. I am really interested how it is done as the only example I found online that fetches and builds `protobuf` is [https://github.com/OpenMined/TenSEAL/blob/main/cmake/protobuf.cmake] and they use explicit `execute_process` – erzya Jan 10 '23 at 01:23
0

protobuf_generate_cpp is from FindProtobuf. It doesn't seem to work with a protoc that was build in the project with FetchContent. You'll have to call the protoc binary explicitly.

set(GENERATED_CODE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
set(PROTO_SRCS ${GENERATED_CODE_DIR}/message.pb.cc)
set(PROTO_HDRS ${GENERATED_CODE_DIR}/message.pb.h)
set(PROTOC ${protobuf_BINARY_DIR}/protoc)
set(PROTO_DIR ${CMAKE_CURRENT_SOURCE_DIR})

add_custom_command(
    OUTPUT ${PROTO_SRCS} ${PROTO_HDRS}
    COMMAND ${PROTOC} --proto_path ${PROTO_DIR} message.proto --cpp_out ${GENERATED_CODE_DIR}
    DEPENDS ${PROTOC} ${PROTO_DIR}/message.proto
    )