Mik*_*lla 17 python packaging software-distribution distutils distribution
我是distutils的新手,我有一个问题,真的让我陷入困境.我正在编译一个需要扩展的包,所以我这样做了扩展:
a_module = Extension(
"amodule",
["initmodule.cpp"],
library_dirs=libdirs,
extra_objects = [
"unix/x86_64/lib/liba.so"
"unix/x86_64/lib/lib.so",
"unix/x86_64/lib/libc.so"],
)
Run Code Online (Sandbox Code Playgroud)
然后我运行安装方法:
setup(name="apackage", version="7.2",
package_dir = {'':instdir+'/a/b/python'},
packages=['apackage','package.tests'],
ext_modules=[hoc_module]
)
Run Code Online (Sandbox Code Playgroud)
包分发是正确的,我可以"python setup.py安装"罚款,但当我尝试导入我的包时,我收到一个错误
ImportError: liba.so.0: cannot open shared object file: No such file or directory
我意识到当我将liba.so.0的位置添加到我的LD_LIBRARY_PATH时,程序运行正常.不幸的是,我没有编写这些模块,也没有很好地理解编译.我一直试图解决这个问题几天无济于事.
更新:我尝试将liba.a,libb.a等文件传递给extra_objects,但这不起作用,生成以下错误:liba.a:无法读取符号:错误值collect2:ld返回1退出状态.我正在尝试做的是打包一个python模块,它需要编译一个库本身依赖于我需要以某种方式包含在包中的其他库.我怀疑我的问题非常类似于这个:http:/ /mail.python.org/pipermail/distutils-sig/2009-February/010960.html但那个问题没有得到解决,我想也许已经有两年了,已经找到了解决方案?
更新2:现在我通过这样做解决了这个问题:
data_files=[('/usr/local/lib', glob.glob('unix/x86_64/lib/*'))]
Run Code Online (Sandbox Code Playgroud)
也就是说,我正在将我需要的库复制到/ usr/local/lib中.我对这个解决方案并不是非常满意,尤其是因为它要求我的用户拥有root权限,并且因为这可能仍然无法使用Redhat发行版.所以,如果有人能提出比这个修复更好的建议,请告诉我.
Bri*_*erg 15
您可以将标志传递给编译器或链接器,以便让它知道在运行时查找库的位置,从而减少了正确设置LD_LIBRARY_PATH的需要.我将用几个例子来说明:
# Will link just fine, then fail to find libpcap.so unless it's in LD_LIBRARY_PATH
gcc -o blah blah.o -lpcap -L/opt/csw/lib
# If libpcap is in LD_LIBRARY_PATH, it'll link fine. Other people who may not have
# LD_LIBRARY_PATH set properly can still run it without fixing their environment
gcc -o blah blah.o -lpcap -R/opt/csw/lib
# This will allow me to link and execute the binary without having LD_LIBRARY_PATH
# setup properly
gcc -o blah blah.o -lpcap -{L,R}/opt/csw/lib
# This makes it possible to use relative paths. The literal string `$ORIGIN/../lib/`
# gets stored in the binary (`readelf -d binary_name` if you want to see the effect
# it has), which causes `$ORIGIN` to resolve to the directory containing the binary
# when it was executed. In a makefile, you'll see that written as `$$ORIGIN/../lib/`
# to prevent `make` from expanding it.
gcc -o blah blah.o -lsomelib -L/whatever/path/floats/your/boat -R'$ORIGIN/../lib/'
Run Code Online (Sandbox Code Playgroud)
在解释的方式,如果不明显(因为我讨厌答案没有解释):
-L仅用于在链接时查找库-R仅用于在执行二进制文件时查找库Tho*_*ers 10
该类的extra_objects参数Extension不是链接到扩展的库列表,而是一个将传递给链接器的目标文件列表(文件名不应包含扩展名,因为distutils会添加这些扩展名.)不做你想要的.
如果你想链接特定的共享库,就像你想要的那些文件的名称一样,你必须做两件事:告诉distutils告诉编译器链接那些共享库,并告诉动态链接器(通常ld.so)在哪里找到那些共享库.你可以告诉distutils告诉编译器使用libraries参数来链接库Extension,这应该是一个库名列表(没有lib前缀和.so后缀.)在你的例子中似乎是['a', 'b', 'c'](虽然看起来像是'b'掉下来了的'lib.so",并且'c'将与系统的libc实际冲突.)
告诉链接器在哪里找到这些共享库可以通过设置LD_LIBRARY_PATH环境变量来完成,或者通过更改系统范围的配置设置(使用ldconfig或通过编辑/etc/ld.so.conf),或者通过在扩展模块中硬编码搜索路径来完成; 你可以通过传递runtime_library_dirs参数来做后者Extension.但是,对路径进行硬编码确实有其自身的问题 - 您必须将这些库保留在同一位置,并且扩展模块的所有用户都可以访问它们.
(或者,你可以使用静态而不是动态链接,例如只提供静态形式的库,liba.a档案(在这种情况下,distutils将自动静态链接到它们.)这基本上意味着整个库包含在扩展模块中,这有各种缺点和好处.)
| 归档时间: |
|
| 查看次数: |
10195 次 |
| 最近记录: |