Комбинированный модуль расширения Python и Ruby

У меня есть модуль расширения C для Python, и я хочу сделать его доступным для рубистов.

В исходном коде есть несколько модулей C, и только один из них зависит от Python. Остальные зависят только друг от друга и стандартной библиотеки. Я могу построить его с помощью python setup.py build обычным способом.

Я экспериментировал с добавлением поддержки Ruby с помощью newgem, и я могу создать версию расширения с помощью rake gem. Однако комбинированный исходный код имеет уродливую структуру каталогов (смешение структур в стиле Gem и Setuptools), а процесс сборки — тупик.

Я не могу просто хранить все исходники в одном каталоге, потому что mkmf автоматически выбирает модуль, зависящий от Python, и пытается его собрать, и пользователям не нужно устанавливать Python для компиляции модуля, который не будет использоваться. Мой текущий хак для extconf.rb состоит в том, чтобы скопировать независимые от Python исходные файлы в тот же каталог, что и модуль расширения, зависящий от Ruby.

Есть ли более разумный способ сделать код доступным для обоих языков? Должен ли я просто дублировать независимый от Python код в отдельном Gem? Должен ли я выпускать независимый код как отдельную библиотеку, созданную с помощью автоинструментов? Есть ли версия mkmf, которая может пропустить ненужный модуль?


person Will Harris    schedule 04.02.2009    source источник


Ответы (2)


Один из способов решить эту проблему — создать три разных проекта:

  • Сама библиотека, независимая от python и ruby.
  • Привязки Python
  • Рубиновые крепления

Это, вероятно, самое чистое решение, хотя оно требует немного больше работы при выпуске релизов, но у него есть то преимущество, что вы можете выпустить новую версию привязки Ruby без необходимости отправлять новую версию привязки библиотеки/python.

person Johan Dahlin    schedule 04.02.2009

В дополнение к тому, что сказал Йохан, я использовал пару библиотек поддержки c/c++ в Python благодаря swig. Вы пишете свой код на c/c++, а затем создаете промежуточный шаблон для каждого языка, который хотите поддерживать. Это довольно безболезненно для Python, но для Ruby необходимо сделать некоторые соображения... а именно, я не думаю, что поддержка pthread будет довольна Ruby или наоборот.

http://www.swig.org/ Кривая обучения несколько крутая, поэтому лучше найдите там пример проекта, который демонстрирует, как использовать оболочку для ваших целевых языков.

Это, безусловно, полезный инструмент, так как он делает ваш код намного чище, в то же время обеспечивая надежную привязку к нескольким языкам (PHP, Python, Ruby и, я думаю, c#).

person David    schedule 05.02.2009