| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- # Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- # Exceptions. See /LICENSE for license information.
- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- """Provides variables and rules to work with Clang's runtime library sources.
- These are organized into groups based on the Clang runtimes providing them and
- how they are built:
- - CRT: The C language runtimes not provided by the C standard library, currently
- just infrastructure for global initialization and teardown.
- - Builtins: The compiler builtins library mirroring `libgcc` that provides
- function definitions for operations not reliably available in hardware but
- needed by Clang.
- - Libc++ and libc++abi: The C++ standard library and its ABI components.
- - Libunwind: The unwinding library.
- Future runtimes we plan to add support for but not yet included:
- - Sanitizers
- - Profiling runtimes
- """
- load("@llvm-project//:vars.bzl", "LLVM_VERSION_MAJOR")
- load("@llvm-project//compiler-rt:compiler-rt.bzl", "builtins_copts", "crt_copts")
- load("@llvm-project//libcxx:libcxx_library.bzl", "libcxx_and_abi_copts")
- load("@llvm-project//libunwind:libunwind_library.bzl", "libunwind_copts")
- load("//bazel/cc_rules:defs.bzl", "cc_library")
- CRT_FILES = {
- "crtbegin_src": "@llvm-project//compiler-rt:builtins_crtbegin_src",
- "crtend_src": "@llvm-project//compiler-rt:builtins_crtend_src",
- }
- BUILTINS_SRCS_FILEGROUPS = [
- "@llvm-project//compiler-rt:builtins_aarch64_srcs",
- "@llvm-project//compiler-rt:builtins_i386_srcs",
- "@llvm-project//compiler-rt:builtins_x86_64_srcs",
- ]
- BUILTINS_TEXTUAL_SRCS_FILEGROUPS = [
- "@llvm-project//compiler-rt:builtins_aarch64_textual_srcs",
- "@llvm-project//compiler-rt:builtins_i386_textual_srcs",
- "@llvm-project//compiler-rt:builtins_x86_64_textual_srcs",
- ]
- RUNTIMES_HDRS_FILEGROUPS = [
- "@llvm-project//libc:libcxx_shared_headers_hdrs",
- "@llvm-project//libcxx:libcxx_hdrs",
- "@llvm-project//libcxxabi:libcxxabi_hdrs",
- "@llvm-project//libunwind:libunwind_hdrs",
- ]
- RUNTIMES_SRCS_FILEGROUPS = [
- "@llvm-project//libcxx:libcxx_linux_srcs",
- "@llvm-project//libcxx:libcxx_macos_srcs",
- "@llvm-project//libcxx:libcxx_win32_srcs",
- "@llvm-project//libcxxabi:libcxxabi_srcs",
- "@llvm-project//libunwind:libunwind_srcs",
- ]
- RUNTIMES_TEXTUAL_SRCS_FILEGROUPS = [
- "@llvm-project//libcxxabi:libcxxabi_textual_srcs",
- ]
- RUNTIMES_PREFIXES = {
- "libcxx_hdrs": "runtimes/libcxx/",
- "libcxx_linux_srcs": "runtimes/libcxx/",
- "libcxx_macos_srcs": "runtimes/libcxx/",
- "libcxx_shared_headers_hdrs": "runtimes/libc/internal/",
- "libcxx_win32_srcs": "runtimes/libcxx/",
- "libcxxabi_hdrs": "runtimes/libcxxabi/",
- "libcxxabi_srcs": "runtimes/libcxxabi/",
- "libcxxabi_textual_srcs": "runtimes/libcxxabi/",
- "libunwind_hdrs": "runtimes/libunwind/",
- "libunwind_srcs": "runtimes/libunwind/",
- }
- def _get_name(target):
- return target.split(":")[1]
- def _format_one_per_line(list):
- return "\n" + "\n".join([
- ' "{0}",'.format(item)
- for item in list
- ]) + "\n"
- def _builtins_path(file):
- """Returns the install path for a file in CompilerRT's builtins library."""
- path = file.path
- # Skip to the relative path below the workspace root.
- path = path.rpartition(file.owner.workspace_root + "/")[2]
- # And now we can predictably remove the `compiler-rt/lib` prefix.
- path = path.removeprefix("compiler-rt/lib/")
- if not path.startswith("builtins/"):
- fail("Not a builtins-relative path for: {0}".format(file.path))
- return "runtimes/" + path
- def _runtimes_path(file):
- """Returns the install path for a file in a normal runtimes library."""
- return file.owner.name
- def _get_path(file_attr, to_path_fn):
- files = file_attr[DefaultInfo].files.to_list()
- if len(files) > 1:
- fail("Expected a single file and got {0} files.".format(len(files)))
- return '"{0}"'.format(to_path_fn(files[0]))
- def _get_paths(files_attr, to_path_fn, prefix = ""):
- files = []
- for src in files_attr:
- files.extend(src[DefaultInfo].files.to_list())
- files.extend(src[DefaultInfo].default_runfiles.files.to_list())
- return _format_one_per_line([
- "{0}{1}".format(prefix, to_path_fn(f))
- for f in files
- ])
- def _get_substitutions(ctx):
- key_attr = lambda k: getattr(ctx.attr, "_" + k)
- return {
- "BUILTINS_COPTS": _format_one_per_line(builtins_copts),
- "CRT_COPTS": _format_one_per_line(crt_copts),
- "LIBCXX_AND_ABI_COPTS": _format_one_per_line(libcxx_and_abi_copts),
- "LIBUNWIND_COPTS": _format_one_per_line(libunwind_copts),
- "LLVM_VERSION_MAJOR": LLVM_VERSION_MAJOR,
- } | {
- k.upper(): _get_path(key_attr(k), _builtins_path)
- for k in CRT_FILES.keys()
- } | {
- name.upper(): _get_paths(key_attr(name), _builtins_path)
- for name in [_get_name(g) for g in (
- BUILTINS_SRCS_FILEGROUPS + BUILTINS_TEXTUAL_SRCS_FILEGROUPS
- )]
- } | {
- # Other runtimes are installed under separate directories named the
- # same as their key.
- name.upper(): _get_paths(
- key_attr(name),
- _runtimes_path,
- RUNTIMES_PREFIXES[name],
- )
- for name in [_get_name(g) for g in (
- RUNTIMES_HDRS_FILEGROUPS + RUNTIMES_SRCS_FILEGROUPS +
- RUNTIMES_TEXTUAL_SRCS_FILEGROUPS
- )]
- }
- _common_runtimes_rule_attrs = {
- "_" + k: attr.label(default = v, allow_single_file = True)
- for k, v in CRT_FILES.items()
- } | {
- "_" + _get_name(g): attr.label_list(default = [g], allow_files = True)
- for g in (
- BUILTINS_SRCS_FILEGROUPS +
- BUILTINS_TEXTUAL_SRCS_FILEGROUPS +
- RUNTIMES_HDRS_FILEGROUPS +
- RUNTIMES_SRCS_FILEGROUPS +
- RUNTIMES_TEXTUAL_SRCS_FILEGROUPS
- )
- }
- def _generate_runtimes_build_info_h_rule(ctx):
- h_file = ctx.actions.declare_file(ctx.label.name)
- ctx.actions.expand_template(
- template = ctx.file._template_file,
- output = h_file,
- substitutions = _get_substitutions(ctx),
- )
- return [DefaultInfo(files = depset([h_file]))]
- generate_runtimes_build_info_h = rule(
- implementation = _generate_runtimes_build_info_h_rule,
- attrs = _common_runtimes_rule_attrs | {
- "_template_file": attr.label(
- default = "runtimes_build_info.tpl.h",
- allow_single_file = True,
- ),
- },
- )
- def generate_runtimes_build_info_cc_library(name, deps = [], **kwargs):
- """Generates a `runtimes_build_info.h` header and a `cc_library` rule.
- This first generates the header file with variables describing the runtimes
- build info from Clang, and then a `cc_library` that exports that header.
- The `cc_library` rule name is the provided `name` and should be depended on
- by code that includes the generated header. The `kwargs` are expanded into
- the `cc_library` in case other attributes need to be configured there.
- """
- generate_runtimes_build_info_h(name = "runtimes_build_info.h")
- cc_library(
- name = name,
- hdrs = ["runtimes_build_info.h"],
- deps = [
- # For StringRef.h
- "@llvm-project//llvm:Support",
- ] + deps,
- **kwargs
- )
- def _generate_runtimes_build_vars_rule(ctx):
- file = ctx.actions.declare_file(ctx.label.name)
- ctx.actions.expand_template(
- template = ctx.file._template_file,
- output = file,
- substitutions = _get_substitutions(ctx),
- )
- return [DefaultInfo(files = depset([file]))]
- generate_runtimes_build_vars = rule(
- implementation = _generate_runtimes_build_vars_rule,
- attrs = _common_runtimes_rule_attrs | {
- "_template_file": attr.label(
- default = "runtimes_build_vars.tpl.bzl",
- allow_single_file = True,
- ),
- },
- )
|