Динамический поиск символов завершается неудачно со статически встроенным Python в Mac OS X - PullRequest
3 голосов
/ 16 ноября 2010

Я создаю приложение для Mac OS X, которое должно встраивать Python. Технически мое приложение представляет собой пакет (то есть его основной исполняемый файл - MH_BUNDLE); это плагин для другого приложения. Я бы хотел, чтобы он встраивал Python статически, но хотел бы иметь возможность загружать расширения динамически.

Я сделал следующее: я включил целую библиотеку (-force_load path/to/libpython2.7.a), также повторно экспортировал все символы Python (-exported_symbol_list path/to/list) и добавил -u _PyMac_Error, который я получил, используя этот совет по связыванию, Сам пакет отлично загружается, кажется, что весь внутренний код Python работает, но он не работает, когда пытается импортировать динамическую библиотеку (time.so) со следующим сообщением:

Traceback (most recent call last):
  ...
ImportError: dlopen(/<stripped>/time.so, 2): Symbol not found: _PyExc_OverflowError
  Referenced from: /<stripped>/time.so
  Expected in: dynamic lookup

Этот символ является частью Python API и должен быть уже в моем комплекте. Я могу проверить это:

nm -g Build/Debug/pyfm | grep _PyExc_OverflowError
00172884 D _PyExc_OverflowError
0019cde0 D _PyExc_OverflowError

(он указан дважды, потому что у меня есть две архитектуры, i386 и ppc).

time.so не ссылается на что-либо, что, как я понимаю, является намеренным:

otool -L "/<stripped>/time.so"
/<stripped>/time.so (architecture ppc):
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11)
/<stripped>/time.so (architecture i386):
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11)

Моя проблема, похоже, похожа на this , но все наоборот: я связываю Python статически, в то время как другой постер связывает его динамически (и наши платформы тоже разные). Для него статическое связывание решило проблему.

Почему он не находит символ?

Обновление. Я подозреваю, что это происходит, потому что основное приложение загружает свои плагины (и, следовательно, мой пакет) с RTLD_LOCAL.

1 Ответ

1 голос
/ 22 ноября 2010

«Обновление», которое я сделал, показывает, что это правильно: основной комплект подключаемых модулей загружается локально (RTLD_LOCAL), поэтому никто не может видеть там никаких символов, если не использовать явный dlopen, за которым следует dlsym.

Если бы это был Linux, я мог бы продвинуть пакет в глобальное пространство имен, dlopen снова пометив его флагом RTLD_GLOBAL, но в Mac OS X это не работает. Но Mac OS X прекрасно упаковывает вещи в пакеты, поэтому я просто создал динамическую библиотеку и поместил ее в каталог пакетов плагинов. Библиотека загружается автоматически как RTLD_GLOBAL, и все символы Python доступны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...