I need to integrate protobuf 3 into my app. Since it's multiplatform and multiarchitecture, I cannot simply install protobuf into my system and use the cmake include function like this:
INCLUDE(FindProtobuf)
FIND_PACKAGE(Protobuf REQUIRED)
because it'll only work for x86_64 (the architecture into which I'm installing it)
My idea was to call the protobuf's Makefile through my CMakeLists.txt but it's not that simple, because the project has a configure.
I tried to find protobuf cmake integrations on github but they're all for protobuf2.
What can I do in this situation?
UPDATE:
I added, in my project,
add_subdirectory(${DEPENDENCIES}/protobuf/cmake _protobuf)
Because I found CMakeLists.txt in protobuf/cmake
: https://github.com/protocolbuffers/protobuf/tree/master/cmake
However I stil cannot call
PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER message.proto)
because that's defined in https://github.com/protocolbuffers/protobuf/blob/d9ccd0c0e6bbda9bf4476088eeb46b02d7dcd327/cmake/protobuf-module.cmake.in
I tried then generating and including it:
configure_file(${DEPENDENCIES}/protobuf/cmake/protobuf-module.cmake.in
${CMAKE_CURRENT_SOURCE_DIR}/protobuf-module.cmake @ONLY)
include(protobuf-module.cmake)
but then I get errors in protobuf-module.cmake
like
-- Could NOT find Protobuf (missing: Protobuf_PROTOC_EXECUTABLE Protobuf_LIBRARIES) (found version "")
Unknown CMake command "protobuf_generate".
There are two ways you could solve this. Both require protoc to be installed on the host system.
The first and probably recommended way would be to use add_custom_command()
instead of protobuf_generate_cpp()
# Find the protoc executable installed on the host system
find_program(PROTOBUF_PROTOC protoc REQUIRED)
# set the arguments for the protobuf compiler
set (protoc_args
"--cpp_out=${output_folder}"
"-I"
"${source_folder}"
"${CMAKE_CURRENT_SOURCE_DIR}/helloWorld.proto"
)
set(output
"${output_folder}/helloWorld.pb.h"
"${output_folder}/helloWorld.pb.cc"
)
# add custom command to generate the protobuf sources
add_custom_command(
OUTPUT ${output}
COMMAND ${PROTOBUF_PROTOC}
ARGS ${protoc_args}
DEPENDS ${source_folder}/helloWorld.proto
COMMENT "Running C++ protocol buffer compiler on helloWorld.proto"
VERBATIM
)
set_source_files_properties(${output} PROPERTIES GENERATED TRUE)
#
# Add the output files to your target as you would when using protobuf_generate_cpp()
The second option is to overwrite the location of the protobuf::protoc
target that is created by find_package(protobuf)
and used by protobuf_generate()
. This will allow you to use protobuf_generate_cpp()
when cross compiling.
# Find cross compiled protobuf package installed on your cross-compile toolchain path
find_package(Protobuf CONFIG REQUIRED)
if(CMAKE_CROSSCOMPILING)
# Change protobuf::protoc to reference the protoc executable found on the host system
find_program(_PROTOBUF_PROTOC protoc)
get_target_property(protoc_config protobuf::protoc IMPORTED_CONFIGURATIONS)
set_target_properties(protobuf::protoc PROPERTIES IMPORTED_LOCATION_${protoc_config} ${_PROTOBUF_PROTOC})
get_target_property(new_location protobuf::protoc IMPORTED_LOCATION_${protoc_config})
message(STATUS "Using protoc compiler: ${new_location}")
endif()