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
108 changes: 85 additions & 23 deletions .github/workflows/pip.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
name: Pip

on:
workflow_dispatch:
pull_request:
push:
branches:
- master
- main
branches: [main, master]
pull_request:
branches: [main, master]
workflow_dispatch:

jobs:
build:
test:
name: Test on Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
python-version: ["3.12", "3.13"]

runs-on: ${{ matrix.platform }}
python-version: ['3.12', '3.13']

steps:
- uses: actions/checkout@v5
- name: Checkout code
uses: actions/checkout@v5
with:
submodules: true
submodules: recursive

- uses: actions/setup-python@v6
- name: Verify submodules
run: |
echo "Checking submodule status:"
git submodule status
echo "Checking libbpf directory:"
ls -la libbpf/
echo "Checking libbpf/src:"
ls -la libbpf/src/ || echo "libbpf/src not found!"

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -33,19 +42,72 @@ jobs:
sudo apt-get install -y \
libbpf-dev \
libelf-dev \
linux-headers-generic \
zlib1g-dev \
build-essential \
clang \
cmake \
ninja-build
ninja-build \
pkg-config \
git \
make

- name: Add requirements
run: python -m pip install --upgrade pip wheel setuptools
- name: Install Python build dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade "setuptools>=77.0.0" wheel
pip install cmake ninja pybind11

- name: Build and install
run: pip install --verbose .[test]
- name: Check build requirements
run: |
echo "Python version:"
python --version
echo "CMake version:"
cmake --version
echo "Ninja version:"
ninja --version
echo "Setuptools version:"
python -c "import setuptools; print(setuptools.__version__)"

- name: Test import
run: python -I -c "import pylibbpf; print('Import successful')"
- name: Build and install pylibbpf (verbose)
run: |
pip install -v -e . 2>&1 | tee build.log
continue-on-error: false

- name: Test
run: python -I -m pytest -v
- name: Check build output
run: |
echo "Build directory contents:"
find build -type f -name "*.so" 2>/dev/null || echo "No .so files found in build/"
echo ""
echo "Looking for pylibbpf extension:"
find . -name "pylibbpf*.so" -o -name "pylibbpf*.pyd"
echo ""
echo "Site-packages contents:"
python -c "import site; print(site.getsitepackages())"
ls -la $(python -c "import site; print(site.getsitepackages()[0])")/pylibbpf/ || echo "pylibbpf not in site-packages"

- name: Try importing extension directly
run: |
python -c "
import sys
print('Python path:', sys.path)
try:
from pylibbpf import pylibbpf
print('Successfully imported pylibbpf.pylibbpf')
print('pylibbpf.pylibbpf members:', dir(pylibbpf))
except ImportError as e:
print(f'Failed to import pylibbpf.pylibbpf: {e}')
"

- name: Verify extension loaded
run: |
python -c "import pylibbpf; print('Members:', dir(pylibbpf)); assert hasattr(pylibbpf, 'BpfObject'), 'BpfObject not found!'; print('✓ OK')"

- name: Install test dependencies
if: success()
run: |
pip install pytest pytest-cov

- name: Run tests
if: success()
run: |
python -I -m pytest -v -s --cov=pylibbpf --cov-report=term-missing
12 changes: 7 additions & 5 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: true
submodules: recursive

- name: Build SDist
run: pipx run build --sdist
Expand All @@ -41,22 +41,24 @@ jobs:
steps:
- uses: actions/checkout@v5
with:
submodules: true
submodules: recursive

- name: Build wheels
uses: pypa/cibuildwheel@v3.2
env:
CIBW_PLATFORM: linux
CIBW_ARCHS_LINUX: ${{ matrix.arch }}
CIBW_BUILD: "cp311-*"
CIBW_BUILD: "cp312-* cp313-*"
CIBW_SKIP: "*-musllinux*"
CIBW_TEST_COMMAND: "python -c 'import pylibbpf; print(f\"pylibbpf {pylibbpf.__version__} imported successfully\")'"
CIBW_TEST_COMMAND: "python -c 'import pylibbpf; assert hasattr(pylibbpf, \"BpfObject\"), \"BpfObject not found\"; print(f\"pylibbpf {pylibbpf.__version__} OK\")'"
CIBW_TEST_SKIP: "*-linux_aarch64"

CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28

CIBW_BEFORE_ALL_LINUX: |
dnf install -y elfutils-libelf-devel zlib-devel
dnf install -y elfutils-libelf-devel zlib-devel make gcc gcc-c++ git
CIBW_BEFORE_BUILD: >
pip install --upgrade "setuptools>=77.0.0" wheel cmake ninja pybind11

- name: Verify clean directory
run: git diff --exit-code
Expand Down
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
find_package(
Python
COMPONENTS Interpreter Development.Module
REQUIRED)

# pybind11
include_directories(${CMAKE_SOURCE_DIR}/src)
Expand Down
3 changes: 1 addition & 2 deletions pylibbpf/ir_to_ctypes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import ctypes
import logging
from typing import Dict, Type

from llvmlite import ir

Expand Down Expand Up @@ -51,7 +50,7 @@ def __repr__(self):
return __repr__


def convert_structs_to_ctypes(structs_sym_tab) -> Dict[str, Type[ctypes.Structure]]:
def convert_structs_to_ctypes(structs_sym_tab) -> dict[str, type[ctypes.Structure]]:
"""Convert PythonBPF's structs_sym_tab to ctypes.Structure classes."""
if not structs_sym_tab:
return {}
Expand Down
4 changes: 2 additions & 2 deletions pylibbpf/wrappers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Callable, Optional
from collections.abc import Callable


class PerfEventArrayHelper:
Expand All @@ -13,7 +13,7 @@ def open_perf_buffer(
callback: Callable,
struct_name: str = "",
page_cnt: int = 8,
lost_callback: Optional[Callable] = None,
lost_callback: Callable | None = None,
):
"""Open perf buffer with auto-deserialization."""
from .pylibbpf import PerfEventArray
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,7 @@ extend-select = [
"RUF", # Ruff-specific
"UP", # pyupgrade
]

[tool.setuptools]
packages = ["pylibbpf"]
package-data = {"pylibbpf" = ["*.py", "*.so", "*.pyd", "py.typed"]}
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
from pathlib import Path

from setuptools import Extension, find_packages, setup
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext


Expand Down Expand Up @@ -116,5 +116,4 @@ def build_extension(self, ext: CMakeExtension) -> None:
setup(
ext_modules=[CMakeExtension("pylibbpf.pylibbpf")],
cmdclass={"build_ext": CMakeBuild},
zip_safe=False,
)
Loading