unplugged-system/build/bazel/rules/bpf/bpf.bzl

152 lines
4.9 KiB
Python

# Copyright (C) 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
def _get_clang_cmd_output(ctx):
copts = [
"--target=bpf",
"-nostdlibinc",
"-no-canonical-prefixes",
"-O2",
]
copts.extend(ctx.attr.copts)
if ctx.attr.btf:
copts.append("-g")
includes = [
"frameworks/libs/net/common/native/bpf_headers/include/bpf",
# TODO(b/149785767): only give access to specific file with AID_* constants
"system/core/libcutils/include",
"external/musl/src/env",
ctx.label.package,
]
includes.extend(ctx.attr.absolute_includes)
system_includes = [
"bionic/libc/include",
"bionic/libc/kernel/uapi",
# The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
"bionic/libc/kernel/uapi/asm-arm64",
"bionic/libc/kernel/android/uapi",
]
toolchain = find_cpp_toolchain(ctx)
extra_features = [
"dependency_file",
"bpf_compiler_flags",
]
extra_disabled_features = [
"sdk_version_flag",
"pie",
"non_external_compiler_flags",
"common_compiler_flags",
"asm_compiler_flags",
"cpp_compiler_flags",
"c_compiler_flags",
"external_compiler_flags",
"arm_isa_arm",
"arm_isa_thumb",
"no_override_clang_global_copts",
]
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = toolchain,
requested_features = ctx.features + extra_features,
unsupported_features = ctx.disabled_features + extra_disabled_features,
)
compilation_context = []
dir_name = ctx.label.name
if ctx.attr.btf:
# If btf is true, intermediate dir ("unstripped") is added when
# clang command is executed, because ctx.actions.run used in stripped
# command does not allow the same input and output names.
# "unstripped" will be removed when strip command is executed.
dir_name = paths.join("unstripped", dir_name)
(compilation_context, compilation_outputs) = cc_common.compile(
name = dir_name,
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = toolchain,
srcs = ctx.files.srcs,
system_includes = system_includes,
includes = includes,
user_compile_flags = copts,
compilation_contexts = compilation_context,
)
return compilation_outputs.objects
def _declare_stripped_cmd_output_file(ctx, src):
file_path = paths.join("_objs", src.basename, src.basename)
return ctx.actions.declare_file(file_path)
def _get_stripped_cmd_output(ctx, srcs):
out_files = [_declare_stripped_cmd_output_file(ctx, src) for src in srcs]
args = ctx.actions.args()
args.add("--strip-unneeded")
args.add("--remove-section=.rel.BTF")
args.add("--remove-section=.rel.BTF.ext")
args.add("--remove-section=.BTF.ext")
for in_file, out_file in zip(srcs, out_files):
ctx.actions.run(
inputs = [in_file],
outputs = [out_file],
executable = ctx.executable._strip,
arguments = [args] + [in_file.path, "-o", out_file.path],
)
return out_files
def _bpf_impl(ctx):
for src in ctx.files.srcs:
if "_" in src.basename:
fail("Invalid character '_' in source name")
clang_outfiles = _get_clang_cmd_output(ctx)
if not ctx.attr.btf:
return [DefaultInfo(files = depset(clang_outfiles))]
else:
stripped_outfiles = _get_stripped_cmd_output(ctx, clang_outfiles)
return [DefaultInfo(files = depset(stripped_outfiles))]
bpf = rule(
implementation = _bpf_impl,
attrs = {
"srcs": attr.label_list(
mandatory = True,
allow_files = True,
),
"copts": attr.string_list(),
"absolute_includes": attr.string_list(),
"btf": attr.bool(
default = True,
doc = "if set to true, generate BTF debug info for maps & programs",
),
"_strip": attr.label(
cfg = "exec",
executable = True,
default = "//prebuilts/clang/host/linux-x86:llvm-strip",
allow_files = True,
),
},
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
fragments = ["cpp"],
)