我在構建自己的python擴展時遇到了問題。構建此代碼之前(在Debian 7 Wheezy上)工作,但現在失敗(在Ubuntu 15.04 Vivid上)。在python擴展名(.so)中同時鏈接libgfortran和libstdC++
有問題的模塊似乎鏈接正確,但我在import
上遇到錯誤。我嘗試了兩個連接器行,其中一個使用g ++(它給了我fortran運行時函數缺少的符號錯誤),另一個使用了gfortran(這給了我一個運行時vtable缺少的符號錯誤。)
模塊用途:
- 一些多晶型C++我寫代碼,
- 一個FORTRAN(90)從stripack例程,經由通過我使用yolinux's guide寫入頭文件與C連接,
- 一個用Cython文件揭露一些python入口指向例程。
因此,它需要與C++標準庫和FORTRAN運行時鏈接,並且被構建到單片共享對象文件中。
我用蟒build manager that I wrote myself來解決這個問題:當前發佈的版本生成以下接頭線:
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提到了 「虛函數表的__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
我也嘗試過使用靜態鏈接,它會在鏈接時發生錯誤(比如「無法移動符號」),最初我認爲運行時可能會被分割到單獨的文件中,而tr ied -lfoo
許多美孚。但是,我檢查了鏈接器路徑上的libgfortran.so
文件,其中scanelf
和確實包含相關符號。
這種連接方法用於工作(在Debian Wheezy上,很久以前也在Mac OS X 10.7上測試過)。我很難理解它是如何打破最新的ubuntu(使用更新的GCC,4.9 )。
任何想法,理論和測試,以幫助調試/解決這個將不勝感激。
理論:它檢測到庫之間的衝突,並且不加載第一個庫,警告不知怎麼會丟失。我試圖列出來自兩者的所有導出符號(使用'readelf'或'nm'),並交叉引用它們。 – mtijanic
參數的順序在命令行中很重要。如果A使用B,則A應出現在B之前。https://wiki.ubuntu.com/ToolChain/CompilerFlags#A-Wl.2C--as-needed –
@MarcGlisse謝謝您,點。如果只有ubuntu默認使用-Wl,那就可以解釋爲什麼同一行可以在其他操作系統上運行。 – tehwalrus