最近、いくつかのコンパイル済み C++ モジュールを操作するときに問題が発生したため、質問を言い換えたいと思います。
「mod1」と「mod2」の 2 つのモジュールがあります。ここに示すように、setup.py で 2 つの異なる「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'])
しかし、内部では、最初のモジュールが 2 番目のモジュールで使用されるものを定義しているため、'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
ここで、「Parent」は mod1 で定義され、mod2 で使用されるクラスの名前です。
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 を実行すると、segfault が発生します。
どちらのモジュールも共有ライブラリとして構築されていますが、私の間違いでなければ、mod1 で定義されたものが必要なため、mod2 を機能させるには mod1 にリンクする必要があります。setuptools/distribute でそのような依存関係を定義することは可能ですか?
何かのようなもの :
mod2 = Extension('mod2',
sources = ['mod2.cpp'],
libraries = ['boost_python',mod1])
私のさまざまな読書から、ブーストの bjam ユーティリティでこのようなことを行うことが可能であるように見えます.
私が試したこと:
- mod2 のソースに「mod1.cpp」を追加します。それは機能します(一種:機能させるにはmod2の前にmod1をインポートする必要があります)が、モジュールを共有オブジェクトとして持つことへの関心を失っています。
回避策:
- mod1をmod2の通常のpythonモジュールとしてインポートしますが、それは私のC ++コード内に余分なpythonの層を置きます
どう思いますか ?