Separate protobuf-generate cmake function to own file (#10426)
When using "FetchContent_Declare" with OVERRIDE_FIND_PACKAGE, protobuf-config.cmake won't be used, thus the protobuf-generate macro would be unavailable. By moving protobuf_generate to its own file, it can be sourced and used even when using CMake's FetchContent. Co-authored-by: Harald Fernengel <547273+haraldF@users.noreply.github.com>pull/10448/head
parent
43b8721457
commit
ad55f52fdb
3 changed files with 159 additions and 155 deletions
@ -0,0 +1,155 @@ |
||||
function(protobuf_generate) |
||||
include(CMakeParseArguments) |
||||
|
||||
set(_options APPEND_PATH) |
||||
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES) |
||||
if(COMMAND target_sources) |
||||
list(APPEND _singleargs TARGET) |
||||
endif() |
||||
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS) |
||||
|
||||
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}") |
||||
|
||||
if(NOT protobuf_generate_PROTOS AND NOT protobuf_generate_TARGET) |
||||
message(SEND_ERROR "Error: protobuf_generate called without any targets or source files") |
||||
return() |
||||
endif() |
||||
|
||||
if(NOT protobuf_generate_OUT_VAR AND NOT protobuf_generate_TARGET) |
||||
message(SEND_ERROR "Error: protobuf_generate called without a target or output variable") |
||||
return() |
||||
endif() |
||||
|
||||
if(NOT protobuf_generate_LANGUAGE) |
||||
set(protobuf_generate_LANGUAGE cpp) |
||||
endif() |
||||
string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE) |
||||
|
||||
if(NOT protobuf_generate_PROTOC_OUT_DIR) |
||||
set(protobuf_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) |
||||
endif() |
||||
|
||||
if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp) |
||||
set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}") |
||||
endif() |
||||
|
||||
foreach(_option ${_dll_export_decl} ${protobuf_generate_PLUGIN_OPTIONS}) |
||||
# append comma - not using CMake lists and string replacement as users |
||||
# might have semicolons in options |
||||
if(_plugin_options) |
||||
set( _plugin_options "${_plugin_options},") |
||||
endif() |
||||
set(_plugin_options "${_plugin_options}${_option}") |
||||
endforeach() |
||||
|
||||
if(protobuf_generate_PLUGIN) |
||||
set(_plugin "--plugin=${protobuf_generate_PLUGIN}") |
||||
endif() |
||||
|
||||
if(NOT protobuf_generate_GENERATE_EXTENSIONS) |
||||
if(protobuf_generate_LANGUAGE STREQUAL cpp) |
||||
set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc) |
||||
elseif(protobuf_generate_LANGUAGE STREQUAL python) |
||||
set(protobuf_generate_GENERATE_EXTENSIONS _pb2.py) |
||||
else() |
||||
message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS") |
||||
return() |
||||
endif() |
||||
endif() |
||||
|
||||
if(protobuf_generate_TARGET) |
||||
get_target_property(_source_list ${protobuf_generate_TARGET} SOURCES) |
||||
foreach(_file ${_source_list}) |
||||
if(_file MATCHES "proto$") |
||||
list(APPEND protobuf_generate_PROTOS ${_file}) |
||||
endif() |
||||
endforeach() |
||||
endif() |
||||
|
||||
if(NOT protobuf_generate_PROTOS) |
||||
message(SEND_ERROR "Error: protobuf_generate could not find any .proto files") |
||||
return() |
||||
endif() |
||||
|
||||
if(protobuf_generate_APPEND_PATH) |
||||
# Create an include path for each file specified |
||||
foreach(_file ${protobuf_generate_PROTOS}) |
||||
get_filename_component(_abs_file ${_file} ABSOLUTE) |
||||
get_filename_component(_abs_dir ${_abs_file} DIRECTORY) |
||||
list(FIND _protobuf_include_path ${_abs_dir} _contains_already) |
||||
if(${_contains_already} EQUAL -1) |
||||
list(APPEND _protobuf_include_path -I ${_abs_dir}) |
||||
endif() |
||||
endforeach() |
||||
endif() |
||||
|
||||
foreach(DIR ${protobuf_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 ${protobuf_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 ${protobuf_generate_GENERATE_EXTENSIONS}) |
||||
list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}") |
||||
endforeach() |
||||
list(APPEND _generated_srcs_all ${_generated_srcs}) |
||||
|
||||
set(_comment "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}") |
||||
if(protobuf_generate_PROTOC_OPTIONS) |
||||
set(_comment "${_comment}, protoc-options: ${protobuf_generate_PROTOC_OPTIONS}") |
||||
endif() |
||||
if(_plugin_options) |
||||
set(_comment "${_comment}, plugin-options: ${_plugin_options}") |
||||
endif() |
||||
|
||||
add_custom_command( |
||||
OUTPUT ${_generated_srcs} |
||||
COMMAND protobuf::protoc |
||||
ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} |
||||
DEPENDS ${_abs_file} protobuf::protoc ${protobuf_generate_DEPENDENCIES} |
||||
COMMENT ${_comment} |
||||
VERBATIM ) |
||||
endforeach() |
||||
|
||||
set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE) |
||||
if(protobuf_generate_OUT_VAR) |
||||
set(${protobuf_generate_OUT_VAR} ${_generated_srcs_all} PARENT_SCOPE) |
||||
endif() |
||||
if(protobuf_generate_TARGET) |
||||
target_sources(${protobuf_generate_TARGET} PRIVATE ${_generated_srcs_all}) |
||||
endif() |
||||
|
||||
endfunction() |
Loading…
Reference in new issue