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