Подтвердить что ты не робот

Как я могу связать (или работать) две сторонние статические библиотеки, которые определяют одни и те же символы?

Я не могу быть единственным, кто столкнулся с этим.

У меня есть приложение на С++, которое необходимо связать с одной сторонней и другой статической библиотекой, установленной в SDK. SDK по какой-то ужасно расстраивающей причине перекомпилировал подмножество этой же сторонней библиотеки в свою собственную (переименованную) библиотеку lib, хотя сами символы называются одинаковыми, и они не инкапсулированы в пространство имен. Мое приложение зависит от той же сторонней библиотеки.

Я рассмотрел несколько вариантов, но, возможно, мне что-то не хватает, и, надеюсь, свежий взгляд поможет мне. Возможно, я рядом, и кто-то узнает следующий шаг для одного из них. Я буду перечислять то, что я пробовал, и недостатки каждого решения:

  • Связь с обоими. Я получаю около 2500 строк предупреждений о переопределении символов/изменении размера и ошибок. Это когда я впервые обнаружил, что они определили одни и те же символы. Я пытаюсь перекомпилировать OpenSSL с g++ и переместить его в пространство имен на данный момент... см. Ниже...

  • Ссылка только на SDK. Я получаю символы undefined, от которых зависит мой собственный код - это когда я обнаружил, что их перекомпиляция третьей стороны lib является подмножеством или, по крайней мере, была настроена с отключенным одним модулем.

  • Связывается только с третьей стороной lib. У меня есть пара символов undefined, о которых сообщает SDK, - один из них на самом деле является #define в файле заголовка в третьей стороне lib, поэтому все ссылки в третьей стороне lib разрешают определение, но ссылки вне этого не. Я переместил это в файл c, который разрешает это, однако у меня все еще есть две нерешенные функции, которые я не могу найти нигде. Это самое близкое, что я получил до сих пор.

  • Разделите конфликтующие символы из одной библиотеки и ссылки в обоих. Пока это не сработало. Это может быть проблема с версией между lib, статически связанной в SDK, и версиями, которые я пытался использовать сторонней lib, но похоже, что некоторые функции перемещались между символами, поэтому, удалив символ, я случайно удаляю функции, которые мне нужны в другом месте. Кажется, что нет идеального отображения между функциями в символах в SDK и функциями в символах в сторонней библиотеке. Возможно ли разрезать функции без необходимости ручной настройки адресов?

Я изучал символы в библиотеках с помощью:

nm -C --defined-only lib<name>.a

И извлечение целых объектов с помощью

ar -x lib<name>.a <objname>.o

Надеюсь, это также поможет другим, кто должен был связываться с сторонними библиотеками, которые конфликтуют друг с другом. Для специфики, сторонняя библиотека OpenSSL, а SDK Opsec - libcpopenssl.a является нарушителем lib в Opsec.

** РЕДАКТИРОВАТЬ. Возможно, поздняя запись может перекомпилировать OpenSSL с g++ и поместить все это в пространство имен, а затем связать обе библиотеки. Я сейчас пытаюсь... еще впереди...

4b9b3361

Ответ 1

Поиск в Google показывает, что SSL_get_peer_dh и DH_dup действительно являются дополнениями от libcpopenssl.a, и они также не существуют в моей копии OpenSSL. Таким образом, вам действительно нужно будет связать эту библиотеку. Смешивание обеих библиотек вместе (подход 4 выше) на двоичном уровне вряд ли сработает - OpenSSL очень разборчив в отношении своего ABI (обычно они имеют файлы .so с версией до младшего номера), поэтому вам должно быть очень повезло иметь .so что ABI-совместимый с их .a файлом.

Мое предложение - это вариант подхода 4, но на исходном уровне: у вас будет ссылка в Opsec libcpopenssl.a, так как это модифицированная версия OpenSSL, которая включает дополнительные символы (и, возможно, другие модификации), и захватить дополнительные функции, которые вам нужны из источников OpenSSL, и перекомпилировать эти объекты с помощью libcpopenssl.a, чтобы они могли использовать функции из версии Opsec. Если вы используете только несколько функций OpenSSL, которые не экспортируются libcpopenssl.a, это вполне выполнимо.

Конечно, это еще и громоздкий подход, но это гарантированный способ получить совместимость символов, конечно же, что Opsec SDK не внес семантические изменения в OpenSSL, что нарушит дополнительные функции OpenSSL, которые вы втягиваете в свои проект.

(Я новичок в StackOverflow, поэтому не знаю, соответствует ли это предложение правильному ответу, но у меня нет точек репутации, чтобы публиковать комментарии). Я удалю это, если это будет неуместно.)

Ответ 2

Если вам любопытно, 249 файлов были изменены в самой последней версии OpenSSL, чтобы получить ее для компиляции. Наиболее распространенной проблемой на сегодняшний день было обилие бросков указателей стиля С, в частности с void *. Теперь я вижу "reinterpret_cast" во сне.

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

Спасибо за помощь всем.