build-ebpf

Build the eBPF for Windows repository — entire solution or specific components. Use this skill when asked to build, compile, rebuild, restore, or clean the…

npx skills add https://github.com/microsoft/ebpf-for-windows --skill build-ebpf

Build eBPF for Windows

Build the eBPF for Windows solution or individual components using MSBuild.

When to Use

  • User asks to build, compile, rebuild, or clean the project
  • User asks to build a specific component (driver, library, tool, test, etc.)
  • User asks to restore NuGet packages
  • User asks to do a full or partial build with a specific configuration
  • After making code changes that need to be compiled

Environment Requirements

  • Visual Studio Developer PowerShell (required — regular PowerShell lacks build environment variables)
  • MSBuild from VS Build Tools
  • Must run from the solution root directory (ebpf-for-windows.sln location)

Build Instructions

Step 1: Determine What to Build

Ask the user (or infer from context) what they want to build. Options:

  1. Full solution — build everything
  2. Specific component(s) — use the target map below to select /t: targets
  3. Restore only — just restore NuGet packages

Step 2: Determine Configuration and Platform

ParameterOptionsDefault
ConfigurationDebug, Release, NativeOnlyDebug, NativeOnlyRelease, FuzzerDebugDebug
Platformx64, ARM64x64

If the user doesn't specify, use Debug and x64.

Step 3: Construct and Run the MSBuild Command

CRITICAL RULES:

  • Always use the solution file: msbuild ebpf-for-windows.sln — never build .vcxproj files directly
  • Always run from the solution root directory
  • Use /m for parallel builds
  • For first-time or fresh builds, add -Restore to restore NuGet packages
  • For clean rebuilds, use /t:"target:clean,target" syntax

Full Solution Build

# Standard build
msbuild ebpf-for-windows.sln /m /p:Configuration=Debug /p:Platform=x64

# With NuGet restore (first-time or after package changes)
msbuild ebpf-for-windows.sln /m /p:Configuration=Debug /p:Platform=x64 -Restore

# Clean the solution
msbuild ebpf-for-windows.sln /m /p:Configuration=Debug /p:Platform=x64 /t:clean

# With static analysis
msbuild ebpf-for-windows.sln /m /p:Configuration=Release /p:Platform=x64 /p:Analysis=True

Targeted Component Build

# Single target
msbuild ebpf-for-windows.sln /m /p:Configuration=Debug /p:Platform=x64 /t:drivers\EbpfCore

# Multiple targets
msbuild ebpf-for-windows.sln /m /p:Configuration=Debug /p:Platform=x64 /t:"drivers\EbpfCore,drivers\netebpfext,tests\unit_tests"

# Clean + rebuild a target (use semicolon or comma separator)
msbuild ebpf-for-windows.sln /m /p:Configuration=Debug /p:Platform=x64 /t:"tools\bpf2c:Clean;tools\bpf2c"

Step 4: Analyze Results

  • If the build succeeds, report success with the output path (e.g., x64\Debug\)
  • If the build fails, show the first error(s) and suggest fixes
  • Common issues:
    • Missing NuGet packages → suggest adding -Restore
    • Missing environment → suggest using Visual Studio Developer PowerShell
    • Header/linker errors → suggest checking dependencies and rebuilding prerequisite targets

MSBuild Target Map

Use this map to translate component names to MSBuild /t: targets. Solution targets use solution folder paths, not filesystem paths.

Drivers (Kernel Components)

ComponentTargetSource
EbpfCore (kernel execution context)drivers\EbpfCoreebpfcore/
EbpfCore_Usersim (usersim variant)drivers\EbpfCore_Usersimebpfcore/usersim/
netebpfext (WFP network hooks)drivers\netebpfextnetebpfext/sys/
sample_ebpf_ext (sample extension)undocked\drivers\sample_ebpf_extundocked/tests/sample/ext/drv/

DLLs and Services (User-Mode)

ComponentTargetSource
EbpfApi (libbpf-compatible API)dlls\EbpfApiebpfapi/
eBPFSvc (JIT/verification service)service\ebpfsvcebpfsvc/
ebpfnetsh (netsh plugin)dlls\ebpfnetshtools/netsh/

Libraries

ComponentTargetSource
API librarylibs\user\apilibs/api/
Service librarylibs\user\servicelibs/service/
Execution context (kernel)libs\kernel\execution_context_kernellibs/execution_context/kernel/
Execution context (user)libs\user\execution_context_userlibs/execution_context/user/
uBPF (kernel)libs\kernel\ubpf_kernellibs/ubpf/kernel/
uBPF (user)libs\user\ubpf_userlibs/ubpf/user/
Runtime (kernel)libs\kernel\runtime_kernellibs/runtime/kernel/
Runtime (user)libs\user\runtime_userlibs/runtime/user/
API commonlibs\user\api_commonlibs/api_common/
Shared (kernel)libs\kernel\shared_kernellibs/shared/kernel/
Shared (user)libs\user\shared_userlibs/shared/user/
PE parselibs\user\pe-parselibs/pe-parse/
ELF speclibs\user\elf_speclibs/elf_spec/
Store helperlibs\user\ebpf_store_helperlibs/store_helper/user/
Netsh staticlibs\user\netsh_staticlibs/ebpfnetsh/
PREVAIL verifierlibs\user\prevailexternal/ebpf-verifier/build/
libbtflibs\user\libbtfexternal/ebpf-verifier/build/external/libbtf/
netebpfext (user)libs\user\netebpfext_usernetebpfext/user/
cxplat (kernel)libs\kernel\cxplat_winkernelexternal/usersim/cxplat/
cxplat (user)libs\user\cxplat_winuserexternal/usersim/cxplat/
usersimlibs\user\usersimexternal/usersim/src/
usersim_dll_skeletonlibs\user\usersim_dll_skeletonexternal/usersim/usersim_dll_skeleton/

Tools

ComponentTargetSource
bpf2c (native code generator)tools\bpf2ctools/bpf2c/
bpftooltools\bpftooltools/bpftool/
export_program_infotools\export_program_infotools/export_program_info/
dnsfloodtools\dnsfloodtools/dnsflood/
port_quotatools\port_quotatools/port_quota/
port_leaktools\port_leaktools/port_leak/
Setup buildtools\setup_buildscripts/setup_build/
OneBranchtools\onebranchtools/onebranch/
export_program_info_sampleundocked\tools\export_program_info_sampleundocked/tools/export_program_info_sample/

Tests

ComponentTargetSource
API teststests\api_testtests/api_test/
Unit teststests\unit_teststests/unit/
bpf2c teststests\bpf2c_teststests/bpf2c_tests/
Performance teststests\performancetests/performance/
Socket teststests\socket_teststests/socket/
Cilium teststests\cilium_teststests/cilium/
Connect redirect teststests\connect_redirect_teststests/connect_redirect/
Common teststests\common_teststests/libs/common/
netebpfext unit teststests\netebpfext_unittests/netebpfext_unit/
Sample programstests\sampletests/sample/
bpftool testsinstaller\bpftool_teststests/bpftool_tests/
bpf2c plugintests\bpf2c_plugintests/bpf2c_plugin/
Test utilitiestests\test_utiltests/libs/util/
Sample ext apptests\sample_ext_apptests/sample/ext/app/
TCP/UDP listenertests\tcp_udp_listenertests/tcp_udp_listener/
export_program_info testtests\export_program_info_testtests/export_program_info_test/
Restart test controllertests\ebpf_restart_test_controllertests/stress/restart_test_controller/
Restart test helpertests\ebpf_restart_test_helpertests/stress/restart_test_helper/

Stress Tests and Fuzzers

Stress tests build in Debug/Release. Fuzzers require FuzzerDebug configuration.

ComponentTargetConfigSource
Stress tests (user-mode)tests\ebpf_stress_tests_umDebugtests/stress/um/
Stress tests (kernel-mode)tests\ebpf_stress_tests_kmDebugtests/stress/km/
Execution context fuzzertests\libfuzzer\execution_context_fuzzerFuzzerDebugtests/libfuzzer/execution_context/
bpf2c fuzzertests\libfuzzer\bpf2c_fuzzerFuzzerDebugtests/libfuzzer/bpf2c_fuzzer/
Verifier fuzzertests\libfuzzer\verifier_fuzzerFuzzerDebugtests/libfuzzer/verifier_fuzzer/
Core helper fuzzertests\libfuzzer\core_helper_fuzzerFuzzerDebugtests/libfuzzer/core_helper_fuzzer/
netebpfext fuzzertests\libfuzzer\netebpfext_fuzzerFuzzerDebugtests/libfuzzer/netebpfext_fuzzer/

External Dependencies

ComponentTargetSource
Catch2tests\Catch2external/Catch2/
Catch2WithMaintests\Catch2WithMainexternal/Catch2/

Note: The PREVAIL verifier for normal builds is libs\user\prevail. The ubpf_fuzzer\* targets (ebpfverifier, ubpf, libbtf, win-c, ubpf_fuzzer, ubpf_fuzzer_post_build) are only built in FuzzerDebug configuration and will fail with MSB4057 errors in Debug/Release.

ubpf_fuzzer Targets (FuzzerDebug Only)

These targets only build in FuzzerDebug configuration:

ComponentTargetSource
ebpfverifier (fuzzer copy)ubpf_fuzzer\ebpfverifierexternal/ubpf/build_fuzzer/external/ebpf-verifier/
ubpf (fuzzer copy)ubpf_fuzzer\ubpfexternal/ubpf/build_fuzzer/vm/
ubpf_fuzzerubpf_fuzzer\ubpf_fuzzerexternal/ubpf/build_fuzzer/libfuzzer/
libbtf (fuzzer copy)ubpf_fuzzer\libbtfexternal/ubpf/build_fuzzer/.../libbtf/
win-c (fuzzer copy)ubpf_fuzzer\win-cexternal/ubpf/build_fuzzer/.../win-c/
ubpf_fuzzer_post_buildubpf_fuzzer\ubpf_fuzzer_post_buildscripts/ubpf_fuzzer_post_build/

Build Utilities and Installers

ComponentTargetConfig NotesSource
RPC interfaceidl\rpc_interfaceAll configsrpc_interface/
NuGet packagetools\nugetAll configstools/nuget/
Redist packagetools\redist-packageNativeOnly/Release only (not Debug)tools/redist-package/
Installer (WiX)installer\ebpf-for-windowsAll configsinstaller/ebpf-for-windows/

Common Build Patterns

Use these when the user describes what area they're working on:

Working OnTargets to Build
API changeslibs\user\api,dlls\EbpfApi,tests\api_test
bpf2c / native code generationtools\bpf2c,tests\bpf2c_tests,tests\sample
Kernel driver changesdrivers\EbpfCore,drivers\netebpfext,tests\unit_tests
Service changeslibs\user\service,service\ebpfsvc,tests\ebpf_stress_tests_um
Execution context changeslibs\kernel\execution_context_kernel,libs\user\execution_context_user,tests\api_test
Network extension changesdrivers\netebpfext,tests\netebpfext_unit
Verifier changeslibs\user\prevail,tests\unit_tests
Shared library changesRebuild all dependents — prefer full solution build

bpf2c Expected Output Regeneration

If bpf2c output changes and tests\bpf2c_tests expected files must be updated:

  1. Build x64\Debug.
  2. Run:
.\scripts\generate_expected_bpf2c_output.ps1 x64\Debug

Dependency Chain

When building specific components, be aware of the dependency order:

  1. tools\setup_build (build utilities — runs first)
  2. libs\kernel\shared_kernel / libs\user\shared_user (fundamental utilities)
  3. libs\kernel\runtime_kernel / libs\user\runtime_user (platform abstractions)
  4. libs\kernel\execution_context_kernel / libs\user\execution_context_user (core eBPF execution)
  5. drivers\EbpfCore, drivers\netebpfext (kernel drivers)
  6. libs\user\api, dlls\EbpfApi (user-mode APIs)
  7. Tests and tools

MSBuild handles dependency resolution within the solution, so you typically only need to specify the top-level target(s) you want built.

Output Locations

Build artifacts are placed under:

  • x64\Debug\ — Debug x64 builds
  • x64\Release\ — Release x64 builds
  • x64\NativeOnlyDebug\ — NativeOnly Debug builds
  • x64\NativeOnlyRelease\ — NativeOnly Release builds
  • ARM64\Debug\ — ARM64 Debug builds (if applicable)

Quieting Build Output

For targeted builds where you only need to see errors, use /v:q /nologo:

msbuild ebpf-for-windows.sln /m /p:Configuration=Debug /p:Platform=x64 /t:"tools\bpf2c" /v:q /nologo

Pipe through | Select-Object -Last N to see just the tail when checking for success/failure.

Repository Initialization

After cloning, changing submodule pointers, or resetting submodules, run the initialization script before building:

# From solution root — initializes submodules, generates cmake projects, restores NuGet
.\scripts\initialize_ebpf_repo.ps1

# Or with ARM64
.\scripts\initialize_ebpf_repo.ps1 -Architecture ARM64

This script:

  1. Runs git submodule update --init --recursive
  2. Generates cmake projects for ebpf-verifier, Catch2, and ubpf in their respective build/ dirs
  3. Restores NuGet packages for the solution

IMPORTANT: If cmake-generated project files are missing (e.g., external/ebpf-verifier/build/prevail.vcxproj), MSBuild will error with MSB3202. Run initialize_ebpf_repo.ps1 to regenerate them.

Submodule Gotchas

  • msbuild /t:clean will fail if cmake-generated projects don't exist yet — run initialize_ebpf_repo.ps1 first
  • git stash in the parent repo does NOT affect submodule working trees — stash separately in each submodule if needed
  • After resetting submodules (git submodule update --init --recursive), re-run initialize_ebpf_repo.ps1

BPF Program Compilation (clang → .o)

When manually compiling BPF C programs with clang, use the full set of include paths from the tests\sample\sample.vcxproj CustomBuild rules.

Locate clang.exe — use the first existing path (highest priority first): packages\llvm.tools\clang.exe, "$env:ProgramFiles\LLVM\bin\clang.exe", "$(& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath)\VC\Tools\Llvm\bin\clang.exe"

# Standard sample programs (tests\sample\*.c)
& '<clang-path>' -g -target bpf -O2 -Werror `
  -Iinclude -Iexternal\bpftool `
  -Itests\xdp -Itests\socket -Itests\sample\ext\inc -Itests\include `
  -c tests\sample\<name>.c -o x64\Debug\<name>.o

# Undocked sample programs (tests\sample\undocked\*.c) — add extra includes
& '<clang-path>' -g -target bpf -O2 -Werror `
  -Iinclude -Iexternal\bpftool `
  -Itests\xdp -Itests\socket -Itests\sample\ext\inc -Itests\include `
  -Itests\sample -Iundocked\tests\sample\ext\inc `
  -c tests\sample\undocked\<name>.c -o x64\Debug\<name>.o

Common mistake: Using only -Iinclude will fail for programs that include socket_tests_common.h, xdp_common.h, or sample_ext_helpers.h.