Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ internal/test/integration/components/pythonserver/pyvenv.cfg
internal/test/integration/components/gosql/qosql
*_bpfel.go
*_bpfel.o
*_bpfel.go.d
*_bpfeb.go.d
opentelemetry-ebpf-instrumentation.sln
obi.sln
internal/test/integration/components/javakafka/target/*
Expand Down
91 changes: 83 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ CILIUM_EBPF_VER ?= v0.20.0
CILIUM_EBPF_PKG := github.com/cilium/ebpf

# regular expressions for excluded file patterns
EXCLUDE_COVERAGE_FILES="(_bpfel.go)|(/opentelemetry-ebpf-instrumentation/internal/test/)|(/opentelemetry-ebpf-instrumentation/configs/)|(.pb.go)|(/pkg/export/otel/metric/)|(/cmd/obi-genfiles)"
EXCLUDE_COVERAGE_FILES="(_bpfel.go)|(/opentelemetry-ebpf-instrumentation/internal/test/)|(/opentelemetry-ebpf-instrumentation/configs/)|(.pb.go)|(/pkg/export/otel/metric/)"

.DEFAULT_GOAL := all

Expand All @@ -54,6 +54,12 @@ EXCLUDE_COVERAGE_FILES="(_bpfel.go)|(/opentelemetry-ebpf-instrumentation/interna
# projects ca have different versions of the tools
PROJECT_DIR := $(shell dirname $(abspath $(firstword $(MAKEFILE_LIST))))

# BPF2GO_MAKEBASE tells bpf2go to generate Make-compatible dependency files (.d files)
# relative to the project root. These .d files track dependencies between generated
# Go code and source .c/.h files, enabling smart incremental builds.
# See: https://pkg.go.dev/github.com/cilium/ebpf/cmd/bpf2go
export BPF2GO_MAKEBASE := $(PROJECT_DIR)

# Check that given variables are set and all have non-empty values,
# die with an error otherwise.
#
Expand Down Expand Up @@ -168,18 +174,87 @@ update-offsets: $(GO_OFFSETS_TRACKER)
@echo "### Updating pkg/internal/goexec/offsets.json"
$(GO_OFFSETS_TRACKER) -i configs/offsets/tracker_input.json pkg/internal/goexec/offsets.json

.PHONY: generate
### eBPF Code Generation ###########################################################
#
# This section handles generation of Go code from eBPF C sources using bpf2go.
# The system supports smart incremental builds via Make's dependency tracking.
#
# Developer Guide:
#
# make generate - Smart incremental build (recommended for development)
# Only regenerates files that are missing or out-of-date.
# Takes ~0.05s when nothing needs rebuilding.
#
# make generate/all - Force regeneration of everything (use after git clean)
# Always regenerates all eBPF code (~60s).
# Use after: git clean -dxf, initial clone, or when in doubt.
#
# make docker-generate - Generate in Docker container (for reproducible builds)
# Mounts workspace and runs 'make generate' inside container.
# Image: $(GEN_IMG)
#
# How it works:
# - bpf2go generates .d files (thanks to BPF2GO_MAKEBASE) that track dependencies
# - Make reads these .d files to know when source .c/.h files have changed
# - Only affected packages are rebuilt when sources change
# - Pattern rule runs go generate for each out-of-date file's directory
#
# Generated files (gitignored):
# - *_bpfel.go, *_bpfeb.go - Go bindings for eBPF programs
# - *_bpfel.o, *_bpfeb.o - Compiled eBPF bytecode
# - *_bpfel.go.d, *_bpfeb.go.d - Dependency files for Make
#
# NOTE on parallel builds:
# Using 'make -j' with the 'generate' target may result in a race condition.
# Each go generate invocation produces multiple files, and parallel execution
# can cause bpf2go to simultaneously be run on the same directory. This
# command should be idempotent, but it may cause redundant generation and
# potential conflicts.
#
################################################################################

BPF_ROOT = pkg/

# Find all generated Go and object files (used as Make targets)
BPF_GEN_GO := $(shell find $(BPF_ROOT) -type f \( -name 'bpf_*_bpfe[lb].go' -o -name 'net_*_bpfe[lb].go' -o -name 'netsk_*_bpfe[lb].go' \))
BPF_GEN_OBJ := $(BPF_GEN_GO:.go=.o)
BPF_GEN_ALL := $(if $(BPF_GEN_GO),$(BPF_GEN_GO) $(BPF_GEN_OBJ))

# Include dependency files generated by bpf2go for smart incremental builds.
# These .d files contain Make rules like:
# pkg/internal/ebpf/logger/bpf_x86_bpfel.go: bpf/logger/logger.c bpf/bpfcore/vmlinux.h ...
-include $(shell find $(BPF_ROOT) -type f -name '*_bpfe[lb].go.d' 2>/dev/null)

.PHONY: generate generate/all
# Smart incremental build - only regenerates what's needed
generate: export BPF_CLANG := $(CLANG)
generate: export BPF_CFLAGS := $(CFLAGS)
generate: export BPF2GO := $(BPF2GO)
generate: $(BPF2GO)
@echo "### Generating files..."
@OTEL_EBPF_GENFILES_RUN_LOCALLY=1 go generate cmd/obi-genfiles/obi_genfiles.go

generate: $(BPF2GO) $(if $(BPF_GEN_ALL),$(BPF_GEN_ALL),generate/all)

Comment thread
MrAlias marked this conversation as resolved.
# Pattern rule: regenerate specific eBPF files when dependencies change
$(BPF_GEN_ALL): $(BPF2GO)
@echo "Generating $(dir $@)..."
@go generate ./$(dir $@)

Comment thread
MrAlias marked this conversation as resolved.
# Force regeneration of all eBPF code (use after git clean or initial clone)
generate/all: export BPF_CLANG := $(CLANG)
generate/all: export BPF_CFLAGS := $(CFLAGS)
generate/all: export BPF2GO := $(BPF2GO)
generate/all: $(BPF2GO)
@echo "### Generating all eBPF files..."
@go generate ./...

# Generate eBPF code in Docker container for reproducible builds
.PHONY: docker-generate
docker-generate:
@echo "### Generating files (docker)..."
@GOOS=$(shell go env GOHOSTOS) GOARCH=$(shell go env GOHOSTARCH) OTEL_EBPF_GENFILES_GEN_IMG=$(GEN_IMG) go generate cmd/obi-genfiles/obi_genfiles.go
@echo "### Generating files in Docker..."
@$(OCI_BIN) run --rm \
-u $(DOCKER_USER) \
-v "$(CURDIR):/src:z" \
-w /src \
$(GEN_IMG) \
make generate

.PHONY: verify
verify: prereqs lint test license-header-check
Expand Down
Loading