【问题标题】:Compiling C shared library with distutils' setup.py, when the library depends on a second shared library当库依赖于第二个共享库时,使用 distutils 的 setup.py 编译 C 共享库
【发布时间】:2015-11-23 19:47:04
【问题描述】:

我在 OSX 上,试图用 distutils 的 setup.py 编译一个 C 中的共享库(使用 ctypes 在 python 中使用)。我是 distutils 的新手,但是当我要编译的共享库 (libreboundx.so) 依赖于另一个共享库 (librebound.so) 时,我遇到了问题。明确地,在 modify_orbits_direct.c 我有

#include "rebound.h"

rebound.h在/Users/dt/rebound/src/目录下,rebound.h中的所有函数都在/Users/dt/rebound/的共享库librebound.so中。

与 cc 的链接看起来像。

cc -fPIC -shared reboundx.o -L/Users/dt/rebound -lrebound -o libreboundx.so

更新:这种情况看起来与第二节末尾的示例完全相同。 3https://docs.python.org/2/extending/building.html。我已经更新了我的 setup.py 来模仿那个:

libreboundxmodule = Extension('libreboundx',
                sources = [ 'src/reboundx.c',
                            'src/modify_orbits_direct.c'],  
                include_dirs = ['src', '/Users/dt/rebound/src'], 
                extra_compile_args=['-fstrict-aliasing', '-O3','-std=c99','-march=native', '-D_GNU_SOURCE', '-fPIC'],
                library_dirs=['/Users/dt/rebound'],
                libraries=['rebound'],
                                )   

运行时安装良好

pip install -e ./

构建输出:

You are using pip version 7.0.3, however version 7.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Obtaining file:///Users/dtamayo/Documents/workspace/reboundx
Installing collected packages: reboundx
Running setup.py develop for reboundx
Successfully installed reboundx-1.0

但是当我尝试时

import reboundx

在 Python 中,我得到一个 OSError: dlopen(libreboundx.so, 10): Symbol not found: _reb_boundary_particle_is_in_box,这是另一个库 (librebound.so) 中的一个函数,它甚至没有在代码中被调用对于 libreboundx.so。

如果我将共享库与上面的 cc 命令链接,一切正常,我可以在 C 中使用共享库 libreboundx.so 非常好。如果我尝试使用相同的 libreboundx.so,我使用 cc 命令进行编译并把它贴在 setup.py 放它的地方,然后尝试在 python 中导入反弹x,我反而得到了

OSError: dlopen(/Users/dtamayo/Documents/workspace/reboundx/reboundx/../libreboundx.so, 10): Library not loaded: librebound.so

引用自:/Users/dtamayo/Documents/workspace/reboundx/libreboundx.so 原因:找不到图片

这可能是一个 rpath 问题,在运行时 libreboundx.so 不知道去哪里寻找 librebound.so?

【问题讨论】:

  • libraries=['librebound'] 看起来很可疑。这不应包含lib-前缀,而应仅包含rebound。你也没有链接到-llibrebound,而是-lrebound。除此之外,你能提供构建输出吗?
  • 我已将其添加到问题中。我在库中使用“librebound”或“rebo​​und”得到完全相同的行为/输出(这表明出了点问题!)。另外,我尝试在底部的 install_requires 中添加“反弹”。这给出了“要求已经满足(使用 --upgrade 升级):在 /Users/dtamayo/Documents/workspace/rebound 中反弹(来自反弹x==1.0)”,但是当我在 Python 中导入时出现同样的错误。
  • 在 OS X 上,otool -D 显示 lib 的 install_nameinstall_name_tool -id 将更改它。如果您想要相对于加载模块的路径,请使用 @loader_path 标记。使用otool -L 列出依赖关系,并使用install_name_tool -change 更改它们。也可以设置-rpath依赖搜索路径;这可以使用@loader_path 作为相对路径。 Extension 类有一个 rpath 参数,但这个类确实不适合构建通用共享模块(尤其是在 Windows 上,如果这很重要的话)。可以直接调用ccompiler.new_compiler执行gcc。
  • 因为无论如何你都需要一个编译器,从总体上看,如果你改用CFFI的API接口而不是ctypes,你的生活可能会更简单。
  • 顺便说一句,我从未使用过 OS X,所以请以我的建议为起点。参考dyld man pageOS X ABI Mach-O File Format Reference,以及Mach-O Binaries上的这篇文章。

标签: python c ctypes distutils


【解决方案1】:

感谢所有建议。我应该在问题中指定最终我想要一个可以打包上传到 PyPy 的解决方案,以便用户可以使用单个命令进行安装。它也应该在 OSX 和 Linux 上运行,所以我更喜欢不涉及 install_name_tool 的解决方案。

我无法测试它,但我想添加

 runtime_library_dirs=['/Users/dt/rebound'],

library_dirs 旁边应该可以解决 Linux 上的问题。显然这在 Mac 上不起作用,但您可以使用 extra_link_args。在上面发布的 libreboundxmodule 定义下方添加此内容,

if platform.system() == 'Darwin':
    extra_link_args.append('-Wl,-rpath,'+'/Users/dtamayo/Documents/workspace/rebound')

解决了我的问题。我在这里找到了答案:Python runtime_library_dirs doesn't work on Mac

【讨论】:

  • 如果上传到 PyPI,这实际上是行不通的。除非用户碰巧被称为 dtamayo 并且在 Documents 下的工作区中工作;)您需要将库与您的包捆绑在一起,并且您需要使用相对的 rpath,例如@executable_path 或类似别名。
  • 没错。我想尝试单独定位反弹库所在的位置,这似乎是可能的,因为 python setup.py install 将其列为其输出的一部分。即使我知道路径,我也无法让它工作
  • 我对实验的建议:首先,手工制作你想要的捆绑包。例如。复制 libreboundx.dylib 之外的 librebound.dylib,然后尝试导入包。如果失败,请使用 install_name_tool 更改 libreboundx 的 rpath,以便找到它(显然通过使用 @-aliases 使用相对路径)。一旦你达到了这个目标,试着按摩你的 setup.py 直到它构建/交付这个结果。
  • 谢谢,我正在尝试这样的简单案例。我发现 extra_link_args 用 rpath 完成了我需要的工作。我现在被困在下一个并发症上:) stackoverflow.com/questions/32313793/…
猜你喜欢
  • 2012-04-05
  • 2011-10-01
  • 1970-01-01
  • 2012-06-19
  • 2018-02-12
  • 1970-01-01
  • 2012-02-24
  • 2016-06-06
  • 2014-03-22
相关资源
最近更新 更多