From 1dc1d000a0e8bc024ec9769d13101b36e13dbcfa Mon Sep 17 00:00:00 2001 From: Xiong Nandi Date: Wed, 11 Sep 2024 19:55:20 +0800 Subject: FindProtobuf: Fix IMPORT_DIRS handling and relative directory generation Append ${CMAKE_CURRENT_SOURCE_DIR} to `_protobuf_include_path` last, since protoc will search the path in order. Besides, we have to figure out the output directory by iterating through the include paths and checking for valid relative paths. --- Modules/FindProtobuf.cmake | 20 ++++++++++++++--- Tests/FindProtobuf/Test/CMakeLists.txt | 25 ++++++++++++++++++++-- Tests/FindProtobuf/Test/main-generate-grpc.cxx | 2 +- Tests/FindProtobuf/Test/msgs/example_service.proto | 8 ------- .../Test/msgs/grpc/example_service.proto | 8 +++++++ 5 files changed, 49 insertions(+), 14 deletions(-) delete mode 100644 Tests/FindProtobuf/Test/msgs/example_service.proto create mode 100644 Tests/FindProtobuf/Test/msgs/grpc/example_service.proto diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index 8ad3270..bdad4de 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -302,8 +302,6 @@ function(protobuf_generate) list(APPEND _protobuf_include_path -I ${_abs_dir}) endif() endforeach() - else() - set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) endif() foreach(DIR ${protobuf_generate_IMPORT_DIRS}) @@ -314,6 +312,10 @@ function(protobuf_generate) endif() endforeach() + if(NOT protobuf_generate_APPEND_PATH) + list(APPEND _protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + set(_generated_srcs_all) foreach(_proto ${protobuf_generate_PROTOS}) get_filename_component(_abs_file ${_proto} ABSOLUTE) @@ -323,7 +325,19 @@ function(protobuf_generate) set(_possible_rel_dir) if (NOT protobuf_generate_APPEND_PATH) - set(_possible_rel_dir ${_rel_dir}/) + foreach(DIR ${_protobuf_include_path}) + if(NOT DIR STREQUAL "-I") + file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir}) + if(_rel_dir STREQUAL _abs_dir) + continue() + endif() + string(FIND "${_rel_dir}" "../" _is_in_parent_folder) + if (NOT ${_is_in_parent_folder} EQUAL 0) + break() + endif() + endif() + endforeach() + set(_possible_rel_dir ${_rel_dir}/) endif() set(_generated_srcs) diff --git a/Tests/FindProtobuf/Test/CMakeLists.txt b/Tests/FindProtobuf/Test/CMakeLists.txt index 84041ea..cd19384 100644 --- a/Tests/FindProtobuf/Test/CMakeLists.txt +++ b/Tests/FindProtobuf/Test/CMakeLists.txt @@ -55,8 +55,9 @@ add_test(NAME test_desc COMMAND test_desc ${DESC_PROTO_DESC}) if(CMake_TEST_FindProtobuf_gRPC) find_program(gRPC_CPP_PLUGIN grpc_cpp_plugin) - add_library(msgs_grpc msgs/example_service.proto) - target_include_directories(msgs_grpc PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + add_library(msgs_grpc msgs/grpc/example_service.proto) + # NOTE: by default generated files will be placed under ${CMAKE_CURRENT_BINARY_DIR}/msgs/grpc/ + target_include_directories(msgs_grpc PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/msgs/grpc/) target_link_libraries(msgs_grpc PUBLIC ${Protobuf_LIBRARIES}) protobuf_generate(TARGET msgs_grpc LANGUAGE cpp) protobuf_generate(TARGET msgs_grpc LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${gRPC_CPP_PLUGIN}") @@ -64,4 +65,24 @@ if(CMake_TEST_FindProtobuf_gRPC) add_executable(test_generate_grpc main-generate-grpc.cxx) target_link_libraries(test_generate_grpc PRIVATE msgs_grpc) add_test(NAME test_generate_grpc COMMAND test_generate_grpc) + + add_library(msgs_grpc_IMPORT_DIRS msgs/grpc/example_service.proto) + # NOTE: with IMPORT_DIRS msgs/, generated files will be placed under ${CMAKE_CURRENT_BINARY_DIR}/grpc/ + target_include_directories(msgs_grpc_IMPORT_DIRS PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/grpc/) + target_link_libraries(msgs_grpc_IMPORT_DIRS PUBLIC ${Protobuf_LIBRARIES}) + protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE cpp IMPORT_DIRS msgs/) + protobuf_generate(TARGET msgs_grpc_IMPORT_DIRS LANGUAGE grpc IMPORT_DIRS msgs/ GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${gRPC_CPP_PLUGIN}") + add_executable(test_generate_grpc_IMPORT_DIRS main-generate-grpc.cxx) + target_link_libraries(test_generate_grpc_IMPORT_DIRS PRIVATE msgs_grpc_IMPORT_DIRS) + add_test(NAME test_generate_grpc_IMPORT_DIRS COMMAND test_generate_grpc_IMPORT_DIRS) + + add_library(msgs_grpc_APPEND_PATH msgs/grpc/example_service.proto) + # NOTE: with APPEND_PATH, generated files will be placed under ${CMAKE_CURRENT_BINARY_DIR}/ + target_include_directories(msgs_grpc_APPEND_PATH PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + target_link_libraries(msgs_grpc_APPEND_PATH PUBLIC ${Protobuf_LIBRARIES}) + protobuf_generate(TARGET msgs_grpc_APPEND_PATH LANGUAGE cpp APPEND_PATH) + protobuf_generate(TARGET msgs_grpc_APPEND_PATH LANGUAGE grpc APPEND_PATH GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${gRPC_CPP_PLUGIN}") + add_executable(test_generate_grpc_APPEND_PATH main-generate-grpc.cxx) + target_link_libraries(test_generate_grpc_APPEND_PATH PRIVATE msgs_grpc_APPEND_PATH) + add_test(NAME test_generate_grpc_APPEND_PATH COMMAND test_generate_grpc_APPEND_PATH) endif() diff --git a/Tests/FindProtobuf/Test/main-generate-grpc.cxx b/Tests/FindProtobuf/Test/main-generate-grpc.cxx index 070c6b4..3251f6a 100644 --- a/Tests/FindProtobuf/Test/main-generate-grpc.cxx +++ b/Tests/FindProtobuf/Test/main-generate-grpc.cxx @@ -1,4 +1,4 @@ -#include +#include int main() { diff --git a/Tests/FindProtobuf/Test/msgs/example_service.proto b/Tests/FindProtobuf/Test/msgs/example_service.proto deleted file mode 100644 index f35eeb5..0000000 --- a/Tests/FindProtobuf/Test/msgs/example_service.proto +++ /dev/null @@ -1,8 +0,0 @@ -syntax = "proto3"; -package example.msgs; - -import "google/protobuf/empty.proto"; - -service ExampleService { - rpc nothing(google.protobuf.Empty) returns (google.protobuf.Empty) {} -} diff --git a/Tests/FindProtobuf/Test/msgs/grpc/example_service.proto b/Tests/FindProtobuf/Test/msgs/grpc/example_service.proto new file mode 100644 index 0000000..f35eeb5 --- /dev/null +++ b/Tests/FindProtobuf/Test/msgs/grpc/example_service.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package example.msgs; + +import "google/protobuf/empty.proto"; + +service ExampleService { + rpc nothing(google.protobuf.Empty) returns (google.protobuf.Empty) {} +} -- cgit v0.12