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 103 get_filename_component(_file_full_name ${_proto} NAME) 104 string(FIND "${_file_full_name}" "." _file_last_ext_pos REVERSE) 105 string(SUBSTRING "${_file_full_name}" 0 ${_file_last_ext_pos} _basename) 106 107 set(_suitable_include_found FALSE) 108 foreach(DIR ${_protobuf_include_path}) 109 if(NOT DIR STREQUAL "-I") 110 file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir}) 111 string(FIND "${_rel_dir}" "../" _is_in_parent_folder) 112 if (NOT ${_is_in_parent_folder} EQUAL 0) 113 set(_suitable_include_found TRUE) 114 break() 115 endif() 116 endif() 117 endforeach() 118 119 if(NOT _suitable_include_found) 120 message(SEND_ERROR "Error: protobuf_generate could not find any correct proto include directory.") 121 return() 122 endif() 123 124 set(_generated_srcs) 125 foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS}) 126 list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}") 127 endforeach() 128 list(APPEND _generated_srcs_all ${_generated_srcs}) 129 130 add_custom_command( 131 OUTPUT ${_generated_srcs} 132 COMMAND protobuf::protoc 133 ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} 134 DEPENDS ${_abs_file} protobuf::protoc 135 COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" 136 VERBATIM ) 137 endforeach() 138 139 set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE) 140 if(protobuf_generate_OUT_VAR) 141 set(${protobuf_generate_OUT_VAR} ${_generated_srcs_all} PARENT_SCOPE) 142 endif() 143 if(protobuf_generate_TARGET) 144 target_sources(${protobuf_generate_TARGET} PRIVATE ${_generated_srcs_all}) 145 endif() 146 147endfunction() 148 149# CMake FindProtobuf module compatible file 150if(protobuf_MODULE_COMPATIBLE) 151 include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake") 152endif() 153