【发布时间】:2016-10-11 16:43:23
【问题描述】:
我正在 Travis CI 上构建 Rust 二进制文件 (liblonlat_bng.dylib),将其拉入 Cython 扩展(在与 Cython 源 .c/.pyx 相同的目录中),并在 Travis CI 上对其进行测试(在不同的回购和构建中)。但是,Python 包的测试失败了,我不知道为什么:
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/travis/build/urschrei/convertbng/venv/lib/python2.7/site-packages/nose/loader.py", line 418, in loadTestsFromName
addr.filename, addr.module)
File "/Users/travis/build/urschrei/convertbng/venv/lib/python2.7/site-packages/nose/importer.py", line 47, in importFromPath
return self.importFromDir(dir_path, fqname)
File "/Users/travis/build/urschrei/convertbng/venv/lib/python2.7/site-packages/nose/importer.py", line 94, in importFromDir
mod = load_module(part_fqname, fh, filename, desc)
File "/Users/travis/build/urschrei/convertbng/test/test_convertbng.py", line 15, in <module>
from convertbng.cutil import convert_bng as cconvert_bng
ImportError: dlopen(/Users/travis/build/urschrei/convertbng/convertbng/cutil.so, 2): Library not loaded: /Users/travis/build/urschrei/lonlat_bng/target/x86_64-apple-darwin/release/liblonlat_bng.dylib
Referenced from: /Users/travis/build/urschrei/convertbng/convertbng/cutil.so
Reason: image not found
这是来自 Travis 的包的 OSX 构建输出:
Installing collected packages: convertbng
Running setup.py develop for convertbng
Running command /Users/travis/build/urschrei/convertbng/venv/bin/python2.7 -c "import setuptools, tokenize;__file__='/Users/travis/build/urschrei/convertbng/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" develop --no-deps
running develop
running egg_info
writing requirements to convertbng.egg-info/requires.txt
writing convertbng.egg-info/PKG-INFO
writing top-level names to convertbng.egg-info/top_level.txt
writing dependency_links to convertbng.egg-info/dependency_links.txt
warning: manifest_maker: standard file '-c' not found
reading manifest file 'convertbng.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'convertbng.egg-info/SOURCES.txt'
running build_ext
building 'convertbng.cutil' extension
creating build
creating build/temp.macosx-10.11-x86_64-2.7
creating build/temp.macosx-10.11-x86_64-2.7/convertbng
clang -fno-strict-aliasing -fno-common -dynamic -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I. -Iconvertbng -I/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c convertbng/cutil.c -o build/temp.macosx-10.11-x86_64-2.7/convertbng/cutil.o -O3
[unused function warnings]
creating build/lib.macosx-10.11-x86_64-2.7
creating build/lib.macosx-10.11-x86_64-2.7/convertbng
clang -bundle -undefined dynamic_lookup build/temp.macosx-10.11-x86_64-2.7/convertbng/cutil.o -L. -Lconvertbng -llonlat_bng -o build/lib.macosx-10.11-x86_64-2.7/convertbng/cutil.so
copying build/lib.macosx-10.11-x86_64-2.7/convertbng/cutil.so -> convertbng
Creating /Users/travis/build/urschrei/convertbng/venv/lib/python2.7/site-packages/convertbng.egg-link (link to .)
Adding convertbng 0.4.14 to easy-install.pth file
Installed /Users/travis/build/urschrei/convertbng
Successfully installed convertbng
这是 Linux Travis 的输出,它成功地将 dylib 定位在相对路径上。注意 -R 的 $ORIGIN 参数,它不能在 OSX 上使用:
Installing collected packages: convertbng
Running setup.py develop for convertbng
Running command /usr/bin/python -c "import setuptools, tokenize;__file__='/home/travis/build/urschrei/convertbng/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" develop --no-deps
running develop
running egg_info
writing requirements to convertbng.egg-info/requires.txt
writing convertbng.egg-info/PKG-INFO
writing top-level names to convertbng.egg-info/top_level.txt
writing dependency_links to convertbng.egg-info/dependency_links.txt
warning: manifest_maker: standard file '-c' not found
reading manifest file 'convertbng.egg-info/SOURCES.txt'
writing manifest file 'convertbng.egg-info/SOURCES.txt'
running build_ext
building 'convertbng.cutil' extension
creating build
creating build/temp.linux-x86_64-2.7
creating build/temp.linux-x86_64-2.7/convertbng
x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I. -Iconvertbng -I/usr/include/python2.7 -c convertbng/cutil.c -o build/temp.linux-x86_64-2.7/convertbng/cutil.o -O3
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/convertbng
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/convertbng/cutil.o -L. -Lconvertbng -Wl,-R$ORIGIN -llonlat_bng -o build/lib.linux-x86_64-2.7/convertbng/cutil.so
copying build/lib.linux-x86_64-2.7/convertbng/cutil.so -> convertbng
Creating /usr/local/lib/python2.7/dist-packages/convertbng.egg-link (link to .)
Adding convertbng 0.4.14 to easy-install.pth file
Installed /home/travis/build/urschrei/convertbng
Successfully installed convertbng
其他细节:
- 我的 OS X 和 Travis 都在使用 XCode 7.3
- 在本地和 Travis 上使用相同的提交构建二进制文件
- 如果我在本地构建二进制文件,然后在我的包上运行
setup.py build_ext --inplace,则测试通过 - 我在 Linux 上运行相同的安装,使用在 Travis 上使用相同提交构建的 .so,测试通过了
- 如果我将 Travis 构建的 .dylib 复制到本地计算机,然后运行
setup.py build_ext --inplace,测试将失败,并出现与 Travis 相同的错误。
我对发生的事情感到非常困惑。我应该在二进制文件中查看一些内容吗? otool -l 输出略有不同。例如:
本地:
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1226.10.1
特拉维斯:
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Thu Jan 1 00:00:02 1970
current version 1225.1.1
通过 Linux 作业的链接:https://travis-ci.org/urschrei/convertbng/jobs/136730347
链接到失败的 OSX 作业:https://travis-ci.org/urschrei/convertbng/jobs/136730348
更新:
这绝对是因为图书馆的名字。如果我使用install_name_tool 将dylib 位置更改为@loader_path/liblonlat_bng.dylib:
install_name_tool -change /Users/travis/build/urschrei/lonlat_bng/target/x86_64-apple-darwin/release/liblonlat_bng.dylib @loader_path/liblonlat_bng.dylib convertbng/cutil.so
Travis 构建的可执行文件将在我的本地计算机上运行。但是,Travis 似乎安装了损坏的install_name_tool,我无法将正确的调用从setup.py 传递给cutil.so。我尝试将extra_link_args 设置为['-Wl,-rpath,'+'@loader_path/liblonlat_bng.dylib'],这会生成
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/temp.macosx-10.6-intel-2.7/convertbng/cutil.o -L. -Lconvertbng -llonlat_bng -o build/lib.macosx-10.6-intel-2.7/convertbng/cutil.so -Wl,-rpath,@loader_path/liblonlat_bng.dylib
但如果我这样做,我的测试仍然会失败。
更新 2:我可以在使用 cargo 构建时在链接阶段修复 dylib 的 install_name:
RUSTFLAGS="-C link-args=-Wl,-install_name,@rpath/liblonlat_bng.dylib" cargo build --release
这很有效。但我怀疑我的setup.pyExtension 设置错误:
# only append the runtime dir on Linux
rdirs = []
ldirs = []
if sys.platform != 'darwin':
# from http://stackoverflow.com/a/10252190/416626
# the $ORIGIN trick is not perfect, though
rdirs = ['$ORIGIN']
if sys.platform == 'darwin':
ldirs = ['-Wl,-rpath,'+'@loader_path/liblonlat_bng.dylib']
extensions = Extension("convertbng.cutil",
sources=["convertbng/cutil" + suffix],
libraries=["lonlat_bng"],
include_dirs=['.', 'convertbng'],
library_dirs=['.', 'convertbng'],
runtime_library_dirs=rdirs,
extra_compile_args=["-O3"],
extra_link_args=ldirs
)
【问题讨论】:
-
你的问题我不清楚——我无法告诉 您正在创建哪个 包,以及它是否具有依赖关系或类似的东西。 minimal reproducible example 将非常有帮助。否则,我能给出的最佳建议是“是的,删除绝对路径或确保库安装在完全相同的绝对路径上”。
-
@shepmaster 我正在创建一个名为 convertbng 的 Python 包。它唯一的依赖是 dylib,它与生成的 cython .so 位于同一目录中 - 问题是,即使我认为我在 setup.py 中将正确的参数传递给我的 Extensions 实例,它的构建是绝对的小路。使用 cargo 构建时,我已将 install_name 设置为相对路径,但这是一种解决方法。
-
但是你没有向我们展示(或者很难看到)dylib 在两个版本中是如何安装的,dylib 是如何链接到的,等等。要检查,你已经看到 stackoverflow.com/q/2488016/155423 ?
-
@shepmaster 调用
setup.py时链接dylib。您可以在第二个和第三个代码块中看到产生 Cython 扩展的 clang 和 gcc 调用。绝对是缺少的 -R$ORIGIN 调用在 OSX 上绊倒了它。
标签: python rust cython travis-ci