Поиск динамического символа не выполняется с помощью статически встроенного Python в Mac OS X

Я создаю приложение 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

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

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

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

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