DYLD_LIBRARY_PATH / LD_LIBRARY_PATH的替代方案

时间:2010-12-16 19:50:22

标签: python macos bash python-c-extension

我正在开发用于OSX和linux的python C ++扩展。目前,我可以使用包装器脚本wrapper.sh运行我的代码:

#!/bin/bash                                                                                                                              
trunk=`dirname $0`                                                                                                                       
trunk=`cd $trunk; pwd`                                                                                                                   
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$trunk/lib                                                                                   
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$trunk/lib/:$trunk/src/hdf5/lib/:$trunk/src/python/lib                                           
$trunk/src/python/bin/python "$@" 

可以设置我的运行:wrapper.sh app.py

我想要做的是消除wrapper.sh的需要,所以我需要替代DYLD_LIBRARY_PATH和LD_LIBRARY_PATH。我无法将我的库放在像/usr/local/lib这样的标准位置,因为在我的机器上,我维护了几个独立的库实例。也就是说,我的库需要保存在相对于我的安装路径的某个地方。出于同样的原因,我无法将这些环境变量放在我的登录脚本中。目前,我需要调用我的一个wrapper.sh脚本来使用关联的库。我的目标是只能运行app.py,如果它存在于我的安装路径中,它应该能够找到它相关的python和库。目的是简化用户的执行,并简化nosetests等外部工具的使用。

当我构建我的python版本时,一个替代方案似乎是使用rpath:

./configure --enable-shared --prefix=$(CURDIR)/$(PYTHON_DIR) LDFLAGS="-Wl,-rpath,$(CURDIR)/lib/ -Wl,-rpath,$(CURDIR)/src/hdf5/lib -Wl,-rpath,$(CURDIR)/src/python/lib"

这个技巧似乎在linux上工作正常,尽管我的一个库最终需要被直接复制到trunk/src/python/lib/python2.6/lib-dynload由于某种原因我不清楚。但是,这个技巧不适用于OSX;看起来我需要在所有dylibs库上运行install_name_tool

我提出的另一个选择是做这样的事情:

ln -s wrapper.sh python

这样我的脚本都可以使用#! ../python,但我收到Unmatched ".错误。如果我使用#! ../wrapper.sh,也一样。我真的不是bash的专家......

然而,这些都显得如此不必要地复杂化,当然这是其他人已经解决的问题?谢谢你的建议!

2 个答案:

答案 0 :(得分:0)

对于python扩展,请考虑使用PYTHONPATH:Python解释器将在PYTHONPATH中搜索.py / .pyc / .pyo / .so模块以及包。请参阅docs for Python 2.x以及docs for Python 3.x;特别是两个页面上名为“模块搜索路径”的部分。这也引用了一些信息,这些信息似乎表明可以在运行时更新模块搜索路径,如果这是真的,则意味着您可以将所有逻辑添加到您的程序中,它可以自己搜索它的库(比如说它在/ usr / libexec / pkgname / ...某处或某处安装了一个副本。

对于除了最复杂的情​​况之外的所有情况,设置PYTHONPATH并使用shell脚本或本机编译的二进制包装器来启动核心程序是一种很好的方法,也可以在包括Mono在内的其他语言环境中使用和Java。

答案 1 :(得分:0)

在您的情况下,不确定这是否是可接受的(部分)解决方案,但在Linux上ld注意到库的另一种方法是将库的路径添加到/etc/ld.so.conf,然后运行{{1 }}

对于Mac我不记得细节,但我认为Apple提供了一些资源来分发打包为.app的应用程序,其中包括库的一些默认位置(相对于.app的根目录)或“框架” “他们称之为他们。需要从那里进行一些谷歌搜索 - 抱歉无法帮助进一步,但希望你取得一些进展: - )