【问题标题】:linking between two modules with distutils使用 distutils 链接两个模块
【发布时间】:2023-04-05 20:45:02
【问题描述】:

我最近exposed a problem 在处理几个已编译的 C++ 模块时想重新表述这个问题。

我有两个模块“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 才能使其工作)但我失去了将模块作为共享对象的兴趣。

解决方法:

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

你怎么看?

【问题讨论】:

    标签: python boost-python bjam


    【解决方案1】:

    最后,我找不到使用 distutils / 分发的方法。所以我改用 cmake,到目前为止它运行良好!

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

    【讨论】:

    • 我相信这是正确的方法。问题是构建共享库的命令通常是不可移植的,尽管我猜 cmake 会为你解决这个问题?
    【解决方案2】:

    如果你的 mod2 依赖于 mod1,那么,在 mod2 之前显式导入 mod1:

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

    这只是一种选择:)

    【讨论】:

    • 不确定“显式导入”是什么意思。如果我编译,转到'build/lib.linux-i686-2.7',运行python2并执行'import mod1;导入 mod2',我得到 'ImportError: ./mod2.so: undefined symbol: _ZN6ParentD2Ev'
    猜你喜欢
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多