cmake: correct way to generate from multiple proto files in different directories with import statements?

Viewed 294

CMakeLists.txt:

find_package(Protobuf REQUIRED)

add_library(mylib STATIC "")

set(Protobuf_IMPORT_DIRS
    ${CMAKE_CURRENT_LIST_DIR}
)
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS
    ${CMAKE_CURRENT_LIST_DIR}/A/a1.proto
    ${CMAKE_CURRENT_LIST_DIR}/A/a2.proto
    ${CMAKE_CURRENT_LIST_DIR}/B/b.proto
    ${CMAKE_CURRENT_LIST_DIR}/B/C/bc.proto
)

target_include_directories(mylib
    PUBLIC
        ${Protobuf_INCLUDE_DIRS}
        ${CMAKE_CURRENT_BINARY_DIR} # where the generated files go
)

target_sources(mylib
    PRIVATE
        ${PROTO_SRCS}
        ${PROTO_HDRS}
)

a1.proto:

syntax = "proto3";
package A;
...

a2.proto:

syntax = "proto3";
package A;
import "A/a1.proto";
...

b.proto:

syntax = "proto3";
package B;
import "A/a1.proto";
...

bc.proto:

syntax = "proto3";
package B.C;
import "B/b.proto";
...

Strangely, the generated source files for a1.proto, a2.proto, and b.proto all end up in the same directory (??), ${CMAKE_CURRENT_BINARY_DIR}, while the generated source files for bc.proto end up under ${CMAKE_CURRENT_BINARY_DIR}/C. I would expect the same directory structure to be preserved.

Furthermore, the resulting project files (msbuild in my case) assume that all files are located under the same directory, so I get a "Could not find file" error when opening bc.pp.cc or bc.pp.h.

Lastly, the generated files have #include directives that refer to headers corresponding to the original directory structure, e.g., #include "A/a1.pb.h", which I think would work had the original directory structure been preserved for the generated files.

I tried creating separate cmake targets for each individual proto directory, calling protobuf_generate_cpp() in each, but that was problematic as well.

What's the correct magic to do what my CMakeLists.txt is trying to do?

0 Answers
Related