FindProtobuf.cmake 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #.rst:
  2. # FindProtobuf
  3. # ------------
  4. #
  5. # Locate and configure the Google Protocol Buffers library.
  6. #
  7. # The following variables can be set and are optional:
  8. #
  9. # ``PROTOBUF_SRC_ROOT_FOLDER``
  10. # When compiling with MSVC, if this cache variable is set
  11. # the protobuf-default VS project build locations
  12. # (vsprojects/Debug and vsprojects/Release
  13. # or vsprojects/x64/Debug and vsprojects/x64/Release)
  14. # will be searched for libraries and binaries.
  15. # ``PROTOBUF_IMPORT_DIRS``
  16. # List of additional directories to be searched for
  17. # imported .proto files.
  18. #
  19. # Defines the following variables:
  20. #
  21. # ``PROTOBUF_FOUND``
  22. # Found the Google Protocol Buffers library
  23. # (libprotobuf & header files)
  24. # ``PROTOBUF_INCLUDE_DIRS``
  25. # Include directories for Google Protocol Buffers
  26. # ``PROTOBUF_LIBRARIES``
  27. # The protobuf libraries
  28. # ``PROTOBUF_PROTOC_LIBRARIES``
  29. # The protoc libraries
  30. # ``PROTOBUF_LITE_LIBRARIES``
  31. # The protobuf-lite libraries
  32. #
  33. # The following cache variables are also available to set or use:
  34. #
  35. # ``PROTOBUF_LIBRARY``
  36. # The protobuf library
  37. # ``PROTOBUF_PROTOC_LIBRARY``
  38. # The protoc library
  39. # ``PROTOBUF_INCLUDE_DIR``
  40. # The include directory for protocol buffers
  41. # ``PROTOBUF_PROTOC_EXECUTABLE``
  42. # The protoc compiler
  43. # ``PROTOBUF_LIBRARY_DEBUG``
  44. # The protobuf library (debug)
  45. # ``PROTOBUF_PROTOC_LIBRARY_DEBUG``
  46. # The protoc library (debug)
  47. # ``PROTOBUF_LITE_LIBRARY``
  48. # The protobuf lite library
  49. # ``PROTOBUF_LITE_LIBRARY_DEBUG``
  50. # The protobuf lite library (debug)
  51. #
  52. # Example:
  53. #
  54. # .. code-block:: cmake
  55. #
  56. # find_package(Protobuf REQUIRED)
  57. # include_directories(${PROTOBUF_INCLUDE_DIRS})
  58. # include_directories(${CMAKE_CURRENT_BINARY_DIR})
  59. # protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
  60. # protobuf_generate_python(PROTO_PY foo.proto)
  61. # add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
  62. # target_link_libraries(bar ${PROTOBUF_LIBRARIES})
  63. #
  64. # .. note::
  65. # The ``protobuf_generate_cpp`` and ``protobuf_generate_python``
  66. # functions and :command:`add_executable` or :command:`add_library`
  67. # calls only work properly within the same directory.
  68. #
  69. # .. command:: protobuf_generate_cpp
  70. #
  71. # Add custom commands to process ``.proto`` files to C++::
  72. #
  73. # protobuf_generate_cpp (<SRCS> <HDRS> [<ARGN>...])
  74. #
  75. # ``SRCS``
  76. # Variable to define with autogenerated source files
  77. # ``HDRS``
  78. # Variable to define with autogenerated header files
  79. # ``ARGN``
  80. # ``.proto`` files
  81. #
  82. # .. command:: protobuf_generate_python
  83. #
  84. # Add custom commands to process ``.proto`` files to Python::
  85. #
  86. # protobuf_generate_python (<PY> [<ARGN>...])
  87. #
  88. # ``PY``
  89. # Variable to define with autogenerated Python files
  90. # ``ARGN``
  91. # ``.proto`` filess
  92. #=============================================================================
  93. # Copyright 2009 Kitware, Inc.
  94. # Copyright 2009-2011 Philip Lowman <[email protected]>
  95. # Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
  96. #
  97. # Distributed under the OSI-approved BSD License (the "License");
  98. # see accompanying file Copyright.txt for details.
  99. #
  100. # This software is distributed WITHOUT ANY WARRANTY; without even the
  101. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  102. # See the License for more information.
  103. #=============================================================================
  104. # (To distribute this file outside of CMake, substitute the full
  105. # License text for the above reference.)
  106. function(PROTOBUF_GENERATE_CPP SRCS HDRS)
  107. if(NOT ARGN)
  108. message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
  109. return()
  110. endif()
  111. if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
  112. # Create an include path for each file specified
  113. foreach(FIL ${ARGN})
  114. get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
  115. get_filename_component(ABS_PATH ${ABS_FIL} PATH)
  116. list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
  117. if(${_contains_already} EQUAL -1)
  118. list(APPEND _protobuf_include_path -I ${ABS_PATH})
  119. endif()
  120. endforeach()
  121. else()
  122. set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
  123. endif()
  124. if(DEFINED PROTOBUF_IMPORT_DIRS)
  125. foreach(DIR ${PROTOBUF_IMPORT_DIRS})
  126. get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
  127. list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
  128. if(${_contains_already} EQUAL -1)
  129. list(APPEND _protobuf_include_path -I ${ABS_PATH})
  130. endif()
  131. endforeach()
  132. endif()
  133. set(${SRCS})
  134. set(${HDRS})
  135. foreach(FIL ${ARGN})
  136. get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
  137. get_filename_component(FIL_WE ${FIL} NAME_WE)
  138. list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
  139. list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
  140. add_custom_command(
  141. OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
  142. "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
  143. COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
  144. ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
  145. DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_EXECUTABLE}
  146. COMMENT "Running C++ protocol buffer compiler on ${FIL}"
  147. VERBATIM )
  148. endforeach()
  149. set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
  150. set(${SRCS} ${${SRCS}} PARENT_SCOPE)
  151. set(${HDRS} ${${HDRS}} PARENT_SCOPE)
  152. endfunction()
  153. function(PROTOBUF_GENERATE_PYTHON SRCS)
  154. if(NOT ARGN)
  155. message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
  156. return()
  157. endif()
  158. if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
  159. # Create an include path for each file specified
  160. foreach(FIL ${ARGN})
  161. get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
  162. get_filename_component(ABS_PATH ${ABS_FIL} PATH)
  163. list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
  164. if(${_contains_already} EQUAL -1)
  165. list(APPEND _protobuf_include_path -I ${ABS_PATH})
  166. endif()
  167. endforeach()
  168. else()
  169. set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
  170. endif()
  171. if(DEFINED PROTOBUF_IMPORT_DIRS)
  172. foreach(DIR ${PROTOBUF_IMPORT_DIRS})
  173. get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
  174. list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
  175. if(${_contains_already} EQUAL -1)
  176. list(APPEND _protobuf_include_path -I ${ABS_PATH})
  177. endif()
  178. endforeach()
  179. endif()
  180. set(${SRCS})
  181. foreach(FIL ${ARGN})
  182. get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
  183. get_filename_component(FIL_WE ${FIL} NAME_WE)
  184. list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")
  185. add_custom_command(
  186. OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
  187. COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
  188. DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_EXECUTABLE}
  189. COMMENT "Running Python protocol buffer compiler on ${FIL}"
  190. VERBATIM )
  191. endforeach()
  192. set(${SRCS} ${${SRCS}} PARENT_SCOPE)
  193. endfunction()
  194. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  195. set(_PROTOBUF_ARCH_DIR x64/)
  196. endif()
  197. include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
  198. # Internal function: search for normal library as well as a debug one
  199. # if the debug one is specified also include debug/optimized keywords
  200. # in *_LIBRARIES variable
  201. function(_protobuf_find_libraries name filename)
  202. if(${name}_LIBRARIES)
  203. # Use result recorded by a previous call.
  204. return()
  205. elseif(${name}_LIBRARY)
  206. # Honor cache entry used by CMake 3.5 and lower.
  207. set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE)
  208. else()
  209. find_library(${name}_LIBRARY_RELEASE
  210. NAMES ${filename}
  211. PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
  212. mark_as_advanced(${name}_LIBRARY_RELEASE)
  213. find_library(${name}_LIBRARY_DEBUG
  214. NAMES ${filename}
  215. PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
  216. mark_as_advanced(${name}_LIBRARY_DEBUG)
  217. select_library_configurations(${name})
  218. set(${name}_LIBRARY "${${name}_LIBRARY}" PARENT_SCOPE)
  219. set(${name}_LIBRARIES "${${name}_LIBRARIES}" PARENT_SCOPE)
  220. endif()
  221. endfunction()
  222. # Internal function: find threads library
  223. function(_protobuf_find_threads)
  224. set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
  225. find_package(Threads)
  226. if(Threads_FOUND)
  227. list(APPEND PROTOBUF_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
  228. set(PROTOBUF_LIBRARIES "${PROTOBUF_LIBRARIES}" PARENT_SCOPE)
  229. endif()
  230. endfunction()
  231. #
  232. # Main.
  233. #
  234. # By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
  235. # for each directory where a proto file is referenced.
  236. if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
  237. set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
  238. endif()
  239. # Google's provided vcproj files generate libraries with a "lib"
  240. # prefix on Windows
  241. if(MSVC)
  242. set(PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
  243. set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
  244. find_path(PROTOBUF_SRC_ROOT_FOLDER protobuf.pc.in)
  245. endif()
  246. # The Protobuf library
  247. _protobuf_find_libraries(PROTOBUF protobuf)
  248. #DOC "The Google Protocol Buffers RELEASE Library"
  249. _protobuf_find_libraries(PROTOBUF_LITE protobuf-lite)
  250. # The Protobuf Protoc Library
  251. _protobuf_find_libraries(PROTOBUF_PROTOC protoc)
  252. # Restore original find library prefixes
  253. if(MSVC)
  254. set(CMAKE_FIND_LIBRARY_PREFIXES "${PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES}")
  255. endif()
  256. if(UNIX)
  257. _protobuf_find_threads()
  258. endif()
  259. # Find the include directory
  260. find_path(PROTOBUF_INCLUDE_DIR
  261. google/protobuf/service.h
  262. PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/src
  263. )
  264. mark_as_advanced(PROTOBUF_INCLUDE_DIR)
  265. # Find the protoc Executable
  266. find_program(PROTOBUF_PROTOC_EXECUTABLE
  267. NAMES protoc
  268. DOC "The Google Protocol Buffers Compiler"
  269. PATHS
  270. ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release
  271. ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug
  272. )
  273. mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE)
  274. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  275. FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf DEFAULT_MSG
  276. PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR)
  277. if(PROTOBUF_FOUND)
  278. set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR})
  279. endif()