LINUX.ORG.RU

Использование двух библиотек использующих один набор символов без пересборки

 , , ,


2

6

Собственно хочется провернуть сабж без пересборки библиотек и без использования dlopen.

Upd. небольшая поправочка, (думал dlopen наведёт на мысль), библиотеки в смысле shared object.

Upd. RTLD_DEEPBIND надо бы почитать про него повнимательней.

★★★★★

Теоретически можно написать две библиотеки-обертки и поместить оригинальные имена под неймспесы.

KennyMinigun ★★★★★ ()
Ответ на: комментарий от ilammy

LD_PRELOAD вроди же попросту подменяет символы других библиотек?

KennyMinigun ★★★★★ ()

Добавь префиксы именам через objcopy.

Vovanano ()
Ответ на: комментарий от KennyMinigun

Но при запуске две целевые библиотеки одна фигня притащатся загрузчиком в итоговый образ - тут разве не будут пересекаться символы?

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Ну, я написал «теоретически».Т.е. основываясь на факте, что рантайм линкер может разрулить линковку для двух разных бинарников с разными библиотеками, предоставляющими одинаковые символы.

// Аж захотелось попробовать

KennyMinigun ★★★★★ ()
Ответ на: комментарий от KennyMinigun

Да, я из доки однозначно не понял разрулит или нет. Ближе к вечеру надо бы попробовать, главное не забиыть

pon4ik ★★★★★ ()

без использования dlopen.

Он же для того и придуман.

PPP328 ★★ ()
Ответ на: комментарий от PPP328

Тут дело в массовости. 5 функций - я бы даже не задумывался. 100 функций - печаль, но чего делать. 1к+ функций - надо бы на лоре спросить.

Грубо, но примерно столько:) :

localhost-> bc <<< "$(find -name '*.so.*' | xargs nm  2>/dev/null | grep -v : | wc -l) / 4"
12292

pon4ik ★★★★★ ()
Последнее исправление: pon4ik (всего исправлений: 2)
Ответ на: комментарий от pon4ik

Точнее столько:

find -name '*.so.*' | xargs nm  2>/dev/null | grep " T " | sort | uniq | wc -l
8859

В общем на решение в ручную - не тянет.

pon4ik ★★★★★ ()
Последнее исправление: pon4ik (всего исправлений: 2)
Ответ на: комментарий от pon4ik

1к+ функций - надо бы на лоре спросить.

Допустим, загрузил ты несколько таких библиотек. Что ты будешь делать с 1k+ функциями? Вызывать?

i-rinat ★★★★★ ()

Ты имеешь в виду, что в одном бинарнике две эти библиотеки используются одновременно, или они взаимозаменяются?

annulen ★★★★★ ()
Ответ на: комментарий от pon4ik

Сгенерируй два хэдера автоматически, делов на 20 минут баша.

PPP328 ★★ ()
Ответ на: комментарий от PPP328

Тэг c++ - тебя не смутил. Сколько стоит «20» минут твоего времени? Возможно действительно стоит в job?

pon4ik ★★★★★ ()
Ответ на: комментарий от i-rinat

Ну соль в том, что бинарников сотни. Конечно всё множество вызовов не покроется, однако, решение ручками да ещё и для плюсов тут имхо не годится.

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

Это понятно, что когда по заданному вопросу нет идей ищется обходной путь, но тут нужно именно то, что нужно :)

pon4ik ★★★★★ ()
Ответ на: комментарий от PPP328

Ну, и это - ты всерьёз думаешь что ~8к символов определены в одном хидере и в одной либе?

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

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

В таком случае лучше все-таки использовать эти либы в разных бинарях, или пересобрать обе с --wrap чтобы они не пересекались.

annulen ★★★★★ ()
Ответ на: комментарий от pon4ik

А как это в деталях? Пользователь вызывает функцию library_select(int), а затем все вызовы функций перенаправляются в выбранную библиотеку? Тогда можно только одну из библиотек загружать.

Похоже, ты пытаешься решить ту же проблему, что решает подход glXGetProcAddress(), только с помощью манки-патчинга.

i-rinat ★★★★★ ()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от pon4ik

Я попробовал. Не работает.

Вот моя песочница (чтоб не морочится с нуля): http://paste.ubuntu.com/24714305/ (не нашел адекватных обменников, потому так по извращенчески)

KennyMinigun ★★★★★ ()
Ответ на: комментарий от pon4ik

Ну соль в том, что бинарников сотни. Конечно всё множество вызовов не покроется, однако, решение ручками да ещё и для плюсов тут имхо не годится.

Я бы реально задумался над переименованием символов с помощью objcopy. Ибо самое автоматизированное решение.

Кстати, вопрос: тебе надо чтоб можно было в одном бинарнике использовать символы с одинаковыми именами с разныз либ? Или же подходит вариант «выбрать только одну реализацию»

KennyMinigun ★★★★★ ()
Ответ на: комментарий от KennyMinigun

Я попробовал. Не работает.

Спасибо.

Кстати, вопрос: тебе надо чтоб можно было в одном бинарнике использовать символы с одинаковыми именами с разныз либ? Или же подходит вариант «выбрать только одну реализацию»

Вопрос стоит так: нужно из бинарника на основе одной либы вызвать функционал на основе другой либы. И тут уже надо думать либо можно это сделать на уровне реализации загрузчика, либо решать архитектурно, разделив либы с помощью ipc. Учитывая, что пересекающиеся либы и делают всё то же самое, то так же стоит рассмотреть вариант выкинуть одну из них. Вопрос как всегда в трудозатратах.

pon4ik ★★★★★ ()
Ответ на: комментарий от i-rinat

В деталях более высокоуровнево могу:

Пользователь написал бинарник B используя либу A используя класс Foo. Другой пользователь написал либу L, используя либу A1 и класс Foo.

Либу L надо вызывать из бинарника B.

Кстати вот в этой точке, уже допустимо использовать и позднее связывание вполне т.к. телодвижений будет на порядки меньше.

pon4ik ★★★★★ ()
Последнее исправление: pon4ik (всего исправлений: 2)
Ответ на: комментарий от pon4ik

То есть тебе нужно разруливать зависимости зависимостей? Задача не выглядит решаемой. Тут действительно нужно менять способ, которым код связывается.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

Мне нужно сделать по большому счёту так, что бы динамический линкер разрешил зависимости для бинаря отдельно а для его зависимостей отдельно. Как по мне - юзекейс жизненый, странно, что разработчики поделия об этом не задумались(если не задумались конечно).

pon4ik ★★★★★ ()
Ответ на: комментарий от i-rinat

RTLD_DEEPBIND - для dlopen, есть то что нужно. Теперь надо понять можно ли и если можно то как, заставить загрузчик вести себя так же с либой в таблице импорта.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Кстати вот в этой точке, уже допустимо использовать и позднее связывание вполне т.к. телодвижений будет на порядки меньше.

Кажется решение найдено с условием использования dlopen в этой точке.

RTLD_DEEPBIND (since glibc 2.3.4)
              Place the lookup scope of the symbols in this shared object
              ahead of the global scope.  This means that a self-contained
              object will use its own symbols in preference to global
              symbols with the same name contained in objects that have
              already been loaded.

Ну и расплатой за сиё счастие будет маршалинг типов из обеих либ в третье представление которое можно будет использовать в на обоих концах решения.

pon4ik ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.