Jordan Rupprecht 86f74c4d01
[bazel] Use rules_cc everywhere and reformat (#149584)
We already use cc rules from `@rules_cc//cc:defs.bzl` in a few files,
but this uses it everywhere. Done automatically by running `buildifier
--lint=fix
--warnings=native-cc-binary,native-cc-library,native-cc-test,load` over
all the files. I also ran `buildifier` once more to ensure there wasn't
any missing formatting, so that caused a few unrelated diffs.
2025-07-29 16:30:25 -05:00

311 lines
9.8 KiB
Python

# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""LLVM libc starlark rules for building individual functions."""
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@rules_cc//cc:defs.bzl", "cc_library")
load(":libc_configure_options.bzl", "LIBC_CONFIGURE_OPTIONS")
load(":libc_namespace.bzl", "LIBC_NAMESPACE")
load(":platforms.bzl", "PLATFORM_CPU_X86_64")
def libc_common_copts():
root_label = Label(":libc")
libc_include_path = paths.join(root_label.workspace_root, root_label.package)
return [
"-I" + libc_include_path,
"-I" + paths.join(libc_include_path, "include"),
"-DLIBC_NAMESPACE=" + LIBC_NAMESPACE,
]
def libc_release_copts():
copts = [
"-DLIBC_COPT_PUBLIC_PACKAGING",
# This is used to explicitly give public symbols "default" visibility.
# See src/__support/common.h for more information.
"-DLLVM_LIBC_FUNCTION_ATTR='[[gnu::visibility(\"default\")]]'",
# All other libc sources need to be compiled with "hidden" visibility.
"-fvisibility=hidden",
"-O3",
"-fno-builtin",
"-fno-lax-vector-conversions",
"-ftrivial-auto-var-init=pattern",
"-fno-omit-frame-pointer",
"-fstack-protector-strong",
]
platform_copts = selects.with_or({
PLATFORM_CPU_X86_64: ["-mno-omit-leaf-frame-pointer"],
"//conditions:default": [],
})
return copts + platform_copts
def _libc_library(name, **kwargs):
"""Internal macro to serve as a base for all other libc library rules.
Args:
name: Target name.
**kwargs: All other attributes relevant for the cc_library rule.
"""
for attr in ["copts", "local_defines"]:
if attr in kwargs:
fail("disallowed attribute: '{}' in rule: '{}'".format(attr, name))
cc_library(
name = name,
copts = libc_common_copts(),
local_defines = LIBC_CONFIGURE_OPTIONS,
linkstatic = 1,
**kwargs
)
# A convenience function which should be used to list all libc support libraries.
# Any library which does not define a public function should be listed with
# libc_support_library.
def libc_support_library(name, **kwargs):
_libc_library(name = name, **kwargs)
def libc_function(name, **kwargs):
"""Add target for a libc function.
This macro creates an internal cc_library that can be used to test this
function.
Args:
name: Target name. Typically the name of the function this target is for.
**kwargs: Other attributes relevant for a cc_library. For example, deps.
"""
# Builds "internal" library with a function, exposed as a C++ function in
# the "LIBC_NAMESPACE" namespace. This allows us to test the function in the
# presence of another libc.
_libc_library(name = name, **kwargs)
LibcLibraryInfo = provider(
"All source files and textual headers for building a particular library.",
fields = ["srcs", "textual_hdrs"],
)
def _get_libc_info_aspect_impl(
target, # @unused
ctx):
maybe_srcs = getattr(ctx.rule.attr, "srcs", [])
maybe_hdrs = getattr(ctx.rule.attr, "hdrs", [])
maybe_textual_hdrs = getattr(ctx.rule.attr, "textual_hdrs", [])
maybe_deps = getattr(ctx.rule.attr, "deps", [])
return LibcLibraryInfo(
srcs = depset(
transitive = [
dep[LibcLibraryInfo].srcs
for dep in maybe_deps
if LibcLibraryInfo in dep
] + [
src.files
for src in maybe_srcs + maybe_hdrs
],
),
textual_hdrs = depset(
transitive = [
dep[LibcLibraryInfo].textual_hdrs
for dep in maybe_deps
if LibcLibraryInfo in dep
] + [
hdr.files
for hdr in maybe_textual_hdrs
],
),
)
_get_libc_info_aspect = aspect(
implementation = _get_libc_info_aspect_impl,
attr_aspects = ["deps"],
)
def _libc_srcs_filegroup_impl(ctx):
srcs = depset(transitive = [
fn[LibcLibraryInfo].srcs
for fn in ctx.attr.libs
])
if ctx.attr.enforce_headers_only:
paths = [f.short_path for f in srcs.to_list() if f.extension != "h"]
if paths:
fail("Unexpected non-header files: {}".format(paths))
return DefaultInfo(files = srcs)
_libc_srcs_filegroup = rule(
doc = "Returns all sources for building the specified libraries.",
implementation = _libc_srcs_filegroup_impl,
attrs = {
"libs": attr.label_list(
mandatory = True,
aspects = [_get_libc_info_aspect],
),
"enforce_headers_only": attr.bool(default = False),
},
)
def _libc_textual_hdrs_filegroup_impl(ctx):
return DefaultInfo(
files = depset(transitive = [
fn[LibcLibraryInfo].textual_hdrs
for fn in ctx.attr.libs
]),
)
_libc_textual_hdrs_filegroup = rule(
doc = "Returns all textual headers for compiling the specified libraries.",
implementation = _libc_textual_hdrs_filegroup_impl,
attrs = {
"libs": attr.label_list(
mandatory = True,
aspects = [_get_libc_info_aspect],
),
},
)
def libc_release_library(
name,
libc_functions,
weak_symbols = [],
**kwargs):
"""Create the release version of a libc library.
Args:
name: Name of the cc_library target.
libc_functions: List of functions to include in the library. They should be
created by libc_function macro.
weak_symbols: List of function names that should be marked as weak symbols.
**kwargs: Other arguments relevant to cc_library.
"""
_libc_srcs_filegroup(
name = name + "_srcs",
libs = libc_functions,
)
_libc_textual_hdrs_filegroup(
name = name + "_textual_hdrs",
libs = libc_functions,
)
cc_library(
name = name + "_textual_hdr_library",
textual_hdrs = [":" + name + "_textual_hdrs"],
)
weak_attributes = [
"LLVM_LIBC_FUNCTION_ATTR_" + name + "='LLVM_LIBC_EMPTY, [[gnu::weak]]'"
for name in weak_symbols
]
cc_library(
name = name,
srcs = [":" + name + "_srcs"],
copts = libc_common_copts() + libc_release_copts(),
local_defines = weak_attributes + LIBC_CONFIGURE_OPTIONS,
deps = [
":" + name + "_textual_hdr_library",
],
**kwargs
)
def libc_header_library(name, hdrs, deps = [], **kwargs):
"""Creates a header-only library to share libc functionality.
Args:
name: Name of the cc_library target.
hdrs: List of headers to be shared.
deps: The list of libc_support_library dependencies if any.
**kwargs: All other attributes relevant for the cc_library rule.
"""
_libc_srcs_filegroup(
name = name + "_hdr_deps",
libs = deps,
enforce_headers_only = True,
)
_libc_textual_hdrs_filegroup(
name = name + "_textual_hdrs",
libs = deps,
)
cc_library(
name = name + "_textual_hdr_library",
textual_hdrs = [":" + name + "_textual_hdrs"],
)
cc_library(
name = name,
hdrs = hdrs,
# We put _hdr_deps in srcs, as they are not a part of this cc_library
# interface, but instead are used to implement shared headers.
srcs = [":" + name + "_hdr_deps"],
deps = [":" + name + "_textual_hdr_library"],
# copts don't really matter, since it's a header-only library, but we
# need proper -I flags for header validation, which are specified in
# libc_common_copts().
copts = libc_common_copts(),
**kwargs
)
def libc_generated_header(name, hdr, yaml_template, other_srcs = []):
"""Generates a libc header file from YAML template.
Args:
name: Name of the genrule target.
hdr: Path of the header file to generate.
yaml_template: Path of the YAML template file.
other_srcs: Other files required to generate the header, if any.
"""
hdrgen = "//libc:hdrgen"
cmd = "$(location {hdrgen}) $(location {yaml}) -o $@".format(
hdrgen = hdrgen,
yaml = yaml_template,
)
if not hdr.startswith("staging/"):
fail(
"Generated headers should be placed in a 'staging/' directory " +
"so that they can be treated differently from constant source files " +
"when bootstrapping builds.",
)
native.genrule(
name = name,
outs = [hdr],
srcs = [yaml_template] + other_srcs,
cmd = cmd,
tools = [hdrgen],
)
def libc_math_function(
name,
additional_deps = None):
"""Add a target for a math function.
Args:
name: The name of the function.
additional_deps: Other deps like helper cc_library targets used by the
math function.
"""
additional_deps = additional_deps or []
#TODO(michaelrj): Fix the floating point dependencies
OLD_FPUTIL_DEPS = [
":__support_fputil_basic_operations",
":__support_fputil_division_and_remainder_operations",
":__support_fputil_fenv_impl",
":__support_fputil_fp_bits",
":__support_fputil_hypot",
":__support_fputil_manipulation_functions",
":__support_fputil_nearest_integer_operations",
":__support_fputil_normal_float",
":__support_math_extras",
":__support_fputil_except_value_utils",
]
libc_function(
name = name,
srcs = ["src/math/generic/" + name + ".cpp"],
hdrs = ["src/math/" + name + ".h"],
deps = [":__support_common"] + OLD_FPUTIL_DEPS + additional_deps,
)