在python扩展(.so)中同时链接libgfortran和libstdc++

Linking against libgfortran and libstdc++ at the same time, in a python extension (.so)

本文关键字:链接 libgfortran libstdc++ 扩展 python so      更新时间:2023-10-16

我在构建自己的python扩展时遇到了麻烦。构建此代码之前(在Debian 7 Wheezy上)工作,但现在失败了(在Ubuntu 15.04 Vivid上)。

有问题的模块似乎正确链接,但我在import上得到一个错误。我已经尝试了两个链接器行,一个是g++(它给我一个fortran运行时函数缺少符号错误),另一个是gfortran(它给我一个运行时虚函数缺少符号错误)

模块使用:

  • 一些我写的多态c++代码,
  • 一个来自stripack的FORTRAN(90)例程,通过我使用yolinux的指南编写的头文件链接到C,
  • 一个python文件,将一些python入口点暴露给例程。

因此,它需要与c++标准库和FORTRAN运行时链接,并被构建成一个整体共享的对象文件。

我使用自己编写的python构建管理器来解决这个问题:当前发布的版本生成以下链接器行:

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

这显然是对"vtable for __cxxabiv1::__class_type_info"的引用。这意味着,我认为,链接器行中的-lstdc++条目没有正确地完成它的工作。

类似地,我已经尝试修改我的构建系统,以生成一个g++行链接libgfortran,如下所示:

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

我也尝试过静态链接,它在链接时本身会出现错误(如"无法移动符号"),最初我认为运行时可能会被分割为单独的文件,并尝试了-lfoo许多foo。但是,我已经用scanelf检查了链接器路径上的libgfortran.so文件,并且确实包含相关符号。

这种链接方法以前是有效的(在Debian Wheezy上,很久以前也在Mac OS X 10.7上测试过。)我正在努力理解它是如何在最新的ubuntu(使用更新的GCC, 4.9)上崩溃的。

任何想法,理论和测试来帮助调试/解决这个问题,我将不胜感激。

感谢@Marc Glisse的评论:参数的顺序确实是错误的。

如果修改了原来的gfortran行,使-lc-lstdc++项排在最后,则importterror将消失。谢谢你!