DYLD_LIBRARY_PATH/LD_LIBRARY_PATH的替代方案

1 投票
2 回答
3065 浏览
提问于 2025-04-16 08:38

我正在开发可以在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_PATHLD_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

对于Python扩展,考虑使用PYTHONPATH这个环境变量:Python解释器会在PYTHONPATH中查找以.py、.pyc、.pyo和.so结尾的模块,以及包。你可以查看Python 2.x的文档Python 3.x的文档,特别是这两页中名为“模块搜索路径”的部分。这些文档还提到了一些信息,似乎表明可以在程序运行时更新模块搜索路径。如果这是真的,意味着你可以把这些逻辑加到你的程序里,让它自己去寻找需要的库(比如如果它在/usr/libexec/pkgname/...某个地方安装了一个副本)。

不过,对于大多数情况来说,设置PYTHONPATH并使用一个shell脚本或本地编译的二进制文件来启动核心程序是一个不错的做法,这种方法在其他语言环境中也很常见,比如Mono和Java。

0

我不太确定这是否适合你的情况,但在Linux上让ld注意到库的另一种方法是把库的路径添加到/etc/ld.so.conf文件中,然后运行ldconfig

至于Mac,我记不太清楚具体细节了,但我记得苹果提供了一些资源,用于分发打包成.app格式的应用程序,其中包括一些默认的库位置,或者他们称之为“框架”的东西。你可能需要自己去网上查查这些信息,抱歉我帮不了你更多,但希望你能有所进展:-)

撰写回答