如何在由 Poetry 构建的 Wheel 中包含共享对象文件

med*_*y56 9 python python-wheel python-poetry

我有一个简单的包,其中包含 C 扩展。我正在使用 Poetry 管理我的依赖关系和构建过程。

当我运行时poetry build,扩展被编译并包含在 .tar.gz 存档中,但不在 .whl 中,我不明白为什么。从 tar.gz 归档文件安装的 pip 按预期工作,但由于 Wheel 缺少 .so,pip 安装 Wheel 会导致软件包无法使用。

我已经从这里提升了构建机制:https ://github.com/python-poetry/poetry/issues/2740

pyproject.toml

[tool.poetry]
name = "python_ctypes"
version = "0.1.0"
description = ""
authors = ["Me"]
include = [
    {path = "_extensions/*.so", format = "wheel"}
]

[tool.poetry.dependencies]
python = "^3.9"
numpy = "^1.22.1"

[tool.poetry.dev-dependencies]

[tool.poetry.build]
generate-setup-file = false
script = "build.py"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
Run Code Online (Sandbox Code Playgroud)

build.py

"""Poetry build script for python_ctypes"""
import os
import shutil

from distutils.command.build_ext import build_ext
from distutils.core import Distribution
from distutils.core import Extension
from distutils.errors import CCompilerError
from distutils.errors import DistutilsExecError
from distutils.errors import DistutilsPlatformError


extensions = [
    Extension("python_ctypes._extensions.arraysum", ["python_ctypes/_extensions/arraysum.c"]),
]


class ExtBuilder(build_ext):
    # This class allows C extension building to fail.

    built_extensions = []

    def run(self):
        try:
            build_ext.run(self)
        except (DistutilsPlatformError, FileNotFoundError):
            print("Unable to build the C extensions")

    def build_extension(self, ext):
        try:
            build_ext.build_extension(self, ext)
        except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError):
            print('Unable to build the "{}" C extension, '
                  "python_ctypes will use the pure python version of the extension.".format(ext.name))


def build(setup_kwargs):
    """
    This function is mandatory in order to build the extensions.
    """
    print(setup_kwargs)
    distribution = Distribution({"name": "python_ctypes", "ext_modules": extensions})
    distribution.package_dir = "python_ctypes"

    cmd = ExtBuilder(distribution)
    cmd.ensure_finalized()
    cmd.run()

    # Copy built extensions back to the project
    for output in cmd.get_outputs():
        relative_extension = os.path.relpath(output, cmd.build_lib)
        if not os.path.exists(output):
            continue

        shutil.copyfile(output, relative_extension)
        mode = os.stat(relative_extension).st_mode
        mode |= (mode & 0o444) >> 2
        os.chmod(relative_extension, mode)

    return setup_kwargs


if __name__ == "__main__":
    build({})
Run Code Online (Sandbox Code Playgroud)