Я пишу числовой код, в котором я хотел бы использовать стороннюю написанную общую библиотеку. Я работаю над архитектурой x86_64 k8 под CentOS. Желаемой целью, которую я хотел бы построить, был бы модуль расширения Python или Matlab, которые, как я понимаю, представляют собой динамически связанные библиотеки, созданные с помощью gcc, с дополнительными встроенными скаффолдами Matlab / Python. Я сосредоточусь здесь, на Python, возникает та же проблема, и она, вероятно, более знакома сообществу.
Разработчик библиотеки изначально предоставил мне динамическую библиотеку и некоторый тестовый код, написанный на C ++. Вот как он собирался распространять свою библиотеку. Я должен отметить, что я стараюсь обременить первоначального разработчика как можно меньше, поскольку библиотека, вероятно, была для него сторонним проектом некоторое время назад, и его тестовый код в итоге работает нормально. Поэтому я пытаюсь решить проблемы с моей стороны в максимально возможной степени с моей стороны. Мне удалось встроить его примеры в исполняемые файлы, только с помощью gcc 4.5.0. Обычная версия gcc, которую я использую, 4.1.2, выдает четыре «неопределенных ссылки на» ошибки во время компоновки (с g ++), в частности, _M_insert<long>(long)
, _M_widen_init()
, _M_insert<double>(double)
и __ostream_insert<char, std::char_traits<char> >
. Все они являются частью пространства имен std
. Компиляция с g ++ 4.5.0 разрешила эти неопределенные ссылки, и примеры исполняемых файлов работают правильно. В комментарии Е.Р. readelf -x.comment libmaxent_k8.so
указано, что исходные библиотеки были собраны с помощью gcc 4.4.1.
Чтобы проверить, работает ли связь с расширением Python, я построил небольшую функцию расширения Python в C ++, которая просто добавляет два числа. В частности, он не использует ничего из библиотеки, которую я хотел бы использовать. Интерфейс был сгенерирован SWIG 2.0, скомпилирован с g ++ 4.50. и код отлично работает в Python 2.4.3. Однако, когда я пытаюсь связаться с исходной библиотекой, не ссылаясь ни на какие символы из нее, код снова связывается нормально, но затем во время выполнения, при импорте расширения, я получаю ImportError: libmaxent_k8.so: undefined symbol: _ZNSo9_M_insertIlEERSoT_
, который, по c++filt
, равен _M_insert(long)
, который является одним из оригинальных, которые не были определены, когда код C ++ был связан с использованием g ++ 4.1.2.
Я подозреваю, что проблема связана с несовпадающими версиями libstdc ++ во время компоновки и работы Python, но я не знаю, как решить эту проблему. Лучший сценарий для меня позволил бы мне как-то обойтись без gcc 4.5.0 при связывании расширений, возможно, я забегал вперед при решении исходной проблемы с 4 отсутствующими ссылками. Может ли проблема быть решена путем статического связывания bing с статической связью с libstdc ++ 6.0.14 (которая является частью gcc 4.5.0), при этом сохраняя их характер как динамически связанных библиотек? Хотя у Python нет проблем с взаимодействием с gcc 4.5.0, Matlab делает, и их поддержка требует надежности только до gcc 4.2.0. По этой причине я хотел бы как можно меньше избегать компиляции с 4.5.0. Мой gcc поставляется с 6.0.8 версией libstdc ++.
Вот несколько отчетов по рассматриваемой библиотеке. Помните, что, несмотря на все эти ссылки, код работал при компиляции непосредственно в исполняемый файл.
$ readelf -aD /home/mbudisic/lib64/libmaxent_k8.so | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ ldd -d libmaxent_k8.so
undefined symbol: _ZSt4cerr (./libmaxent_k8.so)
undefined symbol: _ZNSt8ios_base4InitD1Ev (./libmaxent_k8.so)
undefined symbol: _ZSt4cout (./libmaxent_k8.so)
undefined symbol: __gxx_personality_v0 (./libmaxent_k8.so)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b92457f3000)
libc.so.6 => /lib64/libc.so.6 (0x00002b9245a01000)
/lib64/ld-linux-x86-64.so.2 (0x000000366e200000)
Запуск nm -uC libmaxent_k8.so
приводит к 35 символам, помеченным буквой «U», и двум символам, помеченным буквой «w», из библиотек libm и libstdc ++, что гораздо больше, чем указано как неопределенное при компоновке / запуске.