1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5FindProtobuf
6------------
7
8Locate and configure the Google Protocol Buffers library.
9
10.. versionadded:: 3.6
11  Support for :command:`find_package` version checks.
12
13.. versionchanged:: 3.6
14  All input and output variables use the ``Protobuf_`` prefix.
15  Variables with ``PROTOBUF_`` prefix are still supported for compatibility.
16
17The following variables can be set and are optional:
18
19``Protobuf_SRC_ROOT_FOLDER``
20  When compiling with MSVC, if this cache variable is set
21  the protobuf-default VS project build locations
22  (vsprojects/Debug and vsprojects/Release
23  or vsprojects/x64/Debug and vsprojects/x64/Release)
24  will be searched for libraries and binaries.
25``Protobuf_IMPORT_DIRS``
26  List of additional directories to be searched for
27  imported .proto files.
28``Protobuf_DEBUG``
29  .. versionadded:: 3.6
30
31  Show debug messages.
32``Protobuf_USE_STATIC_LIBS``
33  .. versionadded:: 3.9
34
35  Set to ON to force the use of the static libraries.
36  Default is OFF.
37
38Defines the following variables:
39
40``Protobuf_FOUND``
41  Found the Google Protocol Buffers library
42  (libprotobuf & header files)
43``Protobuf_VERSION``
44  .. versionadded:: 3.6
45
46  Version of package found.
47``Protobuf_INCLUDE_DIRS``
48  Include directories for Google Protocol Buffers
49``Protobuf_LIBRARIES``
50  The protobuf libraries
51``Protobuf_PROTOC_LIBRARIES``
52  The protoc libraries
53``Protobuf_LITE_LIBRARIES``
54  The protobuf-lite libraries
55
56.. versionadded:: 3.9
57  The following :prop_tgt:`IMPORTED` targets are also defined:
58
59``protobuf::libprotobuf``
60  The protobuf library.
61``protobuf::libprotobuf-lite``
62  The protobuf lite library.
63``protobuf::libprotoc``
64  The protoc library.
65``protobuf::protoc``
66  .. versionadded:: 3.10
67    The protoc compiler.
68
69The following cache variables are also available to set or use:
70
71``Protobuf_LIBRARY``
72  The protobuf library
73``Protobuf_PROTOC_LIBRARY``
74  The protoc library
75``Protobuf_INCLUDE_DIR``
76  The include directory for protocol buffers
77``Protobuf_PROTOC_EXECUTABLE``
78  The protoc compiler
79``Protobuf_LIBRARY_DEBUG``
80  The protobuf library (debug)
81``Protobuf_PROTOC_LIBRARY_DEBUG``
82  The protoc library (debug)
83``Protobuf_LITE_LIBRARY``
84  The protobuf lite library
85``Protobuf_LITE_LIBRARY_DEBUG``
86  The protobuf lite library (debug)
87
88Example:
89
90.. code-block:: cmake
91
92  find_package(Protobuf REQUIRED)
93  include_directories(${Protobuf_INCLUDE_DIRS})
94  include_directories(${CMAKE_CURRENT_BINARY_DIR})
95  protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
96  protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto)
97  protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS DESCRIPTORS PROTO_DESCS foo.proto)
98  protobuf_generate_python(PROTO_PY foo.proto)
99  add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
100  target_link_libraries(bar ${Protobuf_LIBRARIES})
101
102.. note::
103  The ``protobuf_generate_cpp`` and ``protobuf_generate_python``
104  functions and :command:`add_executable` or :command:`add_library`
105  calls only work properly within the same directory.
106
107.. command:: protobuf_generate_cpp
108
109  Add custom commands to process ``.proto`` files to C++::
110
111    protobuf_generate_cpp (<SRCS> <HDRS>
112        [DESCRIPTORS <DESC>] [EXPORT_MACRO <MACRO>] [<ARGN>...])
113
114  ``SRCS``
115    Variable to define with autogenerated source files
116  ``HDRS``
117    Variable to define with autogenerated header files
118  ``DESCRIPTORS``
119    .. versionadded:: 3.10
120      Variable to define with autogenerated descriptor files, if requested.
121  ``EXPORT_MACRO``
122    is a macro which should expand to ``__declspec(dllexport)`` or
123    ``__declspec(dllimport)`` depending on what is being compiled.
124  ``ARGN``
125    ``.proto`` files
126
127.. command:: protobuf_generate_python
128
129  .. versionadded:: 3.4
130
131  Add custom commands to process ``.proto`` files to Python::
132
133    protobuf_generate_python (<PY> [<ARGN>...])
134
135  ``PY``
136    Variable to define with autogenerated Python files
137  ``ARGN``
138    ``.proto`` files
139#]=======================================================================]
140
141function(protobuf_generate)
142  set(_options APPEND_PATH DESCRIPTORS)
143  set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN)
144  if(COMMAND target_sources)
145    list(APPEND _singleargs TARGET)
146  endif()
147  set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS)
148
149  cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
150
151  if(NOT protobuf_generate_PROTOS AND NOT protobuf_generate_TARGET)
152    message(SEND_ERROR "Error: protobuf_generate called without any targets or source files")
153    return()
154  endif()
155
156  if(NOT protobuf_generate_OUT_VAR AND NOT protobuf_generate_TARGET)
157    message(SEND_ERROR "Error: protobuf_generate called without a target or output variable")
158    return()
159  endif()
160
161  if(NOT protobuf_generate_LANGUAGE)
162    set(protobuf_generate_LANGUAGE cpp)
163  endif()
164  string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE)
165
166  if(NOT protobuf_generate_PROTOC_OUT_DIR)
167    set(protobuf_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
168  endif()
169
170  if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp)
171    set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:")
172  endif()
173
174  if(protobuf_generate_PLUGIN)
175    set(_plugin "--plugin=${protobuf_generate_PLUGIN}")
176  endif()
177
178  if(NOT protobuf_generate_GENERATE_EXTENSIONS)
179    if(protobuf_generate_LANGUAGE STREQUAL cpp)
180      set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc)
181    elseif(protobuf_generate_LANGUAGE STREQUAL python)
182      set(protobuf_generate_GENERATE_EXTENSIONS _pb2.py)
183    else()
184      message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS")
185      return()
186    endif()
187  endif()
188
189  if(protobuf_generate_TARGET)
190    get_target_property(_source_list ${protobuf_generate_TARGET} SOURCES)
191    foreach(_file ${_source_list})
192      if(_file MATCHES "proto$")
193        list(APPEND protobuf_generate_PROTOS ${_file})
194      endif()
195    endforeach()
196  endif()
197
198  if(NOT protobuf_generate_PROTOS)
199    message(SEND_ERROR "Error: protobuf_generate could not find any .proto files")
200    return()
201  endif()
202
203  if(protobuf_generate_APPEND_PATH)
204    # Create an include path for each file specified
205    foreach(_file ${protobuf_generate_PROTOS})
206      get_filename_component(_abs_file ${_file} ABSOLUTE)
207      get_filename_component(_abs_path ${_abs_file} PATH)
208      list(FIND _protobuf_include_path ${_abs_path} _contains_already)
209      if(${_contains_already} EQUAL -1)
210          list(APPEND _protobuf_include_path -I ${_abs_path})
211      endif()
212    endforeach()
213  else()
214    set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
215  endif()
216
217  foreach(DIR ${protobuf_generate_IMPORT_DIRS})
218    get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
219    list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
220    if(${_contains_already} EQUAL -1)
221        list(APPEND _protobuf_include_path -I ${ABS_PATH})
222    endif()
223  endforeach()
224
225  set(_generated_srcs_all)
226  foreach(_proto ${protobuf_generate_PROTOS})
227    get_filename_component(_abs_file ${_proto} ABSOLUTE)
228    get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
229    get_filename_component(_basename ${_proto} NAME_WLE)
230    file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
231
232    set(_possible_rel_dir)
233    if (NOT protobuf_generate_APPEND_PATH)
234        set(_possible_rel_dir ${_rel_dir}/)
235    endif()
236
237    set(_generated_srcs)
238    foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS})
239      list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_possible_rel_dir}${_basename}${_ext}")
240    endforeach()
241
242    if(protobuf_generate_DESCRIPTORS AND protobuf_generate_LANGUAGE STREQUAL cpp)
243      set(_descriptor_file "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.desc")
244      set(_dll_desc_out "--descriptor_set_out=${_descriptor_file}")
245      list(APPEND _generated_srcs ${_descriptor_file})
246    endif()
247    list(APPEND _generated_srcs_all ${_generated_srcs})
248
249    add_custom_command(
250      OUTPUT ${_generated_srcs}
251      COMMAND  protobuf::protoc
252      ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file}
253      DEPENDS ${_abs_file} protobuf::protoc
254      COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}"
255      VERBATIM )
256  endforeach()
257
258  set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE)
259  if(protobuf_generate_OUT_VAR)
260    set(${protobuf_generate_OUT_VAR} ${_generated_srcs_all} PARENT_SCOPE)
261  endif()
262  if(protobuf_generate_TARGET)
263    target_sources(${protobuf_generate_TARGET} PRIVATE ${_generated_srcs_all})
264  endif()
265endfunction()
266
267function(PROTOBUF_GENERATE_CPP SRCS HDRS)
268  cmake_parse_arguments(protobuf_generate_cpp "" "EXPORT_MACRO;DESCRIPTORS" "" ${ARGN})
269
270  set(_proto_files "${protobuf_generate_cpp_UNPARSED_ARGUMENTS}")
271  if(NOT _proto_files)
272    message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
273    return()
274  endif()
275
276  if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
277    set(_append_arg APPEND_PATH)
278  endif()
279
280  if(protobuf_generate_cpp_DESCRIPTORS)
281    set(_descriptors DESCRIPTORS)
282  endif()
283
284  if(DEFINED PROTOBUF_IMPORT_DIRS AND NOT DEFINED Protobuf_IMPORT_DIRS)
285    set(Protobuf_IMPORT_DIRS "${PROTOBUF_IMPORT_DIRS}")
286  endif()
287
288  if(DEFINED Protobuf_IMPORT_DIRS)
289    set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
290  endif()
291
292  set(_outvar)
293  protobuf_generate(${_append_arg} ${_descriptors} LANGUAGE cpp EXPORT_MACRO ${protobuf_generate_cpp_EXPORT_MACRO} OUT_VAR _outvar ${_import_arg} PROTOS ${_proto_files})
294
295  set(${SRCS})
296  set(${HDRS})
297  if(protobuf_generate_cpp_DESCRIPTORS)
298    set(${protobuf_generate_cpp_DESCRIPTORS})
299  endif()
300
301  foreach(_file ${_outvar})
302    if(_file MATCHES "cc$")
303      list(APPEND ${SRCS} ${_file})
304    elseif(_file MATCHES "desc$")
305      list(APPEND ${protobuf_generate_cpp_DESCRIPTORS} ${_file})
306    else()
307      list(APPEND ${HDRS} ${_file})
308    endif()
309  endforeach()
310  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
311  set(${HDRS} ${${HDRS}} PARENT_SCOPE)
312  if(protobuf_generate_cpp_DESCRIPTORS)
313    set(${protobuf_generate_cpp_DESCRIPTORS} "${${protobuf_generate_cpp_DESCRIPTORS}}" PARENT_SCOPE)
314  endif()
315endfunction()
316
317function(PROTOBUF_GENERATE_PYTHON SRCS)
318  if(NOT ARGN)
319    message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
320    return()
321  endif()
322
323  if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
324    set(_append_arg APPEND_PATH)
325  endif()
326
327  if(DEFINED PROTOBUF_IMPORT_DIRS AND NOT DEFINED Protobuf_IMPORT_DIRS)
328    set(Protobuf_IMPORT_DIRS "${PROTOBUF_IMPORT_DIRS}")
329  endif()
330
331  if(DEFINED Protobuf_IMPORT_DIRS)
332    set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
333  endif()
334
335  set(_outvar)
336  protobuf_generate(${_append_arg} LANGUAGE python OUT_VAR _outvar ${_import_arg} PROTOS ${ARGN})
337  set(${SRCS} ${_outvar} PARENT_SCOPE)
338endfunction()
339
340
341if(Protobuf_DEBUG)
342  # Output some of their choices
343  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
344                 "Protobuf_USE_STATIC_LIBS = ${Protobuf_USE_STATIC_LIBS}")
345endif()
346
347
348# Backwards compatibility
349# Define camel case versions of input variables
350foreach(UPPER
351    PROTOBUF_SRC_ROOT_FOLDER
352    PROTOBUF_IMPORT_DIRS
353    PROTOBUF_DEBUG
354    PROTOBUF_LIBRARY
355    PROTOBUF_PROTOC_LIBRARY
356    PROTOBUF_INCLUDE_DIR
357    PROTOBUF_PROTOC_EXECUTABLE
358    PROTOBUF_LIBRARY_DEBUG
359    PROTOBUF_PROTOC_LIBRARY_DEBUG
360    PROTOBUF_LITE_LIBRARY
361    PROTOBUF_LITE_LIBRARY_DEBUG
362    )
363    if (DEFINED ${UPPER})
364        string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
365        if (NOT DEFINED ${Camel})
366            set(${Camel} ${${UPPER}})
367        endif()
368    endif()
369endforeach()
370
371if(CMAKE_SIZEOF_VOID_P EQUAL 8)
372  set(_PROTOBUF_ARCH_DIR x64/)
373endif()
374
375
376# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
377if( Protobuf_USE_STATIC_LIBS )
378  set( _protobuf_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
379  if(WIN32)
380    set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
381  else()
382    set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
383  endif()
384endif()
385
386include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
387
388# Internal function: search for normal library as well as a debug one
389#    if the debug one is specified also include debug/optimized keywords
390#    in *_LIBRARIES variable
391function(_protobuf_find_libraries name filename)
392  if(${name}_LIBRARIES)
393    # Use result recorded by a previous call.
394    return()
395  elseif(${name}_LIBRARY)
396    # Honor cache entry used by CMake 3.5 and lower.
397    set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE)
398  else()
399    find_library(${name}_LIBRARY_RELEASE
400      NAMES ${filename}
401      NAMES_PER_DIR
402      PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
403    mark_as_advanced(${name}_LIBRARY_RELEASE)
404
405    find_library(${name}_LIBRARY_DEBUG
406      NAMES ${filename}d ${filename}
407      NAMES_PER_DIR
408      PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
409    mark_as_advanced(${name}_LIBRARY_DEBUG)
410
411    select_library_configurations(${name})
412
413    if(UNIX AND Threads_FOUND AND ${name}_LIBRARY)
414      list(APPEND ${name}_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
415    endif()
416
417    set(${name}_LIBRARY "${${name}_LIBRARY}" PARENT_SCOPE)
418    set(${name}_LIBRARIES "${${name}_LIBRARIES}" PARENT_SCOPE)
419  endif()
420endfunction()
421
422#
423# Main.
424#
425
426# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
427# for each directory where a proto file is referenced.
428if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
429  set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
430endif()
431
432
433# Google's provided vcproj files generate libraries with a "lib"
434# prefix on Windows
435if(MSVC)
436    set(Protobuf_ORIG_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
437    set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
438
439    find_path(Protobuf_SRC_ROOT_FOLDER protobuf.pc.in)
440endif()
441
442if(UNIX)
443  # Protobuf headers may depend on threading.
444  find_package(Threads QUIET)
445endif()
446
447# The Protobuf library
448_protobuf_find_libraries(Protobuf protobuf)
449#DOC "The Google Protocol Buffers RELEASE Library"
450
451_protobuf_find_libraries(Protobuf_LITE protobuf-lite)
452
453# The Protobuf Protoc Library
454_protobuf_find_libraries(Protobuf_PROTOC protoc)
455
456# Restore original find library prefixes
457if(MSVC)
458    set(CMAKE_FIND_LIBRARY_PREFIXES "${Protobuf_ORIG_FIND_LIBRARY_PREFIXES}")
459endif()
460
461# Find the include directory
462find_path(Protobuf_INCLUDE_DIR
463    google/protobuf/service.h
464    PATHS ${Protobuf_SRC_ROOT_FOLDER}/src
465)
466mark_as_advanced(Protobuf_INCLUDE_DIR)
467
468# Find the protoc Executable
469find_program(Protobuf_PROTOC_EXECUTABLE
470    NAMES protoc
471    DOC "The Google Protocol Buffers Compiler"
472    PATHS
473    ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release
474    ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug
475)
476mark_as_advanced(Protobuf_PROTOC_EXECUTABLE)
477
478if(Protobuf_DEBUG)
479    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
480        "requested version of Google Protobuf is ${Protobuf_FIND_VERSION}")
481endif()
482
483if(Protobuf_INCLUDE_DIR)
484  set(_PROTOBUF_COMMON_HEADER ${Protobuf_INCLUDE_DIR}/google/protobuf/stubs/common.h)
485
486  if(Protobuf_DEBUG)
487    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
488                   "location of common.h: ${_PROTOBUF_COMMON_HEADER}")
489  endif()
490
491  set(Protobuf_VERSION "")
492  set(Protobuf_LIB_VERSION "")
493  file(STRINGS ${_PROTOBUF_COMMON_HEADER} _PROTOBUF_COMMON_H_CONTENTS REGEX "#define[ \t]+GOOGLE_PROTOBUF_VERSION[ \t]+")
494  if(_PROTOBUF_COMMON_H_CONTENTS MATCHES "#define[ \t]+GOOGLE_PROTOBUF_VERSION[ \t]+([0-9]+)")
495      set(Protobuf_LIB_VERSION "${CMAKE_MATCH_1}")
496  endif()
497  unset(_PROTOBUF_COMMON_H_CONTENTS)
498
499  math(EXPR _PROTOBUF_MAJOR_VERSION "${Protobuf_LIB_VERSION} / 1000000")
500  math(EXPR _PROTOBUF_MINOR_VERSION "${Protobuf_LIB_VERSION} / 1000 % 1000")
501  math(EXPR _PROTOBUF_SUBMINOR_VERSION "${Protobuf_LIB_VERSION} % 1000")
502  set(Protobuf_VERSION "${_PROTOBUF_MAJOR_VERSION}.${_PROTOBUF_MINOR_VERSION}.${_PROTOBUF_SUBMINOR_VERSION}")
503
504  if(Protobuf_DEBUG)
505    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
506        "${_PROTOBUF_COMMON_HEADER} reveals protobuf ${Protobuf_VERSION}")
507  endif()
508
509  if(Protobuf_PROTOC_EXECUTABLE)
510    # Check Protobuf compiler version to be aligned with libraries version
511    execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} --version
512                    OUTPUT_VARIABLE _PROTOBUF_PROTOC_EXECUTABLE_VERSION)
513
514    if("${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" MATCHES "libprotoc ([0-9.]+)")
515      set(_PROTOBUF_PROTOC_EXECUTABLE_VERSION "${CMAKE_MATCH_1}")
516    endif()
517
518    if(Protobuf_DEBUG)
519      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
520          "${Protobuf_PROTOC_EXECUTABLE} reveals version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}")
521    endif()
522
523    if(NOT "${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" VERSION_EQUAL "${Protobuf_VERSION}")
524      message(WARNING "Protobuf compiler version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}"
525        " doesn't match library version ${Protobuf_VERSION}")
526    endif()
527  endif()
528
529  if(Protobuf_LIBRARY)
530      if(NOT TARGET protobuf::libprotobuf)
531          add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
532          set_target_properties(protobuf::libprotobuf PROPERTIES
533            INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
534          if(EXISTS "${Protobuf_LIBRARY}")
535            set_target_properties(protobuf::libprotobuf PROPERTIES
536              IMPORTED_LOCATION "${Protobuf_LIBRARY}")
537          endif()
538          if(EXISTS "${Protobuf_LIBRARY_RELEASE}")
539            set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
540              IMPORTED_CONFIGURATIONS RELEASE)
541            set_target_properties(protobuf::libprotobuf PROPERTIES
542              IMPORTED_LOCATION_RELEASE "${Protobuf_LIBRARY_RELEASE}")
543          endif()
544          if(EXISTS "${Protobuf_LIBRARY_DEBUG}")
545            set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
546              IMPORTED_CONFIGURATIONS DEBUG)
547            set_target_properties(protobuf::libprotobuf PROPERTIES
548              IMPORTED_LOCATION_DEBUG "${Protobuf_LIBRARY_DEBUG}")
549          endif()
550          if (Protobuf_VERSION VERSION_GREATER_EQUAL "3.6")
551            set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
552              INTERFACE_COMPILE_FEATURES cxx_std_11
553            )
554          endif()
555          if (MSVC AND NOT Protobuf_USE_STATIC_LIBS)
556            set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
557              INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS"
558            )
559          endif()
560          if(UNIX AND TARGET Threads::Threads)
561            set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
562                INTERFACE_LINK_LIBRARIES Threads::Threads)
563          endif()
564      endif()
565  endif()
566
567  if(Protobuf_LITE_LIBRARY)
568      if(NOT TARGET protobuf::libprotobuf-lite)
569          add_library(protobuf::libprotobuf-lite UNKNOWN IMPORTED)
570          set_target_properties(protobuf::libprotobuf-lite PROPERTIES
571            INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
572          if(EXISTS "${Protobuf_LITE_LIBRARY}")
573            set_target_properties(protobuf::libprotobuf-lite PROPERTIES
574              IMPORTED_LOCATION "${Protobuf_LITE_LIBRARY}")
575          endif()
576          if(EXISTS "${Protobuf_LITE_LIBRARY_RELEASE}")
577            set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
578              IMPORTED_CONFIGURATIONS RELEASE)
579            set_target_properties(protobuf::libprotobuf-lite PROPERTIES
580              IMPORTED_LOCATION_RELEASE "${Protobuf_LITE_LIBRARY_RELEASE}")
581          endif()
582          if(EXISTS "${Protobuf_LITE_LIBRARY_DEBUG}")
583            set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
584              IMPORTED_CONFIGURATIONS DEBUG)
585            set_target_properties(protobuf::libprotobuf-lite PROPERTIES
586              IMPORTED_LOCATION_DEBUG "${Protobuf_LITE_LIBRARY_DEBUG}")
587          endif()
588          if (MSVC AND NOT Protobuf_USE_STATIC_LIBS)
589            set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
590              INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS"
591            )
592          endif()
593          if(UNIX AND TARGET Threads::Threads)
594            set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
595                INTERFACE_LINK_LIBRARIES Threads::Threads)
596          endif()
597      endif()
598  endif()
599
600  if(Protobuf_PROTOC_LIBRARY)
601      if(NOT TARGET protobuf::libprotoc)
602          add_library(protobuf::libprotoc UNKNOWN IMPORTED)
603          set_target_properties(protobuf::libprotoc PROPERTIES
604            INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
605          if(EXISTS "${Protobuf_PROTOC_LIBRARY}")
606            set_target_properties(protobuf::libprotoc PROPERTIES
607              IMPORTED_LOCATION "${Protobuf_PROTOC_LIBRARY}")
608          endif()
609          if(EXISTS "${Protobuf_PROTOC_LIBRARY_RELEASE}")
610            set_property(TARGET protobuf::libprotoc APPEND PROPERTY
611              IMPORTED_CONFIGURATIONS RELEASE)
612            set_target_properties(protobuf::libprotoc PROPERTIES
613              IMPORTED_LOCATION_RELEASE "${Protobuf_PROTOC_LIBRARY_RELEASE}")
614          endif()
615          if(EXISTS "${Protobuf_PROTOC_LIBRARY_DEBUG}")
616            set_property(TARGET protobuf::libprotoc APPEND PROPERTY
617              IMPORTED_CONFIGURATIONS DEBUG)
618            set_target_properties(protobuf::libprotoc PROPERTIES
619              IMPORTED_LOCATION_DEBUG "${Protobuf_PROTOC_LIBRARY_DEBUG}")
620          endif()
621          if (Protobuf_VERSION VERSION_GREATER_EQUAL "3.6")
622            set_property(TARGET protobuf::libprotoc APPEND PROPERTY
623              INTERFACE_COMPILE_FEATURES cxx_std_11
624            )
625          endif()
626          if (MSVC AND NOT Protobuf_USE_STATIC_LIBS)
627            set_property(TARGET protobuf::libprotoc APPEND PROPERTY
628              INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS"
629            )
630          endif()
631          if(UNIX AND TARGET Threads::Threads)
632            set_property(TARGET protobuf::libprotoc APPEND PROPERTY
633                INTERFACE_LINK_LIBRARIES Threads::Threads)
634          endif()
635      endif()
636  endif()
637
638  if(Protobuf_PROTOC_EXECUTABLE)
639      if(NOT TARGET protobuf::protoc)
640          add_executable(protobuf::protoc IMPORTED)
641          if(EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
642            set_target_properties(protobuf::protoc PROPERTIES
643              IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}")
644          endif()
645      endif()
646  endif()
647endif()
648
649include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
650FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf
651    REQUIRED_VARS Protobuf_LIBRARIES Protobuf_INCLUDE_DIR
652    VERSION_VAR Protobuf_VERSION
653)
654
655if(Protobuf_FOUND)
656    set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR})
657endif()
658
659# Restore the original find library ordering
660if( Protobuf_USE_STATIC_LIBS )
661  set(CMAKE_FIND_LIBRARY_SUFFIXES ${_protobuf_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
662endif()
663
664# Backwards compatibility
665# Define upper case versions of output variables
666foreach(Camel
667    Protobuf_SRC_ROOT_FOLDER
668    Protobuf_IMPORT_DIRS
669    Protobuf_DEBUG
670    Protobuf_INCLUDE_DIRS
671    Protobuf_LIBRARIES
672    Protobuf_PROTOC_LIBRARIES
673    Protobuf_LITE_LIBRARIES
674    Protobuf_LIBRARY
675    Protobuf_PROTOC_LIBRARY
676    Protobuf_INCLUDE_DIR
677    Protobuf_PROTOC_EXECUTABLE
678    Protobuf_LIBRARY_DEBUG
679    Protobuf_PROTOC_LIBRARY_DEBUG
680    Protobuf_LITE_LIBRARY
681    Protobuf_LITE_LIBRARY_DEBUG
682    )
683    string(TOUPPER ${Camel} UPPER)
684    set(${UPPER} ${${Camel}})
685endforeach()
686