在 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++ 标准库和 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 就会消失。谢谢!