project('libbpf', 'c', version: 'v1.5.0')
libbpf_extra_cflags = [
'-D__user=',
'-D__force=',
'-D__poll_t=unsigned',
]
output_dir = 'output'
libbpf_sources = files(
'src/bpf.c',
'src/bpf_prog_linfo.c',
'src/btf.c',
'src/btf_dump.c',
'src/btf_iter.c',
'src/btf_relocate.c',
'src/elf.c',
'src/features.c',
'src/gen_loader.c',
'src/hashmap.c',
'src/libbpf.c',
'src/libbpf_errno.c',
'src/libbpf_probes.c',
'src/linker.c',
'src/netlink.c',
'src/nlattr.c',
'src/relo_core.c',
'src/ringbuf.c',
'src/str_error.c',
'src/strset.c',
'src/usdt.c',
'src/zip.c'
)
libbpf_static = static_library(
'bpf_static',
sources: libbpf_sources,
c_args: libbpf_extra_cflags,
include_directories: include_directories('include', 'include/uapi', 'src'),
install: true,
)
libbpf_dep = declare_dependency(
link_with: [libbpf_static],
include_directories: include_directories('.'),
)
dep_libelf = dependency('libelf', fallback: ['libelf', 'libelf_dep'])
dep_zlib = dependency('zlib', fallback: ['zlib', 'zlib_dep'])
libbpf = library(
'bpf',
sources: libbpf_sources,
c_args: libbpf_extra_cflags,
include_directories: include_directories('include', 'include/uapi', 'src'),
dependencies: [dep_libelf, dep_zlib],
install: true,
)
pkg = import('pkgconfig')
pkg.generate(
name: meson.project_name(),
description: 'eBPF library',
version: meson.project_version(),
url: 'https://github.com/libbpf/libbpf',
libraries: libbpf,
libraries_private: libbpf_static,
subdirs: ['libbpf'],
)
meson.override_dependency('libbpf', libbpf_dep)
一些eBPF开发程序,还用到很多第三方库,比如libzip、libepf、argp等。前两者Frida就有移植,直接拿来使用就可以了。argp是gnulib的一部分。我也移植了一下。
# Copyright (c) 2024-2025 fei_cong(https://github.com/feicong/ebpf-course)
project('argp', 'c', version: '1.0', license: 'GPL-3.0-or-later')
# Gnulib requires some specific compiler arguments, generally to suppress warnings
# and add GNU extensions if needed.
argp_extra_cflags = [
'-Wall',
'-Wextra',
'-Wno-unused-parameter',
'-D_GL_CONFIG_H_INCLUDED',
'-DHAVE_CONFIG_H',
'-D_GNU_SOURCE',
'-include', 'config.h', # Ensure config.h is included first as required
]
# Include the Gnulib header directory
gnulib_inc = include_directories('src')
# Source files from Gnulib's argp implementation
argp_sources = files(
'src/argp-ba.c',
'src/argp-eexst.c',
'src/argp-fmtstream.c',
'src/argp-fs-xinl.c',
'src/argp-help.c',
'src/argp-parse.c',
'src/argp-pv.c',
'src/argp-xinl.c',
'src/getopt.c',
'src/getopt1.c',
'src/argp-pvh.c'
)
# Configuration checks similar to CMake checks
cc = meson.get_compiler('c')
# Check for headers
have_mempcpy_h = cc.has_header('mempcpy.h')
have_strcase_h = cc.has_header('strcase.h')
have_strchrnul_h = cc.has_header('strchrnul.h')
have_strndup_h = cc.has_header('strndup.h')
have_sysexits_h = cc.has_header('sysexits.h')
have_unistd_h = cc.has_header('unistd.h')
# Check for symbols and functions
have_asprintf = cc.has_function('asprintf')
have_mempcpy = cc.has_function('mempcpy')
have_random = cc.has_function('random')
have_sleep = cc.has_function('sleep')
have_strerror_r = cc.has_function('strerror_r')
have_putc_unlocked = cc.has_function('putc_unlocked')
have_fputs_unlocked = cc.has_function('fputs_unlocked')
have_fwrite_unlocked = cc.has_function('fwrite_unlocked')
have_strcasecmp = cc.has_function('strcasecmp')
have_strchrnul = cc.has_function('strchrnul')
have_strndup = cc.has_function('strndup')
have_program_invocation_short_name = cc.has_function('program_invocation_short_name')
have_program_invocation_name = cc.has_function('program_invocation_name')
have_ssize_t = cc.has_type('ssize_t', dependencies : cc.find_library('c', required : false))
# Generate config.h using the results
config_h = configuration_data()
config_h.set('HAVE_CONFIG_H', 1)
config_h.set('HAVE_MEMPCPY_H', have_mempcpy_h)
config_h.set('HAVE_STRCASE_H', have_strcase_h)
config_h.set('HAVE_STRCHRNUL_H', have_strchrnul_h)
config_h.set('HAVE_STRNDUP_H', have_strndup_h)
config_h.set('HAVE_SYSEXITS_H', have_sysexits_h)
config_h.set('HAVE_UNISTD_H', have_unistd_h)
config_h.set('HAVE_ASPRINTF', have_asprintf)
config_h.set('HAVE_MEMPCPY', have_mempcpy)
config_h.set('HAVE_RANDOM', have_random)
config_h.set('HAVE_SLEEP', have_sleep)
config_h.set('HAVE_STRERROR_R', have_strerror_r)
config_h.set('HAVE_DECL_PUTC_UNLOCKED', have_putc_unlocked)
config_h.set('HAVE_DECL_FPUTS_UNLOCKED', have_fputs_unlocked)
config_h.set('HAVE_DECL_FWRITE_UNLOCKED', have_fwrite_unlocked)
config_h.set('HAVE_STRCASECMP', have_strcasecmp)
config_h.set('HAVE_STRCHRNUL', have_strchrnul)
config_h.set('HAVE_STRNDUP', have_strndup)
config_h.set('HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME', have_program_invocation_short_name)
config_h.set('HAVE_DECL_PROGRAM_INVOCATION_NAME', have_program_invocation_name)
config_h.set('HAVE_SSIZE_T', have_ssize_t)
# Write out config.h
configure_file(
input: 'config.h.in.meson',
output: 'config.h',
configuration: config_h
)
argp_lib = static_library(
'argp',
sources: argp_sources,
c_args: argp_extra_cflags,
include_directories: gnulib_inc,
install: true,
)
argp_dep = declare_dependency(
link_with: argp_lib,
include_directories: gnulib_inc,
)
pkg = import('pkgconfig')
pkg.generate(
libraries: argp_lib,
name: 'argp',
description: 'Gnulib argp library',
version: '1.0',
url: 'https://www.gnu.org/software/gnulib/',
subdirs: ['gnulib'],
)
meson.override_dependency('argp', argp_dep)
接下来就是引用它们到项目到中使用了。
两个项目的代码在这里:
https://github.com/feicong/libbpf
https://github.com/feicong/argp