Last active
April 11, 2022 21:47
-
-
Save danem/4c01c91c8728fdc472b40846968e8a89 to your computer and use it in GitHub Desktop.
GRPC Cmake
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# grpc_generate ( | |
# <TARGET|OUTVAR> | |
# <LANGUAGE (cpp|csharp|javascript|objective_c|php|python|ruby)> | |
# <IMPORT_DIRS [args...]> | |
# [PROTOC_OUT_DIR] | |
# <PROTOS [args...]> | |
# ) | |
# | |
function(grpc_generate) | |
include(CMakeParseArguments) | |
set(_options APPEND_PATH) | |
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN) | |
if(COMMAND target_sources) | |
list(APPEND _singleargs TARGET) | |
endif() | |
set(_multiargs PROTOS IMPORT_DIRS PROTOC_OPTIONS) | |
cmake_parse_arguments(grpc_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}") | |
if(NOT grpc_generate_PROTOS AND NOT grpc_generate_TARGET) | |
message(SEND_ERROR "Error: protobuf_generate called without any targets or source files") | |
return() | |
endif() | |
if(NOT grpc_generate_OUT_VAR AND NOT grpc_generate_TARGET) | |
message(SEND_ERROR "Error: protobuf_generate called without a target or output variable") | |
return() | |
endif() | |
if(NOT grpc_generate_LANGUAGE) | |
set(grpc_generate_LANGUAGE cpp) | |
endif() | |
string(TOLOWER ${grpc_generate_LANGUAGE} protobuf_generate_LANGUAGE) | |
if(NOT grpc_generate_PROTOC_OUT_DIR) | |
set(grpc_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) | |
endif() | |
if(grpc_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp) | |
set(_dll_export_decl "dllexport_decl=${grpc_generate_EXPORT_MACRO}:") | |
endif() | |
if(grpc_generate_LANGUAGE STREQUAL cpp) | |
set(grpc_generate_GENERATE_EXTENSIONS .pb.h .pb.cc) | |
set(protobuf_grpc_PLUGIN gRPC::grpc_cpp_plugin) | |
elseif(grpc_generate_LANGUAGE STREQUAL python) | |
set(grpc_generate_GENERATE_EXTENSIONS _pb2.py) | |
set(protobuf_grpc_PLUGIN gRPC::grpc_python_plugin) | |
elseif(grpc_generate_LANGUAGE STREQUAL javascript) | |
set(grpc_generate_GENERATE_EXTENSIONS _pb2.js) | |
set(protobuf_grpc_PLUGIN gRPC::grpc_node_plugin) | |
elseif(grpc_generate_LANGUAGE STREQUAL php) | |
set(grpc_generate_GENERATE_EXTENSIONS _pb2.php) | |
set(protobuf_grpc_PLUGIN gRPC::grpc_php_plugin) | |
elseif(grpc_generate_LANGUAGE STREQUAL ruby) | |
set(grpc_generate_GENERATE_EXTENSIONS _pb2.rb) | |
set(protobuf_grpc_PLUGIN gRPC::grpc_ruby_plugin) | |
elseif(grpc_generate_LANGUAGE STREQUAL csharp) | |
set(grpc_generate_GENERATE_EXTENSIONS _pb2.cs) | |
set(protobuf_grpc_PLUGIN gRPC::grpc_csharp_plugin) | |
elseif(grpc_generate_LANGUAGE STREQUAL objective_c) | |
set(grpc_generate_GENERATE_EXTENSIONS .pb.h .pb.m) | |
set(protobuf_grpc_PLUGIN gRPC::grpc_objective_c_plugin) | |
else() | |
message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}") | |
return() | |
endif() | |
get_target_property(_GRPC_PLUGIN_PATH ${protobuf_grpc_PLUGIN} LOCATION) | |
set(grpc_generate_GRPC_Settings --grpc_out=${grpc_generate_PROTOC_OUT_DIR} --plugin=protoc-gen-grpc=${_GRPC_PLUGIN_PATH}) | |
if(grpc_generate_TARGET) | |
get_target_property(_source_list ${grpc_generate_TARGET} SOURCES) | |
foreach(_file ${_source_list}) | |
if(_file MATCHES "proto$") | |
list(APPEND protobuf_generate_PROTOS ${_file}) | |
endif() | |
endforeach() | |
endif() | |
if(NOT grpc_generate_PROTOS) | |
message(SEND_ERROR "Error: protobuf_generate could not find any .proto files") | |
return() | |
endif() | |
if(grpc_generate_APPEND_PATH) | |
# Create an include path for each file specified | |
foreach(_file ${grpc_generate_PROTOS}) | |
get_filename_component(_abs_file ${_file} ABSOLUTE) | |
get_filename_component(_abs_path ${_abs_file} PATH) | |
list(FIND _protobuf_include_path ${_abs_path} _contains_already) | |
if(${_contains_already} EQUAL -1) | |
list(APPEND _protobuf_include_path -I ${_abs_path}) | |
endif() | |
endforeach() | |
endif() | |
foreach(DIR ${grpc_generate_IMPORT_DIRS}) | |
get_filename_component(ABS_PATH ${DIR} ABSOLUTE) | |
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) | |
if(${_contains_already} EQUAL -1) | |
list(APPEND _protobuf_include_path -I ${ABS_PATH}) | |
endif() | |
endforeach() | |
if(NOT _protobuf_include_path) | |
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) | |
endif() | |
set(_generated_srcs_all) | |
foreach(_proto ${grpc_generate_PROTOS}) | |
get_filename_component(_abs_file ${_proto} ABSOLUTE) | |
get_filename_component(_abs_dir ${_abs_file} DIRECTORY) | |
get_filename_component(_file_full_name ${_proto} NAME) | |
string(FIND "${_file_full_name}" "." _file_last_ext_pos REVERSE) | |
string(SUBSTRING "${_file_full_name}" 0 ${_file_last_ext_pos} _basename) | |
set(_suitable_include_found FALSE) | |
foreach(DIR ${_protobuf_include_path}) | |
if(NOT DIR STREQUAL "-I") | |
file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir}) | |
string(FIND "${_rel_dir}" "../" _is_in_parent_folder) | |
if (NOT ${_is_in_parent_folder} EQUAL 0) | |
set(_suitable_include_found TRUE) | |
break() | |
endif() | |
endif() | |
endforeach() | |
if(NOT _suitable_include_found) | |
message(SEND_ERROR "Error: protobuf_generate could not find any correct proto include directory.") | |
return() | |
endif() | |
set(_generated_srcs) | |
foreach(_ext ${grpc_generate_GENERATE_EXTENSIONS}) | |
list(APPEND _generated_srcs "${grpc_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}_grpc_pb${_ext}") | |
endforeach() | |
list(APPEND _generated_srcs_all ${_generated_srcs}) | |
#get_target_property(_PROTOC_LOC protobuf::protoc LOCATION) | |
#message(STATUS "${_PROTOC_LOC} ${grpc_generate_GRPC_Settings} ${grpc_generate_PROTOC_OPTIONS} ${_protobuf_include_path} ${_abs_file}") | |
add_custom_command( | |
OUTPUT ${_generated_srcs} | |
COMMAND protobuf::protoc | |
ARGS ${grpc_generate_GRPC_Settings} ${grpc_generate_PROTOC_OPTIONS} ${_protobuf_include_path} ${_abs_file} | |
DEPENDS ${_abs_file} protobuf::protoc | |
COMMENT "Running ${grpc_generate_LANGUAGE} grpc buffer compiler on ${_proto}. Custom options: ${grpc_generate_PROTOC_OPTIONS}" | |
VERBATIM | |
) | |
endforeach() | |
set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE) | |
if(grpc_generate_OUT_VAR) | |
set(${grpc_generate_OUT_VAR} ${_generated_srcs_all} PARENT_SCOPE) | |
endif() | |
if(grpc_generate_TARGET) | |
target_sources(${grpc_generate_TARGET} PRIVATE ${_generated_srcs_all}) | |
endif() | |
endfunction() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment