Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用distutils编译C共享库&x27;setup.py,当库依赖于第二个共享库时_Python_C_Ctypes_Distutils - Fatal编程技术网

Python 用distutils编译C共享库&x27;setup.py,当库依赖于第二个共享库时

Python 用distutils编译C共享库&x27;setup.py,当库依赖于第二个共享库时,python,c,ctypes,distutils,Python,C,Ctypes,Distutils,我在OSX上,试图用distutils的setup.py(在python中使用ctypes)在C中编译一个共享库。我是distutils新手,但是当我想要编译的共享库(librebrank.so)依赖于另一个共享库(librebrank.so)时,我遇到了问题。明确地说,在modify_orbits_direct.c中 #include "rebound.h" h位于目录/Users/dt/resumb/src/中,resumb.h中的所有函数都位于共享库libresumb.so中,该库位于/

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

#include "rebound.h"
h位于目录/Users/dt/resumb/src/中,resumb.h中的所有函数都位于共享库libresumb.so中,该库位于/Users/dt/resumb/中

与cc的链接看起来像

cc -fPIC -shared reboundx.o -L/Users/dt/rebound -lrebound -o libreboundx.so
更新:这种情况与第二节末尾的示例完全相同。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(librebrank.so,10):Symbol not found:_reb_boundary_particle_is_in_box,它是另一个库(librebrank.so)中的函数,在librebrank.so的代码中甚至没有调用它

如果我将共享库与上面的cc命令链接,一切正常,我可以使用共享库librebraxx.so在C中非常好。如果我尝试使用相同的librebraxx.so,那么我使用cc命令编译并将其粘贴到setup.py将其放置的位置,然后尝试在python中导入rebraxx,我会得到

OSError: dlopen(/Users/dtamayo/Documents/workspace/reboundx/reboundx/../libreboundx.so, 10): Library not loaded: librebound.so
引用自:/Users/dtamayo/Documents/workspace/responbx/libresponbx.so 原因:找不到图像


这可能像rpath问题一样,在运行时librebrank x.so不知道在哪里查找librebrank。所以?

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

我还没能测试它,但我想

 runtime_library_dirs=['/Users/dt/rebound'],
在library_dirs旁边,应该修复Linux上的问题。显然,这在Mac上不起作用,但您可以使用额外的链接参数。将其添加到上面发布的libxModule定义下面

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

解决了我的问题。我在这里找到了答案:

库=['libresumb']看起来可疑。这不应包含
lib
-前缀,而应仅包含
回弹
。您也不会链接到
-llibrebound
,而是链接到
-lrebound
。除此之外,您能提供构建输出吗?我已经在问题中添加了它。我在库中得到了与“libresponse”或“response”完全相同的行为/输出(这表明出了问题!)。此外,我还尝试在底部的install_requires中添加“回弹”。这给出了“已经满足的需求(使用——升级到升级):在/Users/dtamayo/Documents/workspace/resumb(from resumbx==1.0)”中反弹,但在Python中导入时出现相同的错误。在OS X上,
otool-D
显示库的
install\u name
,并且
install\u name\u tool-id
将更改它。如果需要相对于加载模块的路径,请使用
@loader\u path
标记。使用
otool-L
列出依赖项,并使用
install\u name\u tool-change
更改它们。您还可以设置
-rpath
依赖项搜索路径;这可以使用
@loader\u path
作为相对路径。
Extension
类有一个
rpath
参数,但是这个类确实不适合构建通用共享模块(特别是在Windows上,如果这很重要的话)。您可以调用
ccompiler.new\u compiler
直接执行gcc。因为您需要一个编译器,从总体上看,如果您改用的是API接口而不是ctypes,您的生活可能会更简单。顺便说一句,我从来没有使用过OS X,所以将我的建议作为起点。请参阅上的、和这篇文章。如果上传到PyPI,这将不起作用。除非用户恰好被称为dtamayo并在文档下的工作区中工作;)您需要将库与包捆绑在一起,并且需要使用相对的rpath,例如
@executable\u path
或类似别名。没错。我想尝试分别定位回弹库的位置,这似乎是可能的,因为python setup.py install将其列为其输出的一部分。我只是无法让它工作之前,甚至当我知道我会建议试验的路径:首先,手工制作你想要的捆绑包。例如,在librebrank x.dylib之外复制librebrank.dylib,并尝试导入该包。如果失败,请使用install_name_工具更改libx的rpath,以便找到它(显然是使用@别名使用相对路径)。一旦你达到了这个目标,试着调整你的setup.py直到它生成/提供这个结果。谢谢,我试过这样简单的例子。我发现额外的链接参数满足了我对rpath的需求。我现在陷入了下一个复杂问题:)