2015-06-06 76 views
2

我在構建自己的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 )。

任何想法,理論和測試,以幫助調試/解決這個將不勝感激。

+0

理論:它檢測到庫之間的衝突,並且不加載第一個庫,警告不知怎麼會丟失。我試圖列出來自兩者的所有導出符號(使用'readelf'或'nm'),並交叉引用它們。 – mtijanic

+1

參數的順序在命令行中很重要。如果A使用B,則A應出現在B之前。https://wiki.ubuntu.com/ToolChain/CompilerFlags#A-Wl.2C--as-needed –

+0

@MarcGlisse謝謝您,點。如果只有ubuntu默認使用-Wl,那就可以解釋爲什麼同一行可以在其他操作系統上運行。 – tehwalrus

回答

1

謝謝@Marc Glisse您的評論:參數的順序確實是錯誤的。

如果修改原始gfortran行以便-lc-lstdc++項最後一次導入錯誤消失。謝謝!

相關問題