FindProtobuf.cmake 28 KB

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