связь между двумя модулями с помощью distutils - PullRequest
1 голос
/ 10 декабря 2011

Недавно выявил проблему при работе с несколькими скомпилированными модулями C ++ и хотел бы перефразировать вопрос.

У меня есть два модуля 'mod1' и 'mod2'.Они скомпилированы как два отдельных «ext_modules» в моем файле setup.py, как показано здесь:

#!/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 сначала завершается неудачно.Но если я попробую agin после импорта mod1, я получу segfault.


Оба модуля построены как разделяемые библиотеки - но если я не ошибаюсь, mod2 должен быть связан с mod1 для работы, так как ему нужны вещи, определенные в mod1.Можно ли определить такую ​​зависимость с помощью setuptools / distribate?

Что-то вроде:

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

Из моих различных чтений похоже, что можно сделать что-то подобное с помощью Booj's Bjamутилита - к сожалению, мне не удалось использовать ее (даже для компиляции примера) в моей системе.

То, что я пробовал:

  • добавление 'mod1.cpp' кисточники мод2.Это работает (вроде: я должен импортировать mod1 перед mod2, чтобы заставить его работать), но я теряю интерес к наличию модулей в качестве общих объектов.

Workarouds:

  • импорт mod1 как обычного модуля python в mod2, но это добавило бы дополнительный слой python в мой код C ++

Как вы думаете?

Ответы [ 2 ]

1 голос
/ 16 декабря 2011

В конце концов, я не смог найти, как это сделать с помощью distutils / distribution.Поэтому я переключился на cmake, и пока он работает безупречно!

с помощью cmake, вы можете легко скомпилировать один модуль в качестве разделяемой библиотеки, а затем добавить эту разделяемую библиотеку в зависимости другого модуля.

0 голосов
/ 10 декабря 2011

Если ваш mod2 зависит от mod1, тогда импортируйте явно mod1 перед mod2:

  • когда мод1 будет импортирован (загружен с dlopen()), все символы мод1 будут загружены в память
  • когда будет импортирован мод2, dlopen() разрешит и будет использовать символ, уже загруженный в память

Это просто альтернатива:)

...