【问题标题】:Can I add an include path in a distutils command?我可以在 distutils 命令中添加包含路径吗?
【发布时间】:2020-06-22 22:36:53
【问题描述】:

我正在将 Python 接口打包到 C 库中。 C 库作为带有头文件和编译库的二进制分发 tarball 提供。我想用它制作一个bdist_wheel,以及我构建的 Python 扩展和标题。

我已经编写了几个 distutils 命令来提取和安装库,如下所示:

from distutils.core import Command
from distutils.command.build import build

import os
import tarfile

class ExtractLibraryCommand(Command):
    description = 'extract library from binary distribution'

    def initialize_options(self):
        self.build_lib = None
        self.build_temp = None
        self.library_dist = os.environ.get('LIBRARY_DIST')

    def finalize_options(self):
        self.set_undefined_options('build',
                                   ('build_lib', 'build_lib'),
                                   ('build_temp', 'build_temp'))

        assert os.path.exists(self.library_dist), 'Library dist {} does not exist'.format(self.library_dist)

    def run(self):
        with tarfile.open(self.library_dist, 'r') as tf: 
            tf.extractall(path=self.build_temp)

class InstallLibraryCommand(Command):
    description = 'install library from extracted distribution'

    def initialize_options(self):
        self.build_lib = None
        self.build_temp = None

    def finalize_options(self):
        self.set_undefined_options('build',
                                   ('build_lib', 'build_lib'),
                                   ('build_temp', 'build_temp'))

    def run(self):
            self.copy_tree(
                os.path.join(os.path.join(build_temp, 'my_library')),
                os.path.join(self.build_lib, os.path.join('my_package', 'my_library'))
            )

然后我覆盖build 步骤以包含我的新命令。

class BuildCommand(build):
    def run(self):
        self.run_command('extract_library')
        self.run_command('install_library')
        build.run(self)

问题是,我不确定如何获取库的标头路径以构建我的扩展,因为它们已安装到 distutils 指定的目录。

from setuptools import setup, find_packages
from setuptools.extension import Extension
from Cython.Build import cythonize

extensions = [
    Extension(
        'package.library.*',
        ['package/library/*.pyx'],
        include_dirs=???,
    ),
]

setup(
    packages=find_packages(),
    ...
    ext_modules=cythonize(extensions),
)

编辑:澄清一下,这是一个 setup.py 脚本。

【问题讨论】:

    标签: python cython setuptools distutils


    【解决方案1】:

    您可以在库可用后修改InstallLibraryCommand 中的扩展名。我可能还会将提取/安装代码移至finalize_options 而不是run,因为在我看来,在构建阶段安装库有点晚(使库在配置阶段不可用)。示例:

    class InstallLibraryCommand(Command):
        def finalize_options(self):
            ...
            with tarfile.open(self.library_dist, 'r') as tf: 
                tf.extractall(path=self.build_temp)
            include_path = os.path.join(self.build_lib, os.path.join('my_package', 'my_library'))
            self.copy_tree(
                    os.path.join(os.path.join(build_temp, 'my_library')),
                    include_path
            )
            for ext in self.distribution.ext_modules:
                ext.include_dirs.append(include_path)
    

    【讨论】:

      【解决方案2】:

      在仔细考虑了这个问题之后,我决定使用 Cython 接口提交库的头文件,因为它们是接口的一部分,并且是构建所必需的。这样,代码文档并使用特定的固定版本,并且可以与兼容的二进制文件一起分发。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-20
        • 1970-01-01
        • 1970-01-01
        • 2011-10-10
        • 1970-01-01
        • 1970-01-01
        • 2020-09-10
        • 2010-09-09
        相关资源
        最近更新 更多