0

I am not familiar with cmake and protobuf. I want to write a CMakeLists.txt to help me generate all protobuf file in a specified directory into another specified directory.

The following is the CMakeLists.txt I writen, but it cannot generate any *.pb.h or *.pb.cc now. Anyone can tell me what's wrong with my CMakeLists.txt? Thanks.

The cmake vesion I used is 3.12 and protoc version is 3.12.

file(GLOB_RECURSE children LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/protos/*.proto")
SET(PROTO_META_BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}/protos_cpp_hpp)
FOREACH(FIL ${children})
  GET_FILENAME_COMPONENT(ABS_FIL ${FIL} ABSOLUTE)
  GET_FILENAME_COMPONENT(FIL_WE ${FIL} NAME_WE)

  LIST(APPEND PROTO_SRCS "${CMAKE_CURRENT_BINARY_DIR}/protos_cpp_hpp/${FIL_WE}.pb.cc")
  LIST(APPEND PROTO_HDRS "${CMAKE_CURRENT_BINARY_DIR}/protos_cpp_hpp/${FIL_WE}.pb.h")

#   EXECUTE_PROCESS(
#       COMMAND PROTOBUF_GENERATE_CPP --cpp_out=${PROTO_META_BASE_DIR} ${FIL}
#       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/protos
#   )

  PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HDR ${CMAKE_SOURCE_DIR}/protos/${FIL})
ENDFOREACH()
JYP2011
  • 23
  • 5

1 Answers1

2

According to the documentation, the function PROTOBUF_GENERATE_CPP creates a custom command which OUTPUT lists resulted files. So, nothing will be generated unless there is a target which consumes these files as a dependency.

The most direct way is consuming the files as sources for add_executable:

add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})

This way is described in the documentation.

If, for some reason, you don't want create anything from the resulted files, then you may create a custom target which consumes these files:

add_custom_target(my_command ALL DEPENDS ${PROTO_SRCS} ${PROTO_HDRS})
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • If I just want to generate protobuf file's *.cc or *.h, but not consuming the generated file, does that means that the protobuf_generate_cpp would not generate the *.cc or *.h for me? – JYP2011 Jul 04 '20 at 08:39
  • 1
    You may create a **custom target** which consumes these files: `add_custom_target(my_command ALL DEPENDS ${PROTO_SRCS} ${PROTO_HDRS})`. I have updated the answer for that case. – Tsyvarev Jul 04 '20 at 08:41
  • I add " add_custom_target(my_command ALL DEPENDS ${PROTO_SRCS} ${PROTO_HDRS})" in the last of CMakeLists.txt, and build it, but It reported error:-( – JYP2011 Jul 04 '20 at 08:47
  • What error it generates? In my answer I assume `PROTO_SRCS` and `PROTO_HDRS` passed to the `PROTOBUF_GENERATE_CPP` function as the first two parameters. Your code seems to pass `PROTO_SRC` and `PROTO_HDRS` instead (without final `S`). – Tsyvarev Jul 04 '20 at 08:55
  • oh, sorry, I miss a ')' in the end of certain function. It does not work for me, I don't found any generated *.pb.h or *.pb.cc in protos_cpp_hpp directory – JYP2011 Jul 04 '20 at 09:10
  • emmm....can you show me a complete add_custom_target example about how to use in my example? Maybe the way I use it is wrong? – JYP2011 Jul 04 '20 at 09:31
  • You have missed the point of first two parameters to `PROTOBUF_GENERATE_CPP` function. They are not **input** lists, using which you may specify the files you want to generate. They are **output only** lists, which contains the files actually generated by the function. It is function who decides where to create the files. Most likely, they are generated somewhere in the build directory. You may print variables (e.g. `message("Files: ${PROTO_SRCS} ${PROTO_HDRS}")`) to see actual paths to the created files. – Tsyvarev Jul 04 '20 at 12:31
  • One question guys, why we add header to `add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})` shouldn't that be `add_executable(bar bar.cc ${PROTO_SRCS})` when we add the `${CMAKE_CURRENT_BINARY_DIR}` to `include_directories()`? @Tsyvarev – Mohammad Rahimi Jun 04 '22 at 10:53
  • 1
    @MohammadRahimi: Adding headers to `add_executable` is optional. See e.g. [that question](https://stackoverflow.com/questions/36174499/why-add-header-files-into-add-library-add-executable-command-in-cmake) and its answer about reasoning to do that. – Tsyvarev Jun 04 '22 at 13:31