defs.bzl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. # Copyright 2021 the V8 project authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. FlagInfo = provider(fields = ["value"])
  5. def _options_impl(ctx):
  6. return FlagInfo(value = ctx.build_setting_value)
  7. _create_option_flag = rule(
  8. implementation = _options_impl,
  9. build_setting = config.bool(flag = True),
  10. )
  11. _create_option_string = rule(
  12. implementation = _options_impl,
  13. build_setting = config.string(flag = True),
  14. )
  15. _create_option_int = rule(
  16. implementation = _options_impl,
  17. build_setting = config.int(flag = True),
  18. )
  19. def v8_flag(name, default = False):
  20. _create_option_flag(name = name, build_setting_default = default)
  21. native.config_setting(name = "is_" + name, flag_values = {name: "True"})
  22. native.config_setting(name = "is_not_" + name, flag_values = {name: "False"})
  23. def v8_string(name, default = ""):
  24. _create_option_string(name = name, build_setting_default = default)
  25. def v8_int(name, default = 0):
  26. _create_option_int(name = name, build_setting_default = default)
  27. def _custom_config_impl(ctx):
  28. defs = []
  29. defs.append("V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=" +
  30. str(ctx.attr._v8_typed_array_max_size_in_heap[FlagInfo].value))
  31. context = cc_common.create_compilation_context(defines = depset(defs))
  32. return [CcInfo(compilation_context = context)]
  33. v8_custom_config = rule(
  34. implementation = _custom_config_impl,
  35. attrs = {
  36. "_v8_typed_array_max_size_in_heap": attr.label(default = ":v8_typed_array_max_size_in_heap"),
  37. },
  38. )
  39. def _config_impl(ctx):
  40. hdrs = []
  41. # Add headers
  42. for h in ctx.attr.hdrs:
  43. hdrs += h[DefaultInfo].files.to_list()
  44. defs = []
  45. # Add conditional_defines
  46. for f, d in ctx.attr.conditional_defines.items():
  47. if f[FlagInfo].value:
  48. defs.append(d)
  49. # Add defines
  50. for d in ctx.attr.defines:
  51. defs.append(d)
  52. context = cc_common.create_compilation_context(
  53. defines = depset(
  54. defs,
  55. transitive = [dep[CcInfo].compilation_context.defines for dep in ctx.attr.deps],
  56. ),
  57. headers = depset(
  58. hdrs,
  59. transitive = [dep[CcInfo].compilation_context.headers for dep in ctx.attr.deps],
  60. ),
  61. )
  62. return [CcInfo(compilation_context = context)]
  63. v8_config = rule(
  64. implementation = _config_impl,
  65. attrs = {
  66. "conditional_defines": attr.label_keyed_string_dict(),
  67. "defines": attr.string_list(),
  68. "deps": attr.label_list(),
  69. "hdrs": attr.label_list(allow_files = True),
  70. },
  71. )
  72. def _default_args():
  73. return struct(
  74. deps = [":define_flags"],
  75. defines = select({
  76. "@v8//bazel/config:is_windows": [
  77. "UNICODE",
  78. "_UNICODE",
  79. "_CRT_RAND_S",
  80. "_WIN32_WINNT=0x0602", # Override bazel default to Windows 8
  81. ],
  82. "//conditions:default": [],
  83. }),
  84. copts = select({
  85. "@v8//bazel/config:is_posix": [
  86. "-fPIC",
  87. "-fno-strict-aliasing",
  88. "-Werror",
  89. "-Wextra",
  90. "-Wno-unknown-warning-option",
  91. "-Wno-bitwise-instead-of-logical",
  92. "-Wno-builtin-assume-aligned-alignment",
  93. "-Wno-unused-parameter",
  94. "-Wno-implicit-int-float-conversion",
  95. "-Wno-deprecated-copy",
  96. "-Wno-non-virtual-dtor",
  97. "-isystem .",
  98. ],
  99. "//conditions:default": [],
  100. }) + select({
  101. "@v8//bazel/config:is_clang": [
  102. "-Wno-invalid-offsetof",
  103. "-std=c++17",
  104. ],
  105. "@v8//bazel/config:is_gcc": [
  106. "-Wno-extra",
  107. "-Wno-array-bounds",
  108. "-Wno-class-memaccess",
  109. "-Wno-comments",
  110. "-Wno-deprecated-declarations",
  111. "-Wno-implicit-fallthrough",
  112. "-Wno-int-in-bool-context",
  113. "-Wno-maybe-uninitialized",
  114. "-Wno-mismatched-new-delete",
  115. "-Wno-redundant-move",
  116. "-Wno-return-type",
  117. "-Wno-stringop-overflow",
  118. # Use GNU dialect, because GCC doesn't allow using
  119. # ##__VA_ARGS__ when in standards-conforming mode.
  120. "-std=gnu++17",
  121. ],
  122. "@v8//bazel/config:is_windows": [
  123. "/std:c++17",
  124. ],
  125. "//conditions:default": [],
  126. }) + select({
  127. "@v8//bazel/config:is_gcc_fastbuild": [
  128. # Non-debug builds without optimizations fail because
  129. # of recursive inlining of "always_inline" functions.
  130. "-O1",
  131. ],
  132. "//conditions:default": [],
  133. }) + select({
  134. "@v8//bazel/config:is_clang_s390x": [
  135. "-fno-integrated-as",
  136. ],
  137. "//conditions:default": [],
  138. }),
  139. includes = ["include"],
  140. linkopts = select({
  141. "@v8//bazel/config:is_windows": [
  142. "Winmm.lib",
  143. "DbgHelp.lib",
  144. "Advapi32.lib",
  145. ],
  146. "@v8//bazel/config:is_macos": ["-pthread"],
  147. "//conditions:default": ["-Wl,--no-as-needed -ldl -pthread"],
  148. }) + select({
  149. ":should_add_rdynamic": ["-rdynamic"],
  150. "//conditions:default": [],
  151. }),
  152. )
  153. ENABLE_I18N_SUPPORT_DEFINES = [
  154. "-DV8_INTL_SUPPORT",
  155. "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC",
  156. # src/regexp/regexp-compiler-tonode.cc uses an unsafe ICU method and
  157. # access a character implicitly.
  158. "-DUNISTR_FROM_CHAR_EXPLICIT=",
  159. ]
  160. def _should_emit_noicu_and_icu(noicu_srcs, noicu_deps, icu_srcs, icu_deps):
  161. return noicu_srcs != [] or noicu_deps != [] or icu_srcs != [] or icu_deps != []
  162. # buildifier: disable=function-docstring
  163. def v8_binary(
  164. name,
  165. srcs,
  166. deps = [],
  167. includes = [],
  168. copts = [],
  169. linkopts = [],
  170. noicu_srcs = [],
  171. noicu_deps = [],
  172. icu_srcs = [],
  173. icu_deps = [],
  174. **kwargs):
  175. default = _default_args()
  176. if _should_emit_noicu_and_icu(noicu_srcs, noicu_deps, icu_srcs, icu_deps):
  177. native.cc_binary(
  178. name = "noicu/" + name,
  179. srcs = srcs + noicu_srcs,
  180. deps = deps + noicu_deps + default.deps,
  181. includes = includes + default.includes,
  182. copts = copts + default.copts,
  183. linkopts = linkopts + default.linkopts,
  184. **kwargs
  185. )
  186. native.cc_binary(
  187. name = "icu/" + name,
  188. srcs = srcs + icu_srcs,
  189. deps = deps + icu_deps + default.deps,
  190. includes = includes + default.includes,
  191. copts = copts + default.copts + ENABLE_I18N_SUPPORT_DEFINES,
  192. linkopts = linkopts + default.linkopts,
  193. **kwargs
  194. )
  195. else:
  196. native.cc_binary(
  197. name = name,
  198. srcs = srcs,
  199. deps = deps + default.deps,
  200. includes = includes + default.includes,
  201. copts = copts + default.copts,
  202. linkopts = linkopts + default.linkopts,
  203. **kwargs
  204. )
  205. # buildifier: disable=function-docstring
  206. def v8_library(
  207. name,
  208. srcs,
  209. deps = [],
  210. includes = [],
  211. copts = [],
  212. linkopts = [],
  213. noicu_srcs = [],
  214. noicu_deps = [],
  215. icu_srcs = [],
  216. icu_deps = [],
  217. **kwargs):
  218. default = _default_args()
  219. if _should_emit_noicu_and_icu(noicu_srcs, noicu_deps, icu_srcs, icu_deps):
  220. native.cc_library(
  221. name = name + "_noicu",
  222. srcs = srcs + noicu_srcs,
  223. deps = deps + noicu_deps + default.deps,
  224. includes = includes + default.includes,
  225. copts = copts + default.copts,
  226. linkopts = linkopts + default.linkopts,
  227. alwayslink = 1,
  228. linkstatic = 1,
  229. **kwargs
  230. )
  231. # Alias target used because of cc_library bug in bazel on windows
  232. # https://github.com/bazelbuild/bazel/issues/14237
  233. # TODO(victorgomes): Remove alias once bug is fixed
  234. native.alias(
  235. name = "noicu/" + name,
  236. actual = name + "_noicu",
  237. )
  238. native.cc_library(
  239. name = name + "_icu",
  240. srcs = srcs + icu_srcs,
  241. deps = deps + icu_deps + default.deps,
  242. includes = includes + default.includes,
  243. copts = copts + default.copts + ENABLE_I18N_SUPPORT_DEFINES,
  244. linkopts = linkopts + default.linkopts,
  245. alwayslink = 1,
  246. linkstatic = 1,
  247. **kwargs
  248. )
  249. # Alias target used because of cc_library bug in bazel on windows
  250. # https://github.com/bazelbuild/bazel/issues/14237
  251. # TODO(victorgomes): Remove alias once bug is fixed
  252. native.alias(
  253. name = "icu/" + name,
  254. actual = name + "_icu",
  255. )
  256. else:
  257. native.cc_library(
  258. name = name,
  259. srcs = srcs,
  260. deps = deps + default.deps,
  261. includes = includes + default.includes,
  262. copts = copts + default.copts,
  263. linkopts = linkopts + default.linkopts,
  264. alwayslink = 1,
  265. linkstatic = 1,
  266. **kwargs
  267. )
  268. def _torque_impl(ctx):
  269. if ctx.workspace_name == "v8":
  270. v8root = "."
  271. else:
  272. v8root = "external/v8"
  273. # Arguments
  274. args = []
  275. args += ctx.attr.args
  276. args.append("-o")
  277. args.append(ctx.bin_dir.path + "/" + v8root + "/" + ctx.attr.prefix + "/torque-generated")
  278. args.append("-strip-v8-root")
  279. args.append("-v8-root")
  280. args.append(v8root)
  281. # Sources
  282. args += [f.path for f in ctx.files.srcs]
  283. # Generate/declare output files
  284. outs = []
  285. for src in ctx.files.srcs:
  286. root, period, ext = src.path.rpartition(".")
  287. # Strip v8root
  288. if root[:len(v8root)] == v8root:
  289. root = root[len(v8root):]
  290. file = ctx.attr.prefix + "/torque-generated/" + root
  291. outs.append(ctx.actions.declare_file(file + "-tq-csa.cc"))
  292. outs.append(ctx.actions.declare_file(file + "-tq-csa.h"))
  293. outs.append(ctx.actions.declare_file(file + "-tq-inl.inc"))
  294. outs.append(ctx.actions.declare_file(file + "-tq.inc"))
  295. outs.append(ctx.actions.declare_file(file + "-tq.cc"))
  296. outs += [ctx.actions.declare_file(ctx.attr.prefix + "/torque-generated/" + f) for f in ctx.attr.extras]
  297. ctx.actions.run(
  298. outputs = outs,
  299. inputs = ctx.files.srcs,
  300. arguments = args,
  301. executable = ctx.executable.tool,
  302. mnemonic = "GenTorque",
  303. progress_message = "Generating Torque files",
  304. )
  305. return [DefaultInfo(files = depset(outs))]
  306. _v8_torque = rule(
  307. implementation = _torque_impl,
  308. # cfg = v8_target_cpu_transition,
  309. attrs = {
  310. "prefix": attr.string(mandatory = True),
  311. "srcs": attr.label_list(allow_files = True, mandatory = True),
  312. "extras": attr.string_list(),
  313. "tool": attr.label(
  314. allow_files = True,
  315. executable = True,
  316. cfg = "exec",
  317. ),
  318. "args": attr.string_list(),
  319. },
  320. )
  321. def v8_torque(name, noicu_srcs, icu_srcs, args, extras):
  322. _v8_torque(
  323. name = "noicu/" + name,
  324. prefix = "noicu",
  325. srcs = noicu_srcs,
  326. args = args,
  327. extras = extras,
  328. tool = select({
  329. "@v8//bazel/config:v8_target_is_32_bits": ":torque_non_pointer_compression",
  330. "//conditions:default": ":torque",
  331. }),
  332. )
  333. _v8_torque(
  334. name = "icu/" + name,
  335. prefix = "icu",
  336. srcs = icu_srcs,
  337. args = args,
  338. extras = extras,
  339. tool = select({
  340. "@v8//bazel/config:v8_target_is_32_bits": ":torque_non_pointer_compression",
  341. "//conditions:default": ":torque",
  342. }),
  343. )
  344. def _v8_target_cpu_transition_impl(settings, attr):
  345. # Check for an existing v8_target_cpu flag.
  346. if "@v8//bazel/config:v8_target_cpu" in settings:
  347. if settings["@v8//bazel/config:v8_target_cpu"] != "none":
  348. return
  349. # Auto-detect target architecture based on the --cpu flag.
  350. mapping = {
  351. "haswell": "x64",
  352. "k8": "x64",
  353. "x86_64": "x64",
  354. "darwin": "x64",
  355. "darwin_x86_64": "x64",
  356. "x64_windows": "x64",
  357. "x86": "ia32",
  358. "aarch64": "arm64",
  359. "arm64-v8a": "arm64",
  360. "arm": "arm64",
  361. "darwin_arm64": "arm64",
  362. "armeabi-v7a": "arm32",
  363. "s390x": "s390x",
  364. "riscv64": "riscv64",
  365. "ppc": "ppc64le",
  366. }
  367. v8_target_cpu = mapping[settings["//command_line_option:cpu"]]
  368. return {"@v8//bazel/config:v8_target_cpu": v8_target_cpu}
  369. # Set the v8_target_cpu to be the correct architecture given the cpu specified
  370. # on the command line.
  371. v8_target_cpu_transition = transition(
  372. implementation = _v8_target_cpu_transition_impl,
  373. inputs = ["@v8//bazel/config:v8_target_cpu", "//command_line_option:cpu"],
  374. outputs = ["@v8//bazel/config:v8_target_cpu"],
  375. )
  376. def _mksnapshot(ctx):
  377. outs = [
  378. ctx.actions.declare_file(ctx.attr.prefix + "/snapshot.cc"),
  379. ctx.actions.declare_file(ctx.attr.prefix + "/embedded.S"),
  380. ]
  381. ctx.actions.run(
  382. outputs = outs,
  383. inputs = [],
  384. arguments = [
  385. "--embedded_variant=Default",
  386. "--startup_src",
  387. outs[0].path,
  388. "--embedded_src",
  389. outs[1].path,
  390. ] + ctx.attr.args,
  391. executable = ctx.executable.tool,
  392. progress_message = "Running mksnapshot",
  393. )
  394. return [DefaultInfo(files = depset(outs))]
  395. _v8_mksnapshot = rule(
  396. implementation = _mksnapshot,
  397. attrs = {
  398. "args": attr.string_list(),
  399. "tool": attr.label(
  400. mandatory = True,
  401. allow_files = True,
  402. executable = True,
  403. cfg = "exec",
  404. ),
  405. "_allowlist_function_transition": attr.label(
  406. default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
  407. ),
  408. "prefix": attr.string(mandatory = True),
  409. },
  410. cfg = v8_target_cpu_transition,
  411. )
  412. def v8_mksnapshot(name, args):
  413. _v8_mksnapshot(
  414. name = "noicu/" + name,
  415. args = args,
  416. prefix = "noicu",
  417. tool = ":noicu/mksnapshot",
  418. )
  419. _v8_mksnapshot(
  420. name = "icu/" + name,
  421. args = args,
  422. prefix = "icu",
  423. tool = ":icu/mksnapshot",
  424. )
  425. def _quote(val):
  426. if val[0] == '"' and val[-1] == '"':
  427. fail("String", val, "already quoted")
  428. return '"' + val + '"'
  429. def _kv_bool_pair(k, v):
  430. return _quote(k) + ": " + v
  431. def _json(kv_pairs):
  432. content = "{"
  433. for (k, v) in kv_pairs[:-1]:
  434. content += _kv_bool_pair(k, v) + ", "
  435. (k, v) = kv_pairs[-1]
  436. content += _kv_bool_pair(k, v)
  437. content += "}\n"
  438. return content
  439. def build_config_content(cpu, icu):
  440. return _json([
  441. ("current_cpu", cpu),
  442. ("dcheck_always_on", "false"),
  443. ("is_android", "false"),
  444. ("is_asan", "false"),
  445. ("is_cfi", "false"),
  446. ("is_clang", "true"),
  447. ("is_component_build", "false"),
  448. ("is_debug", "false"),
  449. ("is_full_debug", "false"),
  450. ("is_gcov_coverage", "false"),
  451. ("is_msan", "false"),
  452. ("is_tsan", "false"),
  453. ("is_ubsan_vptr", "false"),
  454. ("target_cpu", cpu),
  455. ("v8_current_cpu", cpu),
  456. ("v8_dict_property_const_tracking", "false"),
  457. ("v8_enable_atomic_marking_state", "false"),
  458. ("v8_enable_atomic_object_field_writes", "false"),
  459. ("v8_enable_concurrent_marking", "false"),
  460. ("v8_enable_i18n_support", icu),
  461. ("v8_enable_verify_predictable", "false"),
  462. ("v8_enable_verify_csa", "false"),
  463. ("v8_enable_lite_mode", "false"),
  464. ("v8_enable_runtime_call_stats", "false"),
  465. ("v8_enable_pointer_compression", "true"),
  466. ("v8_enable_pointer_compression_shared_cage", "false"),
  467. ("v8_enable_third_party_heap", "false"),
  468. ("v8_enable_webassembly", "false"),
  469. ("v8_control_flow_integrity", "false"),
  470. ("v8_enable_single_generation", "false"),
  471. ("v8_enable_sandbox", "false"),
  472. ("v8_enable_shared_ro_heap", "false"),
  473. ("v8_target_cpu", cpu),
  474. ])
  475. # TODO(victorgomes): Create a rule (instead of a macro), that can
  476. # dynamically populate the build config.
  477. def v8_build_config(name):
  478. cpu = _quote("x64")
  479. native.genrule(
  480. name = "noicu/" + name,
  481. outs = ["noicu/" + name + ".json"],
  482. cmd = "echo '" + build_config_content(cpu, "false") + "' > \"$@\"",
  483. )
  484. native.genrule(
  485. name = "icu/" + name,
  486. outs = ["icu/" + name + ".json"],
  487. cmd = "echo '" + build_config_content(cpu, "true") + "' > \"$@\"",
  488. )