用distutils连接两个模块

时间:2011-12-10 10:23:11

标签: python boost-python bjam

我在使用多个已编译的C ++模块时最近exposed a problem,并希望重新解释这个问题。

我有两个模块'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

这里,“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,我会遇到段错误。


这两个模块都是作为共享库构建的 - 但如果我没有弄错,mod2需要链接到mod1才能工作,因为它需要在mod1中定义的东西。是否可以使用setuptools / distribute?

定义这种依赖关系

类似的东西:

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

从我的各种读物中,看起来可以用boost的bjam实用程序做这样的事情 - 不幸的是,我没有设法在我的系统上使用它(甚至编译示例)。

我尝试过的事情:

  • 将'mod1.cpp'添加到mod2的源代码中。它工作(有点:我必须在mod2之前导入mod1才能使它工作)但我不想把模块作为共享对象。

Workarouds:

  • 在mod2中将mod1导入为常规python模块,但这会在我的C ++代码中添加额外的python层

您怎么看?

2 个答案:

答案 0 :(得分:1)

最后,我无法通过distutils / distribute找到如何做到这一点。所以我切换到cmake,到目前为止它完美无缺!

使用cmake,您可以轻松地将一个模块编译为共享库,然后将此共享库添加到另一个模块的依赖项中。

答案 1 :(得分:0)

如果您的mod2依赖于mod1,则在mod2:

之前明确地导入mod1
  • 当导入mod1(加载dlopen())时,mod1的所有符号都将加载到内存中
  • 当导入mod2时,dlopen()将解析并使用已加载到内存中的符号

这只是另一种选择:)