1# User options 2include("${CMAKE_CURRENT_LIST_DIR}/protobuf-options.cmake") 3 4# Depend packages 5@_protobuf_FIND_ZLIB@ 6 7# Imported targets 8include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake") 9 10function(protobuf_generate) 11 include(CMakeParseArguments) 12 13 set(_options APPEND_PATH) 14 set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN) 15 if(COMMAND target_sources) 16 list(APPEND _singleargs TARGET) 17 endif() 18 set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS) 19 20 cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}") 21 22 if(NOT protobuf_generate_PROTOS AND NOT protobuf_generate_TARGET) 23 message(SEND_ERROR "Error: protobuf_generate called without any targets or source files") 24 return() 25 endif() 26 27 if(NOT protobuf_generate_OUT_VAR AND NOT protobuf_generate_TARGET) 28 message(SEND_ERROR "Error: protobuf_generate called without a target or output variable") 29 return() 30 endif() 31 32 if(NOT protobuf_generate_LANGUAGE) 33 set(protobuf_generate_LANGUAGE cpp) 34 endif() 35 string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE) 36 37 if(NOT protobuf_generate_PROTOC_OUT_DIR) 38 set(protobuf_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) 39 endif() 40 41 if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp) 42 set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:") 43 endif() 44 45 if(protobuf_generate_PLUGIN) 46 set(_plugin "--plugin=${protobuf_generate_PLUGIN}") 47 endif() 48 49 if(NOT protobuf_generate_GENERATE_EXTENSIONS) 50 if(protobuf_generate_LANGUAGE STREQUAL cpp) 51 set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc) 52 elseif(protobuf_generate_LANGUAGE STREQUAL python) 53 set(protobuf_generate_GENERATE_EXTENSIONS _pb2.py) 54 else() 55 message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS") 56 return() 57 endif() 58 endif() 59 60 if(protobuf_generate_TARGET) 61 get_target_property(_source_list ${protobuf_generate_TARGET} SOURCES) 62 foreach(_file ${_source_list}) 63 if(_file MATCHES "proto$") 64 list(APPEND protobuf_generate_PROTOS ${_file}) 65 endif() 66 endforeach() 67 endif() 68 69 if(NOT protobuf_generate_PROTOS) 70 message(SEND_ERROR "Error: protobuf_generate could not find any .proto files") 71 return() 72 endif() 73 74 if(protobuf_generate_APPEND_PATH) 75 # Create an include path for each file specified 76 foreach(_file ${protobuf_generate_PROTOS}) 77 get_filename_component(_abs_file ${_file} ABSOLUTE) 78 get_filename_component(_abs_path ${_abs_file} PATH) 79 list(FIND _protobuf_include_path ${_abs_path} _contains_already) 80 if(${_contains_already} EQUAL -1) 81 list(APPEND _protobuf_include_path -I ${_abs_path}) 82 endif() 83 endforeach() 84 endif() 85 86 foreach(DIR ${protobuf_generate_IMPORT_DIRS}) 87 get_filename_component(ABS_PATH ${DIR} ABSOLUTE) 88 list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) 89 if(${_contains_already} EQUAL -1) 90 list(APPEND _protobuf_include_path -I ${ABS_PATH}) 91 endif() 92 endforeach() 93 94 if(NOT _protobuf_include_path) 95 set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) 96 endif() 97 98 set(_generated_srcs_all) 99 foreach(_proto ${protobuf_generate_PROTOS}) 100 get_filename_component(_abs_file ${_proto} ABSOLUTE) 101 get_filename_component(_abs_dir ${_abs_file} DIRECTORY) 102 get_filename_component(_basename ${_proto} NAME_WLE) 103 104 set(_suitable_include_found FALSE) 105 foreach(DIR ${_protobuf_include_path}) 106 if(NOT DIR STREQUAL "-I") 107 file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir}) 108 if(NOT "${_rel_dir}" MATCHES "^\.\.[/\\].*") 109 set(_suitable_include_found TRUE) 110 break() 111 endif() 112 endif() 113 endforeach() 114 115 if(NOT _suitable_include_found) 116 message(SEND_ERROR "Error: protobuf_generate could not find any correct proto include directory.") 117 return() 118 endif() 119 120 set(_generated_srcs) 121 foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS}) 122 list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}") 123 endforeach() 124 list(APPEND _generated_srcs_all ${_generated_srcs}) 125 126 add_custom_command( 127 OUTPUT ${_generated_srcs} 128 COMMAND protobuf::protoc 129 ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} 130 DEPENDS ${_abs_file} protobuf::protoc 131 COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" 132 VERBATIM ) 133 endforeach() 134 135 set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE) 136 if(protobuf_generate_OUT_VAR) 137 set(${protobuf_generate_OUT_VAR} ${_generated_srcs_all} PARENT_SCOPE) 138 endif() 139 if(protobuf_generate_TARGET) 140 target_sources(${protobuf_generate_TARGET} PRIVATE ${_generated_srcs_all}) 141 endif() 142 143endfunction() 144 145# CMake FindProtobuf module compatible file 146if(protobuf_MODULE_COMPATIBLE) 147 include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake") 148endif() 149