我有一个 C++ 程序,我正在尝试包装/转换为 Cython。它使用了一个特定的库,由于某种原因,该库不会生成用于导入的工作模块。顺便说一下,有一个有效的 C++ 程序。这是 setup.py:
ext_modules = [
Extension(
name="libnmfpy",
sources=["interface/nmf_lib.pyx"],
include_dirs = ["../src/", numpy.get_include()],
libraries=["nmf","mpi_cxx","mpi","m"],
library_dirs=["../build/Linux/bin.release","/usr/local/lib/","/usr/lib"],
language="c++",)
]
setup(
name = 'libnmfpy',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
)
我应该提一下,似乎是 libnmf 导致了问题。第一次构建 libnmf 会导致此脚本生成此错误:
/usr/bin/ld: ../build/Linux/bin.release/libnmf.a(nmf.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
../build/Linux/bin.release/libnmf.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
当我使用 -fPIC 重建 libnmf 时,安装程序生成一个 libnmfpy.so,但是当我在另一个脚本中导入它时,我会得到上述 undefined symbol :
Traceback (most recent call last):
File "test.py", line 1, in <module>
import libnmfpy
ImportError: $path/cython/libnmfpy.so: undefined symbol: _ZN4elem6lapack3SVDEiiPdiS1_
如果有帮助,这里是我的搜索建议:
nm libnmfpy.so | grep _ZN4elem6lapack3SVDEiiPdiS1_
U _ZN4elem6lapack3SVDEiiPdiS1_
nm ../build/Linux/bin.release/libnmf.a | grep _ZN4elem6lapack3SVDEiiPdiS1_
U _ZN4elem6lapack3SVDEiiPdiS1_
这就是我对错误原因的猜测。我查看了我认为是构建 libnmf 的有问题的库:
nm $another_path/lib/libelemental.a | grep _ZN4elem6lapack3SVDEiiPdiS1_
0000000000005290 T _ZN4elem6lapack3SVDEiiPdiS1_
我对库和链接器还不太熟悉,所以任何帮助将不胜感激。谢谢
编辑:一点挖掘让我意识到了一些事情。我应该注意 Mac OS X 和 Linux 之间的区别吗?我为之工作的人写这篇文章最初报告没有这样的构建错误
最佳答案
您应该使用nm -C
来解开您的符号。看起来您正在混合使用静态库和共享库,这通常不是一个好主意。此外,gcc 的链接器是一次性链接器,这意味着库标志的顺序很重要。您想要以反向依赖顺序列出库。换句话说,如果 a 依赖于 b,则 b 必须出现在链接器标志中的 a 之前。
关于python - Cython 构建导致 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23391144/