runtime_sources.bzl 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. # Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. # Exceptions. See /LICENSE for license information.
  3. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. """Provides variables and rules to work with Clang's runtime library sources.
  5. These are organized into groups based on the runtime functionality:
  6. - CRT: The C language runtimes not provided by the C standard library, currently
  7. just infrastructure for global initialization and teardown.
  8. - Builtins: The compiler builtins library mirroring `libgcc` that provides
  9. function definitions for operations not reliably available in hardware but
  10. needed by Clang.
  11. Future runtimes we plan to add support for but not yet included:
  12. - Libunwind
  13. - Libc++ and libc++abi
  14. - Sanitizers
  15. - Profiling runtimes
  16. """
  17. load("//bazel/cc_rules:defs.bzl", "cc_library")
  18. CRT_FILES = {
  19. "crtbegin_src": "@llvm-project//compiler-rt:builtins_crtbegin_src",
  20. "crtend_src": "@llvm-project//compiler-rt:builtins_crtend_src",
  21. }
  22. BUILTINS_FILEGROUPS = {
  23. "aarch64_srcs": "@llvm-project//compiler-rt:builtins_aarch64_srcs",
  24. "bf16_srcs": "@llvm-project//compiler-rt:builtins_bf16_srcs",
  25. "generic_srcs": "@llvm-project//compiler-rt:builtins_generic_srcs",
  26. "i386_srcs": "@llvm-project//compiler-rt:builtins_i386_srcs",
  27. "macos_srcs": "@llvm-project//compiler-rt:builtins_macos_atomic_srcs",
  28. "tf_srcs": "@llvm-project//compiler-rt:builtins_tf_srcs",
  29. "x86_64_srcs": "@llvm-project//compiler-rt:builtins_x86_64_srcs",
  30. "x86_arch_srcs": "@llvm-project//compiler-rt:builtins_x86_arch_srcs",
  31. "x86_fp80_srcs": "@llvm-project//compiler-rt:builtins_x86_fp80_srcs",
  32. }
  33. RUNTIMES_FILEGROUPS = {
  34. "libcxx": "@llvm-project//libcxx:libcxx_srcs",
  35. "libcxxabi": "@llvm-project//libcxxabi:libcxxabi_srcs",
  36. "libunwind": "@llvm-project//libunwind:libunwind_srcs",
  37. }
  38. _TEMPLATE = """
  39. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  40. // Exceptions. See /LICENSE for license information.
  41. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  42. //
  43. // Generated header file of strings describing the Clang runtime library source
  44. // files.
  45. //
  46. // See toolchain/driver/runtime_sources.bzl for more details.
  47. #ifndef CARBON_TOOLCHAIN_BASE_RUNTIME_SOURCES_H_
  48. #define CARBON_TOOLCHAIN_BASE_RUNTIME_SOURCES_H_
  49. #include "llvm/ADT/StringRef.h"
  50. namespace Carbon::RuntimeSources {{
  51. inline constexpr llvm::StringLiteral CrtBegin = {crtbegin_src};
  52. inline constexpr llvm::StringLiteral CrtEnd = {crtend_src};
  53. inline constexpr llvm::StringLiteral BuiltinsGenericSrcs[] = {{
  54. {generic_srcs}
  55. }};
  56. inline constexpr llvm::StringLiteral BuiltinsMacosSrcs[] = {{
  57. {macos_srcs}
  58. }};
  59. inline constexpr llvm::StringLiteral BuiltinsBf16Srcs[] = {{
  60. {bf16_srcs}
  61. }};
  62. inline constexpr llvm::StringLiteral BuiltinsTfSrcs[] = {{
  63. {tf_srcs}
  64. }};
  65. inline constexpr llvm::StringLiteral BuiltinsX86ArchSrcs[] = {{
  66. {x86_arch_srcs}
  67. }};
  68. inline constexpr llvm::StringLiteral BuiltinsX86Fp80Srcs[] = {{
  69. {x86_fp80_srcs}
  70. }};
  71. inline constexpr llvm::StringLiteral BuiltinsAarch64Srcs[] = {{
  72. {aarch64_srcs}
  73. }};
  74. inline constexpr llvm::StringLiteral BuiltinsX86_64Srcs[] = {{
  75. {x86_64_srcs}
  76. }};
  77. inline constexpr llvm::StringLiteral BuiltinsI386Srcs[] = {{
  78. {i386_srcs}
  79. }};
  80. constexpr inline llvm::StringLiteral LibcxxSrcs[] = {{
  81. {libcxx}
  82. }};
  83. constexpr inline llvm::StringLiteral LibcxxabiSrcs[] = {{
  84. {libcxxabi}
  85. }};
  86. constexpr inline llvm::StringLiteral LibunwindSrcs[] = {{
  87. {libunwind}
  88. }};
  89. }} // namespace Carbon::RuntimeSources
  90. #endif // CARBON_TOOLCHAIN_BASE_RUNTIME_SOURCES_H_
  91. """
  92. def _builtins_path(file):
  93. """Returns the runtime install path for a file in CompilerRT's builtins library."""
  94. # The CompilerRT package has the builtins runtime sources in the
  95. # "lib/builtins/" subdirectory, and we install into a "builtins/"
  96. # subdirectory, so just remove the "lib/" prefix from the package-relative
  97. # label name.
  98. return file.owner.name.removeprefix("lib/")
  99. def _runtimes_path(file):
  100. """Returns the runtime install path for a file in a normal runtimes library."""
  101. return file.owner.name
  102. def _get_path(file_attr, to_path_fn):
  103. files = file_attr[DefaultInfo].files.to_list()
  104. if len(files) > 1:
  105. fail(msg = "Expected a single file and got {0} files.".format(len(files)))
  106. return '"{0}"'.format(to_path_fn(files[0]))
  107. def _get_paths(files_attr, to_path_fn, prefix = ""):
  108. files = []
  109. for src in files_attr:
  110. files.extend(src[DefaultInfo].files.to_list())
  111. files.extend(src[DefaultInfo].default_runfiles.files.to_list())
  112. return "\n".join([
  113. ' "{0}{1}",'.format(prefix, to_path_fn(f))
  114. for f in files
  115. ])
  116. def _generate_runtime_sources_h_rule(ctx):
  117. h_file = ctx.actions.declare_file(ctx.label.name)
  118. ctx.actions.write(h_file, _TEMPLATE.format(**({
  119. k: _get_path(getattr(ctx.attr, "_" + k), _builtins_path)
  120. for k in CRT_FILES.keys()
  121. } | {
  122. k: _get_paths(getattr(ctx.attr, "_" + k), _builtins_path)
  123. for k in BUILTINS_FILEGROUPS.keys()
  124. } | {
  125. # Other runtimes are installed under separate directories named the same
  126. # as their key.
  127. k: _get_paths(getattr(ctx.attr, "_" + k), _runtimes_path, k + "/")
  128. for k in RUNTIMES_FILEGROUPS.keys()
  129. })))
  130. return [DefaultInfo(files = depset([h_file]))]
  131. generate_runtime_sources_h = rule(
  132. implementation = _generate_runtime_sources_h_rule,
  133. attrs = {
  134. "_" + k: attr.label(default = v, allow_single_file = True)
  135. for k, v in CRT_FILES.items()
  136. } | {
  137. "_" + k: attr.label_list(default = [v], allow_files = True)
  138. for k, v in BUILTINS_FILEGROUPS.items() + RUNTIMES_FILEGROUPS.items()
  139. } | {
  140. },
  141. )
  142. def generate_runtime_sources_cc_library(name, deps = [], **kwargs):
  143. """Generates a `runtime_sources.h` header and a `cc_library` rule for it.
  144. This first generates the header file with variables describing the runtime
  145. sources from Clang, and then a `cc_library` that exports that header.
  146. The `cc_library` rule name is the provided `name` and should be depended on
  147. by code that includes the generated header. The `kwargs` are expanded into
  148. the `cc_library` in case other attributes need to be configured there.
  149. """
  150. generate_runtime_sources_h(name = "runtime_sources.h")
  151. cc_library(
  152. name = name,
  153. hdrs = ["runtime_sources.h"],
  154. deps = [
  155. # For StringRef.h
  156. "@llvm-project//llvm:Support",
  157. ] + deps,
  158. **kwargs
  159. )