编译python模块扩展时如何静态链接库

2024-06-16 10:01:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我想修改setup.py文件,以便命令“python setup.py build”编译静态(而不是动态)链接到库的基于C的扩展模块。

扩展当前动态链接到多个库。除了静态链接到一个库之外,我希望所有内容都保持不变。通过手动修改distutils运行的gcc调用,我已经成功地完成了这项工作,尽管它要求我显式地列出依赖库。

也许这是太多的信息,但是为了清楚起见,这是在“python setup.py build”脚本中执行的最后一个链接命令:

gcc -pthread -shared -L/system/lib64 -L/system/lib/ -I/system/include build/temp.linux-x86_64-2.7/src/*.o -L/system/lib -L/usr/local/lib -L/usr/lib -ligraph -o build/lib.linux-x86_64-2.7/igraph/core.so

这是我的手工修改:

gcc -pthread -shared -L/system/lib64 -L/system/lib/ -I/system/include build/temp.linux-x86_64-2.7/src/*.o -L/system/lib -L/usr/local/lib -L/usr/lib /system/lib/libigraph.a -lxml2 -lz -lgmp -lstdc++ -lm -ldl -o build/lib.linux-x86_64-2.7/igraph/core.so

Distributing Python Modules的2.3.4节讨论了库的规范,但是只有“库目录”才是合适的,并且这些库是动态链接的。

我正在使用Linux环境进行开发,但该软件包也将编译并安装在Windows上,因此我需要一个可移植的解决方案。

有人能告诉我在哪里查找指令,或者如何修改setup.py脚本吗?(提前谢谢!)

我是新来的StackOverflow,所以如果我没有正确标记这个问题,或者如果我在这篇文章中犯了其他错误,我深表歉意。


Tags: py命令build脚本链接linuxlibusr
3条回答

这可能管用吗?

g++ -Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar -Wl,--as-needed

6-7年后,与Python扩展的静态链接仍然缺乏文档记录。这个问答帮助我找到了解决办法,但现在还不清楚。

在Linux/Unix上

静态库就像对象文件一样链接,并且应该与进入extra_objects的路径保持一致。

在Windows上

编译器将查看链接库是静态的还是动态的,静态库名称将转到库列表,目录将转到库目录

两个平台的解决方案

对于下面的示例,我使用OP中的库场景,链接igraph静态和zxml2gmp动态。这个解决方案有点老套,但至少对每个平台都是正确的。

static_libraries = ['igraph']
static_lib_dir = '/system/lib'
libraries = ['z', 'xml2', 'gmp']
library_dirs = ['/system/lib', '/system/lib64']

if sys.platform == 'win32':
    libraries.extend(static_libraries)
    library_dirs.append(static_lib_dir)
    extra_objects = []
else: # POSIX
    extra_objects = ['{}/lib{}.a'.format(static_lib_dir, l) for l in static_libraries]

ext = Extension('igraph.core',
                 sources=cmf_files,
                 libraries=libraries,
                 library_dirs=library_dirs,
                 include_dirs=include_dirs,
                 extra_objects=extra_objects)

在MacOS上

我想这也适用于MacOS(使用else路径),但我还没有测试它。

如果所有其他操作都失败了,那么^{}生成器总是有一些文档化的^{}extra_link_args选项。(另请参见here。)

不过,您可能需要破解一些与操作系统相关的代码,以获得特定平台的正确参数格式。

相关问题 更多 >