Skip to content

Commit

Permalink
Implement pl_bpf_preprocess as a rule instead of a genrule. (#802)
Browse files Browse the repository at this point in the history
Summary: Implements `pl_bpf_preprocess` as a rule instead of a genrule.
In order to select on the platform for choosing defines to the
preprocessing, we need this to be a fully-fledged rule instead of a
genrule.
This has the added benefit of caching the preprocessor output.

Type of change: /kind cleanup

Test Plan: Tested that the preprocessed output looks sane. Also ran
`bazel build //...`. Relying on #ci:bpf-build to test that the
preprocessed output is correct.

Signed-off-by: James Bartlett <[email protected]>
  • Loading branch information
JamesMBartlett authored Feb 7, 2023
1 parent bb10c7d commit 9834baa
Show file tree
Hide file tree
Showing 19 changed files with 184 additions and 119 deletions.
14 changes: 9 additions & 5 deletions bazel/cc_resource.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ def pl_cc_resource(
def pl_bpf_cc_resource(
name,
src,
hdrs,
syshdrs,
deps = [],
defines = [],
tags = [],
**kwargs):
out_file = pl_bpf_preprocess(name, src, hdrs, syshdrs, defines, tags = kwargs.get("tags", []))
_pl_cc_resource_with_cc_info(name, out_file, **kwargs)
pl_bpf_preprocess(
name = name + "_bpf_preprocess",
src = src,
deps = deps,
defines = defines,
**kwargs
)
_pl_cc_resource_with_cc_info(name, ":" + name + "_bpf_preprocess", **kwargs)

def _sanitize_path(path):
return "".join([c if c.isalnum() else "_" for c in path.elems()])
Expand Down
10 changes: 10 additions & 0 deletions bazel/cc_toolchains/toolchain_features.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,17 @@ def _objcopy_action(ctx):
],
)

def _cpp_action(ctx):
return action_config(
action_name = "c-preprocess",
enabled = True,
tools = [
tool(path = ctx.attr.tool_paths["cpp"]),
],
)

def pl_action_configs(ctx):
return [
_objcopy_action(ctx),
_cpp_action(ctx),
]
102 changes: 67 additions & 35 deletions bazel/pl_bpf_preprocess.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#
# SPDX-License-Identifier: Apache-2.0

load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")

# This macro preprocesses BPF C files to include any user-includes.
# It essentially does this by running the C preprocessor.
# BPF source should not, however, have system includes inlined, as that
Expand All @@ -24,43 +26,73 @@
# The mock system headers take the following form:
# file: linux/sched.h
# contents: include <linux/sched.h>
#
# @param src: The location of the BPF source code.
# @param hdrs: Any user defined headers required by the BPF program (src).
# @param syshdrs: The location of the fake system headers to bypass system includes.
# The syshdrs variable must be a path directory (i.e. not a target with a colon).
# For example, "//src/stirling/bpf_tools/bcc_bpf/system-headers",
# instead of "//src/stirling/bpf_tools/bcc_bpf/system-headers:system-headers".
# To make this work, the directory must have a BUILD.bazel with a target
# that has the same name as the directory.
# This enables automatic generation of the preprocessor -I flag internally.
def pl_bpf_preprocess(
name,
src,
hdrs,
syshdrs,
defines = [],
tags = [],
*kwargs):
out_file = name + "_bpf_preprocess"
def _pl_bpf_preprocess_impl(ctx):
if len(ctx.attr.src.files.to_list()) != 1:
fail("Must provide exactly one file to 'src' attr of pl_bpf_preprocess")

# Hacky: Extract the name of the directory by removing the leading "//".
# There might be Bazel-esque way of doing this, but since filegroups can't have $location
# applied to it, we use this hack instead.
# For more details, see note about syshdrs above.
syshdrs_dir = syshdrs[2:]
cc_toolchain = find_cpp_toolchain(ctx)

defines_str = ""
for d in defines:
defines_str += "-D" + d + " "
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)

preprocessor_tool = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = "c-preprocess",
)

cmd = "cpp -U linux {} -Dinclude=#include -I. -I{} $(location {}) -o $@".format(defines_str, syshdrs_dir, src)
output = ctx.actions.declare_file(ctx.attr.name + ".c")

native.genrule(
name = name + "_bpf_preprocess_genrule",
outs = [out_file],
srcs = [src] + hdrs + [syshdrs],
tags = tags,
cmd = cmd,
merged_cc_info = cc_common.merge_cc_infos(direct_cc_infos = [dep[CcInfo] for dep in ctx.attr.deps])
compilation_ctx = merged_cc_info.compilation_context

includes = compilation_ctx.includes.to_list() + compilation_ctx.quote_includes.to_list() + compilation_ctx.system_includes.to_list()
defines = compilation_ctx.defines.to_list() + compilation_ctx.local_defines.to_list()
defines = defines + ctx.attr.defines

args = ctx.actions.args()
args.add("-U", "linux")
args.add_all(["-D" + d for d in defines])
args.add("-Dinclude=#include")
args.add("-I.")
args.add_all(["-I" + path for path in includes])
args.add(ctx.attr.src.files.to_list()[0].path)
args.add("-o", output.path)

ctx.actions.run(
outputs = [output],
inputs = depset(
transitive = [
ctx.attr.src.files,
compilation_ctx.headers,
],
),
tools = cc_toolchain.all_files,
executable = preprocessor_tool,
arguments = [args],
mnemonic = "CPreprocess",
)
return out_file
return DefaultInfo(files = depset([output]))

pl_bpf_preprocess = rule(
implementation = _pl_bpf_preprocess_impl,
attrs = dict(
src = attr.label(
mandatory = True,
doc = "bpf file to preprocess",
allow_files = True,
),
deps = attr.label_list(
doc = "cc dependencies to take headers from",
providers = [CcInfo],
),
defines = attr.string_list(
doc = "list of defines to preprocess with",
),
),
fragments = ["cpp"],
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
)
17 changes: 10 additions & 7 deletions src/stirling/bpf_tools/bcc_bpf/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,39 @@
#
# SPDX-License-Identifier: MIT

load("@rules_cc//cc:defs.bzl", "cc_library")
load("//bazel:cc_resource.bzl", "pl_bpf_cc_resource")
load("//bazel:pl_build_system.bzl", "pl_cc_test")

package(default_visibility = [
"//src/stirling:__subpackages__",
])

filegroup(
cc_library(
name = "headers",
srcs = glob(["*.h"]),
hdrs = glob(["*.h"]),
)

# Build :task_struct_mem_read_bpf_preprocess_genrule to examine the preprocessing output.
# Build :task_struct_mem_read_bpf_preprocess to examine the preprocessing output.
pl_bpf_cc_resource(
name = "task_struct_mem_read",
src = "task_struct_mem_read.c",
hdrs = ["//src/stirling/bpf_tools/bcc_bpf_intf:headers"],
syshdrs = "//src/stirling/bpf_tools/bcc_bpf/system-headers",
deps = [
"//src/stirling/bpf_tools/bcc_bpf/system-headers",
"//src/stirling/bpf_tools/bcc_bpf_intf:headers",
],
)

pl_cc_test(
name = "utils_test",
srcs = [
"utils.h",
"utils_test.cc",
],
deps = [
"//src/stirling/bpf_tools/bcc_bpf:headers",
"//src/stirling/bpf_tools/bcc_bpf_intf:headers",
"//src/stirling/source_connectors/socket_tracer/bcc_bpf_intf:headers",
],
deps = [
"//src/stirling/utils:cc_library",
],
)
12 changes: 6 additions & 6 deletions src/stirling/bpf_tools/bcc_bpf/system-headers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@
#
# SPDX-License-Identifier: MIT

load("@rules_cc//cc:defs.bzl", "cc_library")

package(default_visibility = [
"//src/stirling:__subpackages__",
])

# We use this as a directory target, so the name must be same name as the directory.
# See bazel/pl_bpf_preprocess.bzl for a note about why this must be the case.
filegroup(
cc_library(
name = "system-headers",
srcs = glob(
["**"],
exclude = ["BUILD.bazel"],
hdrs = glob(
["**/*.h"],
),
includes = ["."],
)
11 changes: 7 additions & 4 deletions src/stirling/bpf_tools/bcc_bpf_intf/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,23 @@
#
# SPDX-License-Identifier: Apache-2.0

load("@rules_cc//cc:defs.bzl", "cc_library")
load("//bazel:pl_build_system.bzl", "pl_cc_library")

package(default_visibility = [
"//src/stirling:__subpackages__",
])

filegroup(
cc_library(
name = "headers",
srcs = glob(["*.h"]),
hdrs = glob(["*.h"]),
)

pl_cc_library(
name = "cc_library",
srcs = [],
hdrs = [":headers"],
deps = ["//src/shared/upid:cc_library"],
deps = [
":headers",
"//src/shared/upid:cc_library",
],
)
4 changes: 2 additions & 2 deletions src/stirling/bpf_tools/testdata/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ package(default_visibility = ["//src/stirling/bpf_tools:__subpackages__"])
pl_bpf_cc_resource(
name = "get_tgid_start_time",
src = "get_tgid_start_time.c",
hdrs = [
deps = [
"//src/stirling/bpf_tools/bcc_bpf:headers",
"//src/stirling/bpf_tools/bcc_bpf/system-headers",
],
syshdrs = "//src/stirling/bpf_tools/bcc_bpf/system-headers",
)

pl_cc_resource(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package(default_visibility = ["//src/stirling/source_connectors/cpu_stat_bpftrac
pl_bpf_cc_resource(
name = "cpustat",
src = "cpustat.bt",
hdrs = [],
syshdrs = "//src/stirling/bpf_tools/bcc_bpf/system-headers",
deps = [
"//src/stirling/bpf_tools/bcc_bpf/system-headers",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ load("//bazel:cc_resource.bzl", "pl_bpf_cc_resource")

package(default_visibility = ["//src/stirling:__subpackages__"])

# Build :profiler_bpf_preprocess_genrule to examine the preprocessing output.
# Build :profiler_bpf_preprocess to examine the preprocessing output.
pl_bpf_cc_resource(
name = "profiler",
src = "profiler.c",
hdrs = [
deps = [
"//src/stirling/bpf_tools/bcc_bpf:headers",
"//src/stirling/bpf_tools/bcc_bpf/system-headers",
"//src/stirling/bpf_tools/bcc_bpf_intf:headers",
"//src/stirling/source_connectors/perf_profiler/bcc_bpf_intf:headers",
"//src/stirling/upid:headers",
],
syshdrs = "//src/stirling/bpf_tools/bcc_bpf/system-headers",
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@
#
# SPDX-License-Identifier: Apache-2.0

load("@rules_cc//cc:defs.bzl", "cc_library")
load("//bazel:pl_build_system.bzl", "pl_cc_library")

package(default_visibility = ["//src/stirling:__subpackages__"])

filegroup(
cc_library(
name = "headers",
srcs = glob(["*.h"]),
hdrs = glob(["*.h"]),
)

pl_cc_library(
name = "cc_library",
srcs = [],
hdrs = [
deps = [
":headers",
"//src/stirling/bpf_tools/bcc_bpf_intf:headers",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ package(default_visibility = ["//src/stirling:__subpackages__"])
pl_bpf_cc_resource(
name = "stringifier_test_bpf_text",
src = "stringifier_test.c",
hdrs = [
deps = [
"//src/stirling/bpf_tools/bcc_bpf:headers",
"//src/stirling/bpf_tools/bcc_bpf/system-headers",
"//src/stirling/bpf_tools/bcc_bpf_intf:headers",
"//src/stirling/source_connectors/perf_profiler/bcc_bpf_intf:headers",
"//src/stirling/upid:headers",
],
syshdrs = "//src/stirling/bpf_tools/bcc_bpf/system-headers",
)
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ load("//bazel:cc_resource.bzl", "pl_bpf_cc_resource")

package(default_visibility = ["//src/stirling:__subpackages__"])

# Build :pidruntime_bpf_preprocess_genrule to examine the preprocessing output.
# Build :pidruntime_bpf_preprocess to examine the preprocessing output.
pl_bpf_cc_resource(
name = "pidruntime",
src = "pidruntime.c",
hdrs = ["//src/stirling/source_connectors/pid_runtime/bcc_bpf_intf:headers"],
syshdrs = "//src/stirling/bpf_tools/bcc_bpf/system-headers",
deps = [
"//src/stirling/bpf_tools/bcc_bpf/system-headers",
"//src/stirling/source_connectors/pid_runtime/bcc_bpf_intf:headers",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@
#
# SPDX-License-Identifier: Apache-2.0

load("@rules_cc//cc:defs.bzl", "cc_library")
load("//bazel:pl_build_system.bzl", "pl_cc_library")

package(default_visibility = ["//src/stirling:__subpackages__"])

filegroup(
cc_library(
name = "headers",
srcs = glob(["*.h"]),
hdrs = glob(["*.h"]),
)

pl_cc_library(
name = "cc_library",
srcs = [],
hdrs = [":headers"],
deps = [":headers"],
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ package(default_visibility = ["//src/stirling/source_connectors/pid_runtime_bpft
pl_bpf_cc_resource(
name = "bpftrace_pidruntime",
src = "pidruntime.bt",
hdrs = [],
syshdrs = "//src/stirling/bpf_tools/bcc_bpf/system-headers",
deps = ["//src/stirling/bpf_tools/bcc_bpf/system-headers"],
)
Loading

0 comments on commit 9834baa

Please sign in to comment.