在 python 扩展名 (.so) 中同时链接 libgfortran 和 libstdc++
Linking against libgfortran and libstdc++ at the same time, in a python extension (.so)
我在构建自己的 python 扩展时遇到问题。构建此代码之前(在 Debian 7 Wheezy 上)有效,但现在失败了(在 Ubuntu 15.04 Vivid 上)。
有问题的模块似乎 link 正确,但我在 import
上遇到错误。我已经尝试了两行 linker 行,一个是 g++(它给我一个 fortran 运行时函数的符号缺失错误),另一个是 gfortran(它给我一个运行时 vtable 的符号缺失错误。)
模块使用:
- 我写的一些多态C++代码,
- 来自 stripack 的 FORTRAN (90) 例程,link通过我使用 yolinux's guide、
编写的头文件编辑到 C
- 一个 Cython 文件,用于向例程公开一些 python 入口点。
因此,它需要与 C++ 标准库和 FORTRAN 运行时一起 link 编辑,并构建到一个单一的共享对象文件中。
我使用 python build manager that I wrote myself 来解决这个问题:当前发布的版本生成以下 linker 行:
gfortran -fno-strict-aliasing -fPIC -pthread -shared \
-Wl,-O1 -Wl,-Bsymbolic-functions -lc -lstdc++ cpp1.o cpp2.o f90.o pyx.o -o \
module.so
(省略了一些文件并缩短了路径。)
这会产生以下导入错误:
ImportError: module.so: undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE
这是 apparently 对 "vtable for __cxxabiv1::__class_type_info
" 的引用。我认为,这意味着 linker 行中的 -lstdc++
条目没有正确完成其工作。
同样,我尝试修改我的构建系统以生成针对 libgfortran 的 g++ 行 linking,如下所示:
c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -lgfortran cpp1.o cpp2.o \
f90.o pyx.o -o module.so
同样,这给了我一个丢失的符号错误:
ImportError: module.so: undefined symbol: _gfortran_st_write_done
我也尝试过静态 linking,它在 link 时间本身给出错误(如 "unable to move symbol"),最初我认为运行时可能会被分割单独的文件并尝试 -lfoo
许多 foo。但是,我用 scanelf
检查了 linker 路径上的 libgfortran.so
文件,它 确实 包含相关符号。
这种 linking 的方法曾经有效(在 Debian Wheezy 上,很久以前也在 Mac OS X 10.7 上测试过。)我正在努力理解它是如何工作的可能在最新的 ubuntu(使用较新的 GCC,4.9)上出现问题。
任何有助于debug/solve的想法、理论和测试都将不胜感激。
感谢@Marc Glisse的评论:参数的顺序确实是错误的。
如果修改原始 gfortran
行,使 -lc
和 -lstdc++
项在最后,ImportError 就会消失。谢谢!
我在构建自己的 python 扩展时遇到问题。构建此代码之前(在 Debian 7 Wheezy 上)有效,但现在失败了(在 Ubuntu 15.04 Vivid 上)。
有问题的模块似乎 link 正确,但我在 import
上遇到错误。我已经尝试了两行 linker 行,一个是 g++(它给我一个 fortran 运行时函数的符号缺失错误),另一个是 gfortran(它给我一个运行时 vtable 的符号缺失错误。)
模块使用:
- 我写的一些多态C++代码,
- 来自 stripack 的 FORTRAN (90) 例程,link通过我使用 yolinux's guide、 编写的头文件编辑到 C
- 一个 Cython 文件,用于向例程公开一些 python 入口点。
因此,它需要与 C++ 标准库和 FORTRAN 运行时一起 link 编辑,并构建到一个单一的共享对象文件中。
我使用 python build manager that I wrote myself 来解决这个问题:当前发布的版本生成以下 linker 行:
gfortran -fno-strict-aliasing -fPIC -pthread -shared \
-Wl,-O1 -Wl,-Bsymbolic-functions -lc -lstdc++ cpp1.o cpp2.o f90.o pyx.o -o \
module.so
(省略了一些文件并缩短了路径。)
这会产生以下导入错误:
ImportError: module.so: undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE
这是 apparently 对 "vtable for __cxxabiv1::__class_type_info
" 的引用。我认为,这意味着 linker 行中的 -lstdc++
条目没有正确完成其工作。
同样,我尝试修改我的构建系统以生成针对 libgfortran 的 g++ 行 linking,如下所示:
c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -lgfortran cpp1.o cpp2.o \
f90.o pyx.o -o module.so
同样,这给了我一个丢失的符号错误:
ImportError: module.so: undefined symbol: _gfortran_st_write_done
我也尝试过静态 linking,它在 link 时间本身给出错误(如 "unable to move symbol"),最初我认为运行时可能会被分割单独的文件并尝试 -lfoo
许多 foo。但是,我用 scanelf
检查了 linker 路径上的 libgfortran.so
文件,它 确实 包含相关符号。
这种 linking 的方法曾经有效(在 Debian Wheezy 上,很久以前也在 Mac OS X 10.7 上测试过。)我正在努力理解它是如何工作的可能在最新的 ubuntu(使用较新的 GCC,4.9)上出现问题。
任何有助于debug/solve的想法、理论和测试都将不胜感激。
感谢@Marc Glisse的评论:参数的顺序确实是错误的。
如果修改原始 gfortran
行,使 -lc
和 -lstdc++
项在最后,ImportError 就会消失。谢谢!