2011-12-10 52 views
1

我最近有exposed a problem在使用幾個已編譯的C++模塊並且想要重新說明問題。使用distutils鏈接兩個模塊

我有兩個模塊'mod1'和'mod2'。它們被編譯在我的setup.py兩個不同的「ext_modules」,如下所示:

#!/usr/bin/python2 

from setuptools import setup, Extension 

mod1 = Extension('mod1', 
       sources = ['mod1.cpp'], 
       libraries = ['boost_python']) 

mod2 = Extension('mod2', 
       sources = ['mod2.cpp'], 
       libraries = ['boost_python']) 

setup(name='foo', 
     version='0.0', 
     description='', 
     ext_modules=[mod1,mod2], 
     install_requires=['distribute']) 

但在內部,「mod2.hpp」是包括「mod1.hpp」,作爲第一個模塊定義的東西,由第二個模塊使用。

編輯:這將編譯良好,但之後:

$> cd build/lib.linux-i686-2.7 
$> python2 -c "import mod1 ; import mod2" 
Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
ImportError: ./mod2.so: undefined symbol: _ZN6ParentD2Ev 

這裏,「家長」是MOD1定義和模2使用的類的名稱。

EDIT2:另一種怪異的行爲我不明白:

$> cd build/lib.linux-i686-2.7 
$> python2 
Python 2.7.2 (default, Nov 21 2011, 17:24:32) 
[GCC 4.6.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import mod2 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: ./mod2.so: undefined symbol: _ZN6ParentD2Ev 
>>> import mod1 
>>> import mod2 
Segmentation fault 

這裏,進口量mod2第一失敗。但是如果我在導入mod1後嘗試agin,我會得到一個段錯誤。


兩個模塊都建立共享庫 - 但如果我沒有記錯,MOD2需要鏈接爲了工作到MOD1,因爲它需要在MOD1定義的東西。有沒有可能用setuptools/distribute定義這種依賴關係?

喜歡的東西:

mod2 = Extension('mod2', 
       sources = ['mod2.cpp'], 
       libraries = ['boost_python',mod1]) 

從我的各種讀數,它看起來像它可以做這樣的事情有增強的bjam的工具 - 不幸的是,我沒能使用它(即使編譯例如)在我的系統上。

事情我已經嘗試:

  • 加入 'mod1.cpp' 以模2的來源。它的工作原理(類型:我必須在mod2之前導入mod1才能使其工作),但是我失去了將模塊作爲共享對象的興趣。

Workarouds:

  • 進口量mod1爲MOD2一個普通的Python模塊,但會放蟒蛇一層額外的我的C++代碼

內你覺得呢?

回答

0

如果你的模2取決於MOD1,那麼,進口量mod2之前明確地MOD1:

  • 時MOD1將被導入(裝載dlopen()),MOD1的所有符號在內存
  • 時mod2的加載將被導入,dlopen()將解決和使用的符號已經加載到內存中

這只是一種替代:)

+0

不確定你的意思是「明確導入」。如果我編譯,轉到'build/lib.linux-i686-2.7',運行python2並執行'import mod1;導入mod2',我得到'ImportError:./mod2.so:undefined symbol:_ZN6ParentD2Ev' – girodt

1

最後,我找不到如何使用distutils/distribute來做到這一點。所以我切換到cmake,到目前爲止它的工作完美無瑕!

使用cmake,您可以輕鬆地將一個模塊編譯爲共享庫,然後將此共享庫添加到另一個模塊的依賴關係中。

+0

我相信這是正確的路要走。問題是構建共享庫的命令通常不是可移植的,儘管我猜cmake會爲你處理這個問題嗎? –