CMake and FindProtobuf

柔情痞子 提交于 2019-11-29 23:16:10

I think FindProtobuf isn't really meant to be used this way. From its docs:

NOTE: The PROTOBUF_GENERATE_CPP macro & add_executable() or add_library() calls only work properly within the same directory.

You're trying to use the PROTOBUF_GENERATE_CPP macro in a subdirectory, and although the CMake docs don't really make it clear, a subdirectory introduces a new scope for variables. This means that any variables set or modified in the subdir scope don't affect similarly-named variables in the parent scope. Hence the reason for PROTO_SRC being available in your protofiles dir, but not in the parent.

The way to pass variables up a scope is to use set(... PARENT_SCOPE), so in protofiles/CMakeLists.txt you could do:

PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER test.proto)

set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE)
set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARIES} PARENT_SCOPE)
set(PROTO_SRC ${PROTO_SRC} PARENT_SCOPE)
set(PROTO_HEADER ${PROTO_HEADER} PARENT_SCOPE)

However, this still doesn't get us all the way!

CMake doesn't actually invoke the protoc compiler to generate the .pb.h and .pb.cc files - it uses add_custom_command to do this. The custom command specifies the .pb.h and .pb.cc files as outputs, and the custom command is only invoked (i.e. protoc executed) if a subsequent target which depends on these files is built.

So, at configure time (when CMake executes) these files don't exist. This is a problem if you try to add them as sources to an add_library or add_executable command - CMake needs to be told that these files don't exist when it runs, but that they will exist at build time.

The way to do that is to set the GENERATED property to TRUE for these files. The PROTOBUF_GENERATE_CPP macro does that automatically, but as with the variables, the property isn't populated up into the parent scope. So in your top-level CMakeLists.txt, you also need to add:

set_source_files_properties(${PROTO_SRC} ${PROTO_HEADER} PROPERTIES
                            GENERATED TRUE)

As you can see, using PROTOBUF_GENERATE_CPP in a different dir to the corresponding add_library/add_executable commands is a bit fragile. If you can avoid doing it, you probably should.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!