当库依赖于第二个共享库时,使用distutils的setup.py编译C共享库

Dan*_*Dan 7 c python ctypes distutils

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

#include "rebound.h"
Run Code Online (Sandbox Code Playgroud)

rebound.h位于目录/ Users/dt/rebound/src /中,并且rebound.h中的所有函数都位于共享库librebound.so中,该库位于/ Users/dt/rebound /中.

与cc的链接看起来像.

cc -fPIC -shared reboundx.o -L/Users/dt/rebound -lrebound -o libreboundx.so
Run Code Online (Sandbox Code Playgroud)

更新:这种情况看起来与Sec末尾的示例完全相同.3在https://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'],
                                )   
Run Code Online (Sandbox Code Playgroud)

我跑的时安装得很好

pip install -e ./
Run Code Online (Sandbox Code Playgroud)

构建输出:

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
Run Code Online (Sandbox Code Playgroud)

但是当我尝试

import reboundx
Run Code Online (Sandbox Code Playgroud)

在Python中,我得到一个OSError:dlopen(libreboundx.so,10):找不到符号:_reb_boundary_particle_is_in_box,这是另一个库(librebound.so)中的一个函数,甚至在libreboundx的代码中都没有调用它.所以.

如果我使用上面的cc命令链接共享库,一切正常,我可以在C中完全使用共享库libreboundx.so.如果我尝试使用相同的libreboundx.so我使用cc命令编译并将其粘贴在哪里setup.py会把它,然后尝试在python中导入reboundx,我反而得到

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

参考自:/Users/dtamayo/Documents/workspace/reboundx/libreboundx.so原因:图片未找到

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

Dan*_*Dan 5

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

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

 runtime_library_dirs=['/Users/dt/rebound'],
Run Code Online (Sandbox Code Playgroud)

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

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

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