Конфликты имен общих библиотек

Я распространяю общую библиотеку (С++) и модуль Python, который использует эту библиотеку. Я создаю модифицированную версию Bullet Physics Library (как подпроект CMake). Я использую классы и функции Bullet только в одном файле --bullet_interface.cpp -- и все содержимое Bullet скрыто внутри "namespace {...}".

Проблема в том, что некоторые другие библиотеки требуют Bullet как системную зависимость и ссылаются на системную версию Bullet. Фактически, одна из зависимостей моей библиотеки (libopenrave) экспортирует символы Bullet. (точнее, иногда он динамически загружает плагин, который экспортирует символы Bullet).

Мне интересно, есть ли способ создать мою библиотеку, чтобы bullet_interface.cpp использовал правильные функции Bullet, но тогда моя библиотека не делает видимыми какие-либо символы Bullet. Я не могу использовать системный маркер, потому что мне пришлось внести изменения в исходный код. Одним из хакерских решений было бы переименовать все функции и классы Bullet с помощью поиска и замены (почти все содержат строку «bt»). Есть ли способ лучше?


person John    schedule 11.02.2013    source источник
comment
Очевидным решением является внесение ваших исправлений в основную Bullet библиотеку и использование THAT в качестве системной библиотеки.   -  person Mark B    schedule 12.02.2013
comment
Можете ли вы просто убедиться, что ваша модифицированная версия загружается первой и удовлетворяет всем зависимостям в других библиотеках, поэтому им не нужна системная версия?   -  person Jonathan Wakely    schedule 12.02.2013
comment
Значит, libopenrave экспортирует символы маркеров и ссылки с библиотекой маркеров, в то время как ваш плагин использует точно такие же символы маркеров и поставляется с модифицированной библиотекой маркеров? Если это так, вы можете попытаться создать свою модифицированную библиотеку маркеров как статическую библиотеку, связать ее со своим плагином и убедиться, что все символы маркеров в вашем плагине скрыты. Ваш код плагина будет использовать их, но они не будут экспортироваться в динамическую таблицу символов. Если make-файлы пули или атрибуты кода явно устанавливают видимость, вам придется взломать ее, возможно, используя binutils для изменения видимости символов перед связыванием объектов?   -  person Al W    schedule 12.02.2013
comment
У меня есть частичное решение, основанное на предложении Ала. (1) Я устанавливаю -fvisibility=hidden и использую макрос DLL_EXPORT для управления видимостью. (2) вместо ссылки на общую библиотеку пули я сделал сборку единства пули (т. е. файл cpp, который включает в себя все файлы пули cpp), и я создаю его вместе с моей общей библиотекой. Теперь моя библиотека не экспортирует символы маркеров. К сожалению, я все еще получаю конфликт имен при загрузке системной общей библиотеки Bullet.   -  person John    schedule 12.02.2013
comment
Что это за платформа? Поведение компоновщика во время выполнения не особенно переносимо...   -  person Useless    schedule 21.02.2013


Ответы (1)


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

Вы можете попробовать «префиксировать» символы в пулевой библиотеке, используя утилиту objcopy следующим образом:

objcopy --prefix-symbols=old_ bullet.a

Это должно работать и с динамической библиотекой, но вам придется попробовать. Подробности см. в этом ответе.

person George Skoptsov    schedule 26.02.2013