__init__.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import os
  2. import os.path
  3. from devtools.yamaker import fileutil
  4. from devtools.yamaker import pathutil
  5. from devtools.yamaker.arcpath import ArcPath
  6. from devtools.yamaker.modules import Linkable, Switch
  7. from devtools.yamaker.project import CMakeNinjaNixProject
  8. def make_full_path(src):
  9. return os.path.join("src/google/protobuf", src)
  10. RUNTIME_EXCESS_SOURCES = [
  11. "src/google/protobuf/compiler/importer.cc",
  12. "src/google/protobuf/compiler/parser.cc",
  13. ]
  14. RUNTIME_YANDEX_SPECIFIC_SOURCES = [
  15. "src/google/protobuf/json_util.cc",
  16. "src/google/protobuf/messagext.cc",
  17. ]
  18. # This stubs are deprecated, will removed after protobuf update
  19. DEPRECATED_STUBS = [
  20. "src/google/protobuf/stubs/hash.h",
  21. "src/google/protobuf/stubs/stl_util.h",
  22. "src/google/protobuf/stubs/stringpiece.cc",
  23. "src/google/protobuf/stubs/stringpiece.h",
  24. "src/google/protobuf/stubs/strutil.cc",
  25. "src/google/protobuf/stubs/strutil.h",
  26. "src/google/protobuf/stubs/status.cc",
  27. "src/google/protobuf/stubs/status.h",
  28. "src/google/protobuf/stubs/substitute.cc",
  29. "src/google/protobuf/stubs/substitute.h",
  30. "src/google/protobuf/stubs/map_util.h",
  31. "src/google/protobuf/stubs/structurally_valid.cc",
  32. "src/google/protobuf/util/json_util.h",
  33. "src/google/protobuf/json/old_json.cc",
  34. "src/google/protobuf/json_util.cc",
  35. "src/google/protobuf/json_util.h",
  36. ]
  37. DEPRECATED_SRC = [x for x in DEPRECATED_STUBS if x.endswith(".cc")]
  38. # Set of proto files coming with original google protobuf (excluding descriptor.proto, see below)
  39. # WARN: upon changing this file, make sure to check protobuf_std counterpart.
  40. RUNTIME_PROTO_FILES = [
  41. "src/google/protobuf/any.proto",
  42. "src/google/protobuf/api.proto",
  43. "src/google/protobuf/descriptor.proto",
  44. "src/google/protobuf/duration.proto",
  45. "src/google/protobuf/empty.proto",
  46. "src/google/protobuf/field_mask.proto",
  47. "src/google/protobuf/source_context.proto",
  48. "src/google/protobuf/struct.proto",
  49. "src/google/protobuf/timestamp.proto",
  50. "src/google/protobuf/type.proto",
  51. "src/google/protobuf/wrappers.proto",
  52. ]
  53. PROTOC_PROTO_FILES = [
  54. "src/google/protobuf/compiler/plugin.proto",
  55. ]
  56. LIBPROTOC_DIR = "contrib/libs/protoc"
  57. PYTHON_DIR = "contrib/python/protobuf/py3"
  58. POSSIBLE_STD_STRING_USAGE_PATTERNS = [
  59. # It can be referenced to as `::std::string` or `std::string`
  60. r"::std::string",
  61. r"\bstd::string\b",
  62. ]
  63. def post_build(self):
  64. # Replace std::string with TProtoStringType.
  65. for pattern in POSSIBLE_STD_STRING_USAGE_PATTERNS:
  66. fileutil.re_sub_dir(
  67. self.dstdir,
  68. pattern,
  69. "TProtoStringType",
  70. # Only apply replacements to C++ code
  71. test=pathutil.is_preprocessable,
  72. )
  73. def post_install(self):
  74. with self.yamakes["."] as libprotobuf:
  75. libprotobuf.PROVIDES = ["protobuf"]
  76. libprotobuf.SRCS.update(RUNTIME_YANDEX_SPECIFIC_SOURCES)
  77. libprotobuf.SRCS.update(DEPRECATED_SRC) # This files should be removed after protobuf update
  78. libprotobuf.NO_UTIL = False
  79. # Work around fixed_address_empty_string initialization on macOS.
  80. gmu = "src/google/protobuf/generated_message_util.cc"
  81. libprotobuf.SRCS.remove(gmu)
  82. libprotobuf.SRCS.add(ArcPath(gmu, GLOBAL=True))
  83. # These sources are parts of protoc, they should not be linked into runtime
  84. for src in RUNTIME_EXCESS_SOURCES:
  85. libprotobuf.SRCS.remove(src)
  86. libprotobuf.after(
  87. "CFLAGS",
  88. Switch(
  89. OS_ANDROID=Linkable(
  90. # Link with system android log library
  91. # Android logging is used in stubs/common.cc
  92. EXTRALIBS=["log"]
  93. )
  94. ),
  95. )
  96. libprotobuf.after("SRCS", Linkable(FILES=RUNTIME_PROTO_FILES))
  97. libprotobuf.after(
  98. "ORIGINAL_SOURCE",
  99. """IF (OPENSOURCE_REPLACE_PROTOBUF AND EXPORT_CMAKE)
  100. OPENSOURCE_EXPORT_REPLACEMENT(
  101. CMAKE Protobuf
  102. CMAKE_TARGET protobuf::libprotobuf protobuf::libprotoc
  103. CONAN protobuf/${OPENSOURCE_REPLACE_PROTOBUF}
  104. CONAN_ADDITIONAL_SEMS
  105. "&& conan_require_tool" protobuf/${OPENSOURCE_REPLACE_PROTOBUF} "&& conan-tool_requires" protobuf/${OPENSOURCE_REPLACE_PROTOBUF}
  106. "&& conan_import \\"bin, protoc* -> ./bin\\" && conan-imports 'bin, protoc* -> ./bin' && vanilla_protobuf"
  107. )
  108. ELSE()
  109. ADDINCL(
  110. GLOBAL contrib/libs/protobuf/src
  111. GLOBAL FOR proto contrib/libs/protobuf/src
  112. )
  113. ENDIF()
  114. """,
  115. )
  116. libprotobuf.ADDINCL = ["contrib/libs/protobuf/third_party/utf8_range"]
  117. libprotobuf.SRCS.add("third_party/utf8_range/utf8_validity.cc")
  118. libprotobuf.RECURSE = ["builtin_proto"]
  119. libprotobuf.PEERDIR.add("library/cpp/sanitizer/include")
  120. # Dont use full y_absl library
  121. # fmt: off
  122. libprotobuf.PEERDIR = set([
  123. lib for lib in libprotobuf.PEERDIR
  124. if 'abseil-cpp-tstring' not in lib
  125. ])
  126. # fmt: on
  127. libprotobuf.PEERDIR.add("contrib/restricted/abseil-cpp-tstring/y_absl/status")
  128. libprotobuf.PEERDIR.add("contrib/restricted/abseil-cpp-tstring/y_absl/log")
  129. del self.yamakes["src/google/protobuf/compiler"]
  130. # merging src/google/protobuf/compiler/protoc library and
  131. # src/google/protobuf/compiler binary into top-level binary
  132. with self.yamakes.pop("src/google/protobuf/compiler/protoc") as libprotoc:
  133. libprotoc.VERSION = self.version
  134. libprotoc.ORIGINAL_SOURCE = self.source_url
  135. libprotoc.PROVIDES = ["protoc"]
  136. libprotoc.after("LICENSE", "LICENSE_TEXTS(.yandex_meta/licenses.list.txt)\n")
  137. libprotoc.after(
  138. "ORIGINAL_SOURCE",
  139. """IF (OPENSOURCE_REPLACE_PROTOBUF AND EXPORT_CMAKE)
  140. OPENSOURCE_EXPORT_REPLACEMENT(
  141. CMAKE Protobuf
  142. CMAKE_TARGET protobuf::libprotobuf protobuf::libprotoc
  143. CONAN protobuf/${OPENSOURCE_REPLACE_PROTOBUF}
  144. CONAN_ADDITIONAL_SEMS
  145. "&& conan_require_tool" protobuf/${OPENSOURCE_REPLACE_PROTOBUF} "&& conan-tool_requires" protobuf/${OPENSOURCE_REPLACE_PROTOBUF}
  146. "&& conan_import \\"bin, protoc* -> ./bin\\" && conan-imports 'bin, protoc* -> ./bin' && vanilla_protobuf"
  147. )
  148. ELSE()
  149. ADDINCL(
  150. GLOBAL contrib/libs/protoc/src
  151. )
  152. ENDIF()
  153. """,
  154. )
  155. libprotoc.ADDINCL = ["contrib/libs/protobuf/third_party/utf8_range"]
  156. libprotoc.SRCS = {os.path.join("src/google/protobuf/compiler", src) for src in libprotoc.SRCS}
  157. # Moving a couple of sources from runtime library to compiler (where they actually belong)
  158. libprotoc.SRCS.update(RUNTIME_EXCESS_SOURCES)
  159. libprotoc.SRCDIR = None
  160. # Unbundle libprotobuf.la which confuses yamaker by being linked statically
  161. libprotoc.PEERDIR = {self.arcdir}
  162. libprotoc_abs_dir = os.path.join(self.ctx.arc, LIBPROTOC_DIR)
  163. fileutil.copy(
  164. os.path.join(self.dstdir, "src/google/protobuf/compiler"),
  165. os.path.join(libprotoc_abs_dir, "src/google/protobuf"),
  166. replace=True,
  167. move=True,
  168. )
  169. fileutil.copy(
  170. [os.path.join(self.dstdir, "LICENSE")],
  171. libprotoc_abs_dir,
  172. replace=True,
  173. move=False,
  174. )
  175. for lang in ["csharp", "objectivec"]:
  176. for root, _, files in os.walk(os.path.join(libprotoc_abs_dir, "src/google/protobuf/compiler", lang)):
  177. for file in files:
  178. if file.endswith(".h"):
  179. with open(os.path.join(root, lang + "_" + file), "w") as f:
  180. f.write(f'#include "{file}"\n')
  181. f.write('#include "names.h"')
  182. with open(f"{libprotoc_abs_dir}/ya.make", "wt") as ymake:
  183. ymake.write(str(libprotoc))
  184. with open(os.path.join(self.ctx.arc, self.arcdir, "src/google/protobuf/util/json_util.h"), "w") as f:
  185. f.write('#define USE_DEPRECATED_NAMESPACE 1\n#include "google/protobuf/json/json.h"')
  186. protobuf = CMakeNinjaNixProject(
  187. owners=["g:cpp-committee", "g:cpp-contrib"],
  188. arcdir="contrib/libs/protobuf",
  189. nixattr="protobuf",
  190. license_analysis_extra_dirs=[
  191. LIBPROTOC_DIR,
  192. ],
  193. install_targets=[
  194. # Do not install protobuf lite, as nobody needs it
  195. "protobuf",
  196. # Specifying protoc will install both libprotoc and protoc executable
  197. "protoc",
  198. ],
  199. unbundle_from={"abseil-cpp": "third_party/abseil-cpp"},
  200. put={"protobuf": "."},
  201. disable_includes=[
  202. "sys/isa_defs.h",
  203. ],
  204. keep_paths=[
  205. # ya.make generation for legacy PACKAGE at protobuf/python/ya.make is not configure by yamaker.
  206. "python/ya.make",
  207. # built-in protobufs need to be exposed via PROTO_LIBRARY.
  208. # Needed at least for Python and for complete descriptors generation
  209. "builtin_proto",
  210. # yandex-specific files. Should be moved out of the project, if possible
  211. "src/google/protobuf/messagext.*",
  212. *DEPRECATED_STUBS,
  213. ],
  214. copy_sources=(
  215. RUNTIME_PROTO_FILES
  216. + PROTOC_PROTO_FILES
  217. + [
  218. # java_names.h is required by contrib/libs/grpc-java
  219. "src/google/protobuf/compiler/java/java_names.h",
  220. ]
  221. ),
  222. post_build=post_build,
  223. post_install=post_install,
  224. )