我正在使用OSX,尝试使用distutils的setup.py编译一个C语言共享库(以便在Python中使用ctypes),这与distutils是新领域。但是,当我想要编译的共享库(libreboundx.so)依赖于另一个共享库(librebound.so)时,我遇到了问题。具体来说,在modify_orbits_direct.c中:
这段代码在我运行时安装正常。
在Python中,我遇到了OSError错误:dlopen(libreboundx.so,10):Symbol not found:_reb_boundary_particle_is_in_box,这是其他库(librebound.so)中的一个函数,该函数在libreboundx.so的代码中甚至没有被调用。
如果我使用上面的cc命令链接共享库,一切正常,我可以在C中完美地使用共享库libreboundx.so。如果我尝试将使用cc命令编译的相同libreboundx.so放在setup.py应该放置它的位置,然后尝试在python中导入reboundx,我却得到了...
#include "rebound.h"
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
更新:这种情况与https://docs.python.org/2/extending/building.html第3节末尾的示例完全相同。我已经更新了我的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。如果我尝试将使用cc命令编译的相同libreboundx.so放在setup.py应该放置它的位置,然后尝试在python中导入reboundx,我却得到了...
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
。除此之外,您可以提供构建输出吗? - deetsotool -D
显示库的install_name
,而install_name_tool -id
将更改它。如果您想要相对于加载模块的路径,请使用@loader_path
标记。使用otool -L
列出依赖项,并使用install_name_tool -change
更改它们。您还可以设置-rpath
依赖项搜索路径;这可以使用@loader_path
作为相对路径。Extension
类具有一个rpath
参数,但是该类确实不适合构建通用共享模块(特别是在Windows上,如果这很重要)。您可以调用ccompiler.new_compiler
直接执行gcc。 - Eryk Sun