在Ubuntu上使用Cython+distutils构建Python 3时链接时更改模块lib名称

5 投票
1 回答
876 浏览
提问于 2025-04-18 16:47

我正在使用Cython和distutils。在我进行测试的时候,构建了一个二进制扩展模块。之后,我的另一个测试会import这个二进制模块并进行测试。在Travis-CI上,链接命令改变了模块的名称。请看下面的截图:编译器正确地生成了test01.o,但链接器错误地创建了test01.cpython-34m.so:我想要的是test01.so

在这里输入图片描述

上面的截图是针对Python 3.4的;在Python 2.7中没有出现这个问题,这让我怀疑Python特定的distutils可能做了一些不同的处理。

distutils的setup()函数是从我的主脚本中调用的,并没有做什么特别的事情:

setup(
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules,
    include_dirs=[numpy.get_include()]
)

这里的ext_modules是一个Extension()类的序列,从distutils.extension中导入。

我查看了2.7和3.4的distutils文档,没有发现有什么明显的不同。是什么导致了名称的变化?我可以在setup()或者Extension()实例化时指定什么选项来防止名称变化呢?


编辑:我在本地设置了一个运行Ubuntu 13.10的虚拟机,可以确认,正如上面所描述的,Python 2.7生成test01.so,而Python 3.4生成test01.cpython-34m.so。因此,这个问题与travis-ci无关,我将删除那个标签并编辑标题。


编辑:确实是distutils的变化,是在3.2中做出的。我还在想办法让我的导入语句看起来正确。


编辑:天哪,Python文档中的helloworld示例在Ubuntu 13.10的Python 3.4.1(Anaconda)上生成helloworld.cpython-34m.so。Python的sysconfig模块启动时sysconfig.get_config_var('SO') == 'cpython-34m.so'

我感觉我要发牢骚了。

1 个回答

7

问题解决了,感谢 @ncoghlan_dev。这个重命名的变化是在 PEP 3149 中做的。实际上,即使二进制扩展模块的名字可能叫做 helloworld.cpython-34m.so,在 Python 解释器中,使用 import helloworld 依然是可以正常工作的。我的 travis 测试失败是因为我有一个测试是检查编译后的 .so 文件的 名字。如果我去掉那个测试,其他部分应该还是能正常工作。

撰写回答