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

时间:2011-01-04 18:53:05

标签: python static compilation

我想修改一个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节讨论了库的规范,但只有“library_dirs”是合适的,并且这些库是动态链接的。

我正在使用Linux环境进行开发,但该软件包也将在Windows上进行编译和安装,因此便携式解决方案就是我所追求的。

有人可以告诉我在哪里查找说明,或者如何修改setup.py脚本? (先谢谢!)

我是StackOverflow的新手,所以如果我没有正确标记这个问题,或者我在这个帖子中犯了其他错误,我很抱歉。

3 个答案:

答案 0 :(得分:12)

6 - 7年后,与Python扩展的静态链接仍然记录不足。这个Q / A有助于我找到解决方案,但现在还不清楚。

在Linux / Unix上

静态库仅作为目标文件链接,并应与extra_objects

的路径一起使用

在Windows上

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

两个平台的解决方案

对于下面的示例,我使用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路径),但我还没有测试过。

答案 1 :(得分:8)

如果所有其他方法都失败了,那么extra_compile_args构建器始终存在记录较少的Extensionextra_link_args选项。 (另见here。)

您可能需要破解一些依赖于操作系统的代码,以便为特定平台获取正确的参数格式。

答案 2 :(得分:0)

这可能有用吗?

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