15

在 Python 中使用 setuptools/distutils 构建 C 库时

$ python setup.py build

*.so/*.pyd文件被放置在(build/lib.win32-2.7或等效)中。

我想在我的测试套件中测试这些文件,但我不想硬编码build/lib*路径。有谁知道如何从 distutils 中提取此路径,以便我可以sys.path.append(build_path)- 或者是否有更好的方法来获取这些文件?(没有先安装它们)

4

4 回答 4

16

您必须获取您正在运行的平台和您正在运行的 python 版本,然后自己组装名称。

要获取当前平台,请使用sysconfig.get_platform(). 要获取 python 版本,请使用sys.version_info(特别是返回元组的前三个元素)。在我的系统(带有 python 2.7.2 的 64 位 linux)上,我得到:

>>> import sysconfig
>>> import sys
>>> sysconfig.get_platform()
linux-x86_64
>>> sys.version_info[:3]
(2, 7, 2)

lib目录的格式为“lib.platform-versionmajor.versionminor”(即只有2.7,不是2.7.2)。您可以使用 python 的字符串格式化方法构造此字符串:

def distutils_dir_name(dname):
    """Returns the name of a distutils build directory"""
    f = "{dirname}.{platform}-{version[0]}.{version[1]}"
    return f.format(dirname=dname,
                    platform=sysconfig.get_platform(),
                    version=sys.version_info)

您可以使用它来生成任何 distutils 构建目录的名称:

>>> import os
>>> os.path.join('build', distutils_dir_name('lib'))
build/lib.linux-x86_64-2.7
于 2013-01-16T23:47:35.873 回答
5

我发现就地编译模块最适合测试目的。为此,只需使用

python setup.py build_ext --inplace

这将像往常一样编译 temp 目录中的所有辅助文件,但最终的 .so 文件将放在当前目录中。

于 2013-11-17T17:12:45.063 回答
5

这可作为命令类的build_lib成员使用,并且与位置相关。在你没有真正跑步的时候开始使用它是相当讨厌的:buildsetup.pysetup

import distutils.dist
import distutils.command.build
b = distutils.command.build.build(distutils.dist.Distribution())
b.finalize_options()
print(b.build_lib)

就我个人而言,我会选择 SethMMorton 的解决方案,因为虽然如果更改构建目录位置可能会很脆弱,但我怀疑如果结构发生变化distutils,玩这些技巧会更加脆弱。distutils

于 2015-08-07T17:50:27.257 回答
0

@SethMMorton 的方法是要走的路。get_platform()然而,使用fromdistutils.util而不是 from可能更安全(即使我不知道他的版本不适用的平台)sysconfig

这是它在distutils-library中的使用方式:

import os
import sys
from distutils.util import get_platform
def get_distutils_lib_path():
    PLAT_SPEC = "%s-%d.%d" % (get_platform(), *sys.version_info[:2])
    return os.path.join("build", "lib.%s" % PLAT_SPEC)
于 2019-02-25T22:30:52.487 回答