Skip to content

Commit 61fdef4

Browse files
authored
refactor(ebpf): add Bazel convenience targets, remove Python verification glue (#48667)
### What does this PR do? Migrates runtime compilation bundles from Ninja to Bazel, adds central convenience targets, and removes Python verification glue code. **Runtime compilation bundle migration (Ninja → Bazel):** - Introduces `runtime_compilation_bundle` macro in `bazel/rules/ebpf/runtime_compilation.bzl` that chains `include_headers` → `integrity` to produce flattened `.c` files and Go integrity hash `.go` files. - Removes `ninja_runtime_compilation_files()` and its Ninja rules (`headerincl`, `integrity`, `rctool`) from `tasks/system_probe.py`. The Linux branch of `ninja_generate()` is now a no-op — runtime compilation is fully handled by Bazel. - Expands `bazel_build_ebpf()` to build `_BAZEL_RUNTIME_FLAT_TARGETS` and `_BAZEL_RUNTIME_GEN_TARGETS`, then copies flattened `.c` files to `pkg/ebpf/bytecode/build/runtime/` and `.go` hash files to `pkg/ebpf/bytecode/runtime/`. - Updates `save_build_outputs()` to include both flattened `.c` files and `.go` hash files in the CI tarball artifact, so omnibus `go build` and packaging can find them. - Keeps `go:generate` directives in the 9 source files as a fallback for `go build` users. **Convenience targets:** - **`//pkg/ebpf:all_ebpf_programs`** — a `filegroup` that collects every eBPF `.o` (prebuilt, CO-RE, inplace) and runtime flattened `.c` file, enabling a single `bazel build` invocation for all eBPF artifacts. - **`//pkg/ebpf:verify_generated_files`** — a `test_suite` aggregating all `write_source_file` diff tests (Linux/Windows cgo godefs), runnable with a single `bazel test` command. **Python glue removal:** - Removed `_BAZEL_CGO_GODEFS_TARGETS`, `_BAZEL_CGO_GODEFS_WIN_TARGETS`, and `_bazel_verify_cgo_godefs()` / `_godefs_test_targets()` helper functions from `tasks/system_probe.py` (~60 lines). - Replaced inline verification in `build_object_files()` with a single `bazel test //pkg/ebpf:verify_generated_files` call that works on both Linux and Windows. - Added the same verification call in `build_cws_object_files()` and `kmt.build_object_files()`. **Macro visibility cleanup:** - All three eBPF macros (`ebpf_prog`, `ebpf_program_suite`, `cgo_godefs`, `runtime_compilation_bundle`) now pass `visibility` through from callers instead of hardcoding `["//visibility:public"]`. All ~60 callsites explicitly set `visibility = ["//visibility:public"]`. - Set `--skip_incompatible_explicit_targets` globally in `.bazelrc` so `target_compatible_with` silently skips platform-incompatible targets. ### Motivation The Python orchestration in `tasks/system_probe.py` maintained ~100 lines of target lists and helper functions for both cgo godefs verification and runtime compilation. This was fragile (target lists had to stay in sync with BUILD files) and was the last remaining Ninja workload on Linux. Moving verification into a Bazel `test_suite` and runtime compilation into a Bazel macro: - Eliminates the Ninja dependency for Linux runtime compilation builds - Eliminates a class of sync bugs between Python and Bazel - Reduces Python glue code as part of the broader effort to minimize invoke task complexity - Gives developers simple one-liner commands for common workflows ### Describe how you validated your changes - Verified `bazel query` resolves both new targets and all their transitive dependencies - Confirmed `--skip_incompatible_explicit_targets` correctly skips Linux-only targets on macOS without errors - CI: buildifier, eBPF object builds, cgo godefs verification, omnibus packaging, and KMT functional tests all pass - KMT `TestGRPCScenarios/runtime_compiled` exercises runtime compilation end-to-end (flattened `.c` → clang compile → eBPF load) — confirms Bazel-produced bundles work correctly ### Additional Notes The `_BAZEL_EBPF_INPLACE_TARGETS`, `_BAZEL_EBPF_CORE_TARGETS`, and `_BAZEL_EBPF_PREBUILT_TARGETS` Python lists in `tasks/system_probe.py` remain — they drive the `_copy_output` logic that maps Bazel outputs to specific staging directories with `.stripped` variant handling, which a simple `filegroup` cannot express. Removing those requires a different approach (e.g., `pkg_install` rules or a Bazel run target that does the copying). Runtime compilation hash `.go` files remain `.gitignore`d — they are generated by Bazel during the build and copied to the source tree, but not committed. To update them locally: `bazel run //pkg/ebpf/bytecode:<name>_verify`. Co-authored-by: joseph.gette <joseph.gette@datadoghq.com>
1 parent 94bc64e commit 61fdef4

44 files changed

Lines changed: 424 additions & 178 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.bazelrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ common --experimental_disk_cache_gc_max_size=5G # Cap applied whenever --disk_ca
2020
common --experimental_ui_max_stdouterr_bytes=1073741819 # why?
2121
common --http_timeout_scaling=3.0 # At least one attempt reaches 30s (3,6,12,24,30,30,30,30) instead of only 10s (1,2,4,8,10,10,10,10)
2222
common --incompatible_strict_action_env # Do not leak local environment variables into the build context
23+
common --skip_incompatible_explicit_targets # Let target_compatible_with skip rather than fail
2324
common --test_output=errors # Print test errors to console output instead of only capturing them in buried test.log
2425
common --verbose_failures
2526

AGENTS.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,39 @@ The development configuration file should be placed at `dev/dist/datadog.yaml`.
108108
- See `pkg/collector/corechecks/ebpf/AGENTS.md` for detailed structure
109109
- Quick reference: `.cursor/rules/system_probe_modules.mdc` for common patterns and pitfalls
110110

111+
### eBPF Bazel Build
112+
113+
eBPF programs, runtime compilation bundles, and cgo godefs type definitions
114+
are built with Bazel. Two convenience targets in `pkg/ebpf/BUILD.bazel`
115+
cover the most common workflows:
116+
117+
```bash
118+
# Build every eBPF .o program and runtime flattened .c file at once
119+
bazel build //pkg/ebpf:all_ebpf_programs
120+
121+
# Verify all committed cgo godefs files are up to date.
122+
# Covers both Linux and Windows targets; incompatible tests are
123+
# skipped automatically via target_compatible_with.
124+
bazel test //pkg/ebpf:verify_generated_files
125+
```
126+
127+
When a `verify_generated_files` test fails, run the corresponding
128+
`write_source_file` target to update the committed file:
129+
130+
```bash
131+
# Update a single cgo godefs output
132+
bazel run //pkg/ebpf:types_godefs
133+
```
134+
135+
Runtime compilation integrity hash files (`pkg/ebpf/bytecode/runtime/*.go`) are
136+
`.gitignored` and generated during the build by `bazel_build_ebpf()`. To update
137+
one locally: `bazel run //pkg/ebpf/bytecode:<name>_verify`.
138+
139+
Key Bazel macros:
140+
- `ebpf_prog` / `ebpf_program_suite` (`bazel/rules/ebpf/ebpf.bzl`) — compile `.c``.o`
141+
- `cgo_godefs` (`bazel/rules/ebpf/cgo_godefs.bzl`) — `go tool cgo -godefs` + `write_source_file` verification
142+
- `runtime_compilation_bundle` (`bazel/rules/ebpf/runtime_compilation.bzl`) — flatten headers + generate integrity hash `.go` file
143+
111144
## Testing Strategy
112145

113146
### Unit Tests

bazel/rules/ebpf/cgo_godefs.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def _cgo_godefs_macro_impl(name, visibility, src, deps, hdrs, platform):
188188
)
189189
write_source_file(
190190
name = name + "_test_file",
191+
visibility = visibility,
191192
in_file = ":" + name + "_test_out",
192193
out_file = test_file,
193194
check_that_out_file_exists = False,

bazel/rules/ebpf/runtime_compilation.bzl

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1-
"""Macro for generating runtime compilation bundles (flattened .c + integrity hash .go)."""
1+
"""Macro for generating runtime compilation bundles (flattened .c + integrity hash .go).
2+
3+
Each bundle produces a flattened .c file (build artifact, not committed) and an
4+
integrity hash .go file. When out_go_file is set, a write_source_file target
5+
is emitted so ``bazel test //<pkg>:<name>_verify_test`` checks the committed
6+
hash file and ``bazel run //<pkg>:<name>_verify`` updates it.
7+
"""
28

39
load("@bazel_lib//lib:run_binary.bzl", "run_binary")
10+
load("@bazel_lib//lib:write_source_files.bzl", "write_source_file")
411

5-
def _runtime_compilation_bundle_impl(name, visibility, src_c, out_name, include_dirs, header_deps):
12+
def _runtime_compilation_bundle_impl(name, visibility, src_c, out_name, include_dirs, header_deps, out_go_file):
613
flat_name = "{}_flat".format(name)
714
run_binary(
815
name = flat_name,
16+
visibility = visibility,
917
tool = "//pkg/ebpf:include_headers",
1018
srcs = [src_c] + header_deps,
1119
outs = ["{}/{}.c".format(name, out_name)],
@@ -33,21 +41,34 @@ def _runtime_compilation_bundle_impl(name, visibility, src_c, out_name, include_
3341
# redundant `import "…/runtime"` and qualifies newAsset as runtime.newAsset.
3442
# Inside a Bazel sandbox the paths never match, so strip the bogus import
3543
# and prefix to keep the output identical to the ninja/go-generate build.
44+
gen_name = "{}_gen".format(name)
3645
native.genrule(
37-
name = name,
46+
name = gen_name,
3847
srcs = [":{}".format(raw_name)],
3948
outs = ["{}/{}.go".format(name, out_name)],
4049
cmd = "sed -e '/^import \"github.com\\/DataDog\\/datadog-agent\\/pkg\\/ebpf\\/bytecode\\/runtime\"/d' -e 's/runtime\\.newAsset/newAsset/g' $< > $@",
4150
visibility = visibility,
4251
)
4352

53+
if out_go_file:
54+
write_source_file(
55+
name = "{}_verify".format(name),
56+
visibility = visibility,
57+
in_file = ":{}".format(gen_name),
58+
out_file = out_go_file,
59+
check_that_out_file_exists = False,
60+
# Out files are .gitignored; tag as manual so bazel test //... skips them.
61+
tags = ["manual"],
62+
)
63+
4464
runtime_compilation_bundle = macro(
4565
doc = "Chains include_headers and integrity to produce a runtime compilation bundle.",
4666
attrs = {
4767
"src_c": attr.label(mandatory = True, allow_single_file = [".c"], configurable = False),
4868
"out_name": attr.string(mandatory = True, configurable = False),
4969
"include_dirs": attr.string_list(mandatory = True, configurable = False),
5070
"header_deps": attr.label_list(mandatory = True, configurable = False),
71+
"out_go_file": attr.label(mandatory = False, allow_single_file = [".go"], configurable = False),
5172
},
5273
implementation = _runtime_compilation_bundle_impl,
5374
)

cmd/system-probe/subcommands/ebpf/testdata/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ ebpf_prog(
88
"-g",
99
"-DDEBUG=1",
1010
],
11+
visibility = ["//visibility:public"],
1112
deps = ["//pkg/ebpf/c:ebpf_c_headers"],
1213
)

pkg/collector/corechecks/ebpf/AGENTS.md

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -84,25 +84,32 @@ if enabled := pkgconfigsetup.SystemProbe().GetBool("<check_name>.enabled"); enab
8484

8585
### 9. Register eBPF Programs in Build System
8686

87-
eBPF programs and CGO type generation are managed by **Bazel**. Runtime
88-
compilation bundles are still generated by **ninja** (via `ninja_runtime_compilation_files`).
89-
90-
**Add the eBPF CO-RE program** in the check's `BUILD.bazel` using the
91-
`ebpf_co_re_program` rule (see existing targets in `pkg/collector/corechecks/ebpf/c/runtime/`).
92-
Then add the Bazel target to `_BAZEL_EBPF_CORE_TARGETS` (or the appropriate
93-
list) in `tasks/system_probe.py`.
94-
95-
**Add runtime compilation support** in `ninja_runtime_compilation_files()` in
96-
`tasks/system_probe.py`:
87+
eBPF programs, CGO type generation, and runtime compilation bundles are all
88+
managed by **Bazel**.
89+
90+
**Add the eBPF CO-RE program** in the check's `c/runtime/BUILD.bazel` using
91+
`ebpf_program_suite` (see existing targets in
92+
`pkg/collector/corechecks/ebpf/c/runtime/BUILD.bazel`). Then:
93+
1. Add the target to `_BAZEL_EBPF_CORE_TARGETS` in `tasks/system_probe.py`
94+
(needed for the copy step that stages `.o` files).
95+
2. Add it to the `all_ebpf_programs` filegroup in `pkg/ebpf/BUILD.bazel`.
96+
97+
**Add runtime compilation support** by creating a `runtime_compilation_bundle`
98+
target in `pkg/ebpf/bytecode/BUILD.bazel`:
9799
```python
98-
runtime_compiler_files = {
99-
# ... existing entries
100-
"pkg/collector/corechecks/ebpf/probe/<check>/<check>.go": "<check-name>",
101-
}
100+
runtime_compilation_bundle(
101+
name = "<check-name>",
102+
header_deps = _CORECHECK_HEADERS,
103+
include_dirs = ["pkg/ebpf/c"],
104+
out_go_file = "//pkg/ebpf/bytecode/runtime:<check-name>.go",
105+
out_name = "<check-name>",
106+
src_c = "//pkg/collector/corechecks/ebpf/c/runtime:<check-name>-kern.c",
107+
)
102108
```
103-
- This enables runtime compilation fallback when CO-RE isn't available
104-
- The key is the Go file with `//go:generate` directives
105-
- The value is the base name for generated C and Go files
109+
Then add the `_flat` target to `_BAZEL_RUNTIME_FLAT_TARGETS` in
110+
`tasks/system_probe.py` and both the `_flat` and `_verify_test` targets to the
111+
convenience targets in `pkg/ebpf/BUILD.bazel` (`all_ebpf_programs` and
112+
`verify_generated_files` respectively).
106113

107114
**Add CGO type generation** by creating a `cgo_godefs` target in the check's
108115
`BUILD.bazel`:
@@ -116,16 +123,13 @@ cgo_godefs(
116123
src = "<check>_kern_types.go",
117124
)
118125
```
119-
Then add the `_gen` target to `_BAZEL_CGO_GODEFS_TARGETS` in `tasks/system_probe.py`:
120-
```python
121-
_BAZEL_CGO_GODEFS_TARGETS = [
122-
# ... existing entries
123-
"//pkg/collector/corechecks/ebpf/probe/<check>:<check>_kern_types_godefs_gen",
124-
]
125-
```
126+
Then add the `_test` and `_test_file_test` targets to the
127+
`verify_generated_files` test suite in `pkg/ebpf/BUILD.bazel`.
128+
126129
- Generates Go types from C structs for BPF map keys/values
127130
- Header file must use `__u32`, `__u64` etc. types and include `ktypes.h`
128-
- Use `bazel test` to verify committed files match, `bazel run` to regenerate
131+
- `bazel test //pkg/ebpf:verify_generated_files` checks all committed files
132+
- `bazel run //<pkg>:<name>_godefs` regenerates a single output
129133

130134
## Building
131135

pkg/collector/corechecks/ebpf/c/runtime/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ebpf_program_suite(
2525
name = "oom-kill",
2626
src = "oom-kill-kern.c",
2727
core = True,
28+
visibility = ["//visibility:public"],
2829
deps = [
2930
":corecheck_ebpf_headers",
3031
"//pkg/ebpf/c:ebpf_c_headers",
@@ -35,6 +36,7 @@ ebpf_program_suite(
3536
name = "tcp-queue-length",
3637
src = "tcp-queue-length-kern.c",
3738
core = True,
39+
visibility = ["//visibility:public"],
3840
deps = [
3941
":corecheck_ebpf_headers",
4042
"//pkg/ebpf/c:ebpf_c_headers",
@@ -45,6 +47,7 @@ ebpf_program_suite(
4547
name = "ebpf",
4648
src = "ebpf-kern.c",
4749
core = True,
50+
visibility = ["//visibility:public"],
4851
deps = [
4952
":corecheck_ebpf_headers",
5053
"//pkg/ebpf/c:ebpf_c_headers",
@@ -55,6 +58,7 @@ ebpf_program_suite(
5558
name = "noisy-neighbor",
5659
src = "noisy-neighbor-kern.c",
5760
core = True,
61+
visibility = ["//visibility:public"],
5862
deps = [
5963
":corecheck_ebpf_headers",
6064
"//pkg/ebpf/c:ebpf_c_headers",

pkg/collector/corechecks/ebpf/probe/ebpfcheck/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ cgo_godefs(
1111
name = "c_types_godefs",
1212
src = "c_types.go",
1313
hdrs = ["//pkg/collector/corechecks/ebpf/c/runtime:corecheck_ebpf_headers"],
14+
visibility = ["//visibility:public"],
1415
)

pkg/collector/corechecks/ebpf/probe/noisyneighbor/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ cgo_godefs(
1111
name = "ebpf_types_godefs",
1212
src = "ebpf_types.go",
1313
hdrs = ["//pkg/collector/corechecks/ebpf/c/runtime:corecheck_ebpf_headers"],
14+
visibility = ["//visibility:public"],
1415
)

pkg/collector/corechecks/ebpf/probe/oomkill/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ cgo_godefs(
1111
name = "c_types_godefs",
1212
src = "c_types.go",
1313
hdrs = ["//pkg/collector/corechecks/ebpf/c/runtime:corecheck_ebpf_headers"],
14+
visibility = ["//visibility:public"],
1415
)

0 commit comments

Comments
 (0)