Development Guide
Relevant source files
The following files were used as context for generating this wiki page:
This document provides comprehensive guidance for developers contributing to eCapture. It covers the build system, development workflow, testing procedures, and release process. For information about implementing new capture modules, see Adding New Modules. For eBPF program development details, see eBPF Program Development.
Development Environment Setup
Prerequisites
eCapture requires the following tools and libraries for development:
| Component | Minimum Version | Purpose |
|---|---|---|
| Go | 1.24 | User-space program compilation |
| Clang | 9+ (14 recommended) | eBPF program compilation |
| LLVM | 9+ (14 recommended) | eBPF bytecode generation |
| Linux Kernel | 4.18+ | eBPF support |
| libelf-dev | - | ELF file parsing |
| Linux headers | - | Kernel structure definitions |
Environment Initialization Script
The project provides an automated environment setup script at builder/init_env.sh:1-106. This script:
- Detects the Ubuntu version and selects appropriate Clang version (builder/init_env.sh:16-39)
- Installs required packages via apt-get (builder/init_env.sh:72-74)
- Configures cross-compilation toolchain (builder/init_env.sh:43-61)
- Prepares Linux kernel sources for eBPF compilation (builder/init_env.sh:81-89)
- Downloads and installs Go (builder/init_env.sh:94-97)
Architecture Detection: The script automatically detects the host architecture and configures cross-compilation:
- On x86_64: Sets up aarch64 cross-compilation (builder/init_env.sh:48-52)
- On aarch64: Sets up x86_64 cross-compilation (builder/init_env.sh:53-58)
Manual Execution:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/gojue/ecapture/master/builder/init_env.sh)"Sources: builder/init_env.sh:1-106
Build System Architecture
Makefile Structure
The build system consists of three primary files:
Build System Components:
Makefile: Main build orchestration (Makefile:1-245)variables.mk: Environment detection and variable definitionsfunctions.mk: Reusable build functions (functions.mk:1-76)builder/Makefile.release: Release packaging and distribution (builder/Makefile.release:1-151)
Sources: Makefile:1-11, functions.mk:1-76, builder/Makefile.release:1-10
Build Targets Overview
| Target | Purpose | Bytecode Included |
|---|---|---|
all | Full build with CO-RE and non-CO-RE | Both |
nocore | Build with non-CO-RE only | Non-CO-RE only |
ebpf | Compile CO-RE eBPF bytecode | CO-RE |
ebpf_noncore | Compile non-CO-RE eBPF bytecode | Non-CO-RE |
assets | Generate Go embedded bytecode | Both |
build | Compile Go binary | - |
clean | Remove build artifacts | - |
test-race | Run unit tests with race detector | - |
e2e | Run end-to-end tests | - |
Sources: Makefile:4-14, Makefile:106-245
Build Process Flow
Complete Build Pipeline
Sources: Makefile:6-11, Makefile:133-201
CO-RE vs Non-CO-RE Compilation
CO-RE (Compile Once, Run Everywhere):
clang -D__TARGET_ARCH_x86 \
-target bpfel \
-c kern/openssl.c \
-o user/bytecode/openssl_kern_core.o \
-g -fno-ident- Produces kernel-agnostic bytecode (Makefile:122-127)
- Requires kernel with BTF (BPF Type Format) support
- Uses
vmlinux.hgenerated bybpftool btf dump(Makefile:130-131) - Smaller file size, portable across kernel versions
Non-CO-RE (Kernel-Specific):
clang -I /usr/src/linux-source/arch/x86/include \
-c kern/openssl.c -o - | \
llc -march=bpf -filetype=obj \
-o user/bytecode/openssl_kern_noncore.o- Requires kernel headers for target kernel (Makefile:144-159)
- Works on older kernels without BTF support
- Kernel-specific, must rebuild for different kernel versions
- Larger file size due to kernel structure definitions
Build Variables:
KERN_SRC_PATH: Kernel source path (Makefile:147-154)KERN_BUILD_PATH: Kernel build path (Makefile:148-152)LINUX_ARCH: Target architecture (x86, arm64) (Makefile:122)
Sources: Makefile:117-159
Asset Embedding Process
The build system uses go-bindata to embed all eBPF bytecode files into the Go binary:
- Compile eBPF Programs: Produces
*.ofiles inuser/bytecode/ - Generate Go Code:
go-bindatareads all.ofiles (Makefile:164) - Create Asset Package: Generates
assets/ebpf_probe.go(Makefile:164) - Embed in Binary: Go build includes embedded assets
This approach eliminates the need to distribute separate bytecode files alongside the binary.
Sources: Makefile:162-171
Building eCapture
Standard Build (Native Architecture)
Full build with both CO-RE and non-CO-RE:
make clean
make env # Display build environment
make all # Build everythingNon-CO-RE only (for older kernels):
make clean
make nocoreThe nocore target is useful when:
- Target system lacks BTF support
- Deploying to specific kernel version
- Reducing binary size by excluding CO-RE bytecode
Sources: Makefile:4-14
Cross-Compilation
Build for ARM64 on x86_64:
make clean
CROSS_ARCH=arm64 make env
CROSS_ARCH=arm64 make allBuild for x86_64 on ARM64:
make clean
CROSS_ARCH=amd64 make env
CROSS_ARCH=amd64 make allCross-Compilation Requirements:
- Cross-compilation toolchain installed (.github/workflows/go-c-cpp.yml:19)
- For ARM64:
gcc-aarch64-linux-gnu - For x86_64:
gcc-x86-64-linux-gnu
- For ARM64:
- Prepared kernel headers for target architecture (.github/workflows/go-c-cpp.yml:31)
libpcap Cross-Compilation: The build system automatically configures libpcap for cross-compilation:
CC=aarch64-linux-gnu-gcc AR=aarch64-linux-gnu-ar \
./configure --host=aarch64-linux-gnuSources: Makefile:56-65, Makefile:176-184, .github/workflows/go-c-cpp.yml:56-65
Android Builds
Build for Android (ARM64):
make clean
CROSS_ARCH=arm64 make env
ANDROID=1 CROSS_ARCH=arm64 make nocoreAndroid-Specific Considerations:
- Android builds use non-CO-RE only (.github/workflows/go-c-cpp.yml:61-65)
- Special handling for BoringSSL versions (Android 12-16)
- Network byte order adjustments for ARM architecture
Sources: Makefile:95, .github/workflows/go-c-cpp.yml:61-65
Build Environment Variables
| Variable | Description | Example |
|---|---|---|
CROSS_ARCH | Target architecture | arm64, amd64 |
ANDROID | Android build flag | 1 (enable) |
DEBUG | Debug build flag | 1 (enable debug symbols) |
SNAPSHOT_VERSION | Override version string | v0.8.0 |
Environment Display:
make envThis command displays all build variables including:
- Host architecture detection
- Kernel version
- Compiler versions
- Target architecture settings
- Version information
Sources: Makefile:19-63
Testing
Unit Tests
Run unit tests:
go test -v ./...Run with race detector:
make test-raceThe race detector build (Makefile:216-224):
- Enables
CGO_ENABLED=1for C integration - Links with libpcap statically
- Uses race detector to identify data races
Sources: Makefile:216-224
End-to-End Tests
The project includes E2E test scripts for each major module:
Run specific E2E test:
make e2e-tls # Test TLS/SSL capture
make e2e-gnutls # Test GnuTLS capture
make e2e-gotls # Test Go TLS captureRun all E2E tests:
make e2eSources: Makefile:226-244
CI/CD Pipeline
GitHub Actions Workflow Architecture
Sources: .github/workflows/go-c-cpp.yml:1-128, .github/workflows/release.yml:1-129
CI Build Matrix
The CI system builds and tests multiple configurations:
| Architecture | Native Build | Cross-Compilation | Android |
|---|---|---|---|
| x86_64 | ✓ CO-RE + non-CO-RE | ✓ arm64 target | ✓ arm64 |
| arm64 | ✓ CO-RE + non-CO-RE | ✓ amd64 target | ✓ amd64 |
CI Build Steps:
Setup Environment (.github/workflows/go-c-cpp.yml:16-33):
- Install Go 1.24.6
- Install Clang 14, LLVM tools
- Extract and prepare Linux kernel sources
Native CO-RE Build (.github/workflows/go-c-cpp.yml:38-44):
bashmake clean make env DEBUG=1 make -j8Code Quality Check (.github/workflows/go-c-cpp.yml:45-50):
- Run
golangci-linton Go code - Version: v2.1
- Run
Non-CO-RE Build (.github/workflows/go-c-cpp.yml:51-55):
bashmake clean make nocoreCross-Compilation (.github/workflows/go-c-cpp.yml:56-65):
bashCROSS_ARCH=arm64 make env CROSS_ARCH=arm64 make -j8 ANDROID=1 CROSS_ARCH=arm64 make nocore -j8Test Execution (.github/workflows/go-c-cpp.yml:66-67):
bashgo test -v -race ./...
Sources: .github/workflows/go-c-cpp.yml:9-127
Compiler Version Management
The CI system ensures consistent compiler versions:
Clang/LLVM Setup:
for tool in "clang" "llc" "llvm-strip"
do
sudo rm -f /usr/bin/$tool
sudo ln -s /usr/bin/$tool-14 /usr/bin/$tool
doneThis creates symlinks to enforce Clang 14 usage (.github/workflows/go-c-cpp.yml:20-24).
Kernel Source Preparation:
cd /usr/src
source_file=$(find . -maxdepth 1 -name "*linux-source*.tar.bz2")
sudo tar -xf $source_file
cd $source_dir
sudo make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- prepare V=0Prepares kernel headers for cross-compilation (.github/workflows/go-c-cpp.yml:25-32).
Sources: .github/workflows/go-c-cpp.yml:16-33
Release Process
Release Workflow
Sources: .github/workflows/release.yml:1-129, builder/Makefile.release:1-151
Release Targets
Create snapshot (development build):
make -f builder/Makefile.release snapshotCreate release (specific version):
SNAPSHOT_VERSION=v0.8.0 make -f builder/Makefile.release releasePublish to GitHub:
SNAPSHOT_VERSION=v0.8.0 make -f builder/Makefile.release publishThe release target orchestrates (builder/Makefile.release:10):
snapshot: Build Linux artifactsbuild_deb: Create DEB packagessnapshot_android: Build Android artifacts
Sources: builder/Makefile.release:10-151
Packaging Formats
TAR.GZ Archives
Archive Contents:
ecapturebinaryLICENSECHANGELOG.mdREADME.mdandREADME_CN.md
Naming Convention:
ecapture-{VERSION}-{OS}-{ARCH}[-nocore].tar.gzExamples:
ecapture-v0.8.0-linux-amd64.tar.gz(CO-RE + non-CO-RE)ecapture-v0.8.0-android-arm64-nocore.tar.gz(non-CO-RE only)
Archive Creation (builder/Makefile.release:62-76):
$(CMD_MKDIR) -p $(TAR_DIR)
$(CMD_CP) LICENSE $(TAR_DIR)/LICENSE
$(CMD_CP) bin/ecapture $(TAR_DIR)/ecapture
$(CMD_TAR) -czf $(OUT_ARCHIVE) $(TAR_DIR)Sources: builder/Makefile.release:62-76, functions.mk:62-76
DEB Packages
Package Structure:
ecapture-v0.8.0-amd64.deb
├── DEBIAN/
│ └── control
└── usr/
└── local/
└── bin/
└── ecaptureControl File Fields (builder/Makefile.release:143-149):
- Package: ecapture
- Version: Extracted from git tag
- Architecture: amd64 or arm64
- Maintainer: CFC4N cfc4ncs@gmail.com
- Description: capture SSL/TLS text content without CA cert by eBPF
Build Process:
make -f builder/Makefile.release debCreates DEB package using dpkg-deb --build (builder/Makefile.release:151).
Sources: builder/Makefile.release:132-151
Docker Images
Multi-Architecture Build:
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg VERSION=v0.8.0 \
-t ecapture:v0.8.0 \
-t ecapture:latest \
--push .Dockerfile Stages (builder/Dockerfile:1-39):
Builder Stage: Ubuntu 22.04 base
- Install compilers (Clang 14, Go 1.24.6)
- Build eCapture with
make all
Runtime Stage: Alpine Linux
- Copy only the
ecapturebinary - Set ENTRYPOINT to
/ecapture
- Copy only the
Image Tags:
{username}/ecapture:v{VERSION}(version-specific){username}/ecapture:latest(latest release)
Sources: .github/workflows/release.yml:101-129, builder/Dockerfile:1-39
Release Notes Generation
The release workflow automatically generates release notes:
Get Previous Tag (.github/workflows/release.yml:63-67):
bashPREVIOUS=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")Generate Notes via GitHub API (.github/workflows/release.yml:68-80):
bashgh api --method POST \ /repos/$REPO/releases/generate-notes \ -f tag_name=$TAG \ -f previous_tag_name=$PREVIOUS_TAGCreate Release (builder/Makefile.release:124):
bashgh release create $(VERSION) $$FILES \ --title "eCapture $(VERSION)" \ --notes-file $(RELEASE_NOTES)
Sources: .github/workflows/release.yml:63-87, builder/Makefile.release:114-124
Development Workflow Summary
Typical Development Cycle
Setup Environment:
bash/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/gojue/ecapture/master/builder/init_env.sh)"Clone and Build:
bashgit clone https://github.com/gojue/ecapture.git cd ecapture make env # Verify environment make all # Build everythingMake Changes:
- Modify eBPF programs in
kern/ - Modify Go code in
cli/,user/, or other packages
- Modify eBPF programs in
Test:
bashmake clean make all go test -v ./... make e2e # If testing modulesFormat Code:
bashmake format # Format C code with clang-formatCommit and Push:
bashgit add . git commit -m "Your change description" git push origin your-branchCreate Pull Request:
- CI automatically runs on x86_64 and arm64
- Both native and cross-compilation builds tested
- Code quality checked with golangci-lint
Key Build Commands Reference
| Command | Purpose | Use Case |
|---|---|---|
make env | Show build environment | Verify configuration |
make all | Full build (CO-RE + non-CO-RE) | Development |
make nocore | Non-CO-RE only build | Older kernels |
make clean | Remove build artifacts | Clean rebuild |
make test-race | Run tests with race detector | Find concurrency issues |
make e2e | Run E2E tests | Integration testing |
make format | Format C code | Code style |
CROSS_ARCH=arm64 make | Cross-compile for ARM64 | ARM target |
ANDROID=1 make nocore | Build for Android | Mobile deployment |
Sources: Makefile:1-245, builder/Makefile.release:1-151