170 похожих чатов

Вопрос граничащий с билдсистемами — но для начала интересует теоретический

аспект, а не конкретные флажки компилятора.

Ситуация — есть libmycompany.a (в первую очередь важен линукс, но винда и мак тоже пригодятся) с каким-то нашим кодом.
Есть libthirdparty.a (именно статическая) с условным opencv/boost/чемугодно, которым наш код активно пользуется.
Наконец есть какой-то client.exe, который хочет пользоваться нашей libmycompany — но не хочет знать про используемую у нас libthirdparty; вместо этого хочет пользоваться своей версией оной, статической или динамической — и при этом не иметь конфликтов по символам

Бытует мнение, будто можно попробовать заменить статическую libmycompany.a на libmycompany.so, и каким-нибудь хитрым образом влинковать в неё libthirdparty.a так, чтобы её символы и наружу не торчали, и для нашего кода резолвились всегда однозначно.

Такое вообще реализуемо? Не влечёт за собой UB? Не порождает подводные камни в неожиданных местах? Платформоспецифично, или более-менее стандартизировано?
Или может вообще копать нужно в другую сторону?

15 ответов

9 просмотров

а в чем хитрость линковки состоит? если вспомнить, что такое .a, то кажется никаких проблем сделать сошку нет, если там конечно с -fPic собрали

-fvisibility=hidden?

Могу порекомендовать один механизм: https://gcc.gnu.org/wiki/Visibility Попробуйте для начала свою версию libthirdparty.a собирать с -fvisibility=hidden

Igor-Ivanov Автор вопроса
Denis P
а в чем хитрость линковки состоит? если вспомнит...

Хитрость состоит в отсутствии вот этого чёткого понимания "что такое .а" у всех участников процесса)) Вроде и кажется, что должно сработать, но грызут сомнения.

Igor-Ivanov Автор вопроса
Daniil Tarakanov
Могу порекомендовать один механизм: https://gcc.gn...

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

Igor Ivanov
Я правильно понимаю, что на этапе линковки поменят...

Видимость это понятие - для линкера. На этапе линковки можно использовать свои собственные линкерные скрипты и прятать символы по своему. Но это порядком сложнее перноса в namespace.

Igor-Ivanov Автор вопроса
Daniil Tarakanov
Видимость это понятие - для линкера. На этапе линк...

Вот заметил упоминание linker scripts в скинутой статье, но как-то очень беспросветно звучит в контексте плюсовых либ. Ничего в духе ld -la -lb --hide=on -lc -ld --hide=off -le не предусмотрено, как я понимаю?

Igor Ivanov
Вот заметил упоминание linker scripts в скинутой с...

Не предусмотренно, но возможно вы найдете подходящие вам примеры решений, это достаточно низкоуровневый механизм, требующий учета особенностей разных платформ: https://sourceware.org/binutils/docs-2.40/ld/Scripts.html

Линкер жёстко следит чтобы ОДР не нарушалось. Поэтому Ваша .либ никак не должна экспортировать симболы, которые могут оконфузить линкер .ехе. Прячьте их в неймспейс. Это самое правильное. Ещё можно через objectcopy переименовывать симболы перед отдачей .либ под .ехе. Я так делаю, но я извращенец.

Int Unsigned
Линкер жёстко следит чтобы ОДР не нарушалось. Поэт...

не так уж и жестко он следит) пару inline там и сям (можно даже без inline) и ODR-violation прошел незамеченным

Int Unsigned
Линкер жёстко следит чтобы ОДР не нарушалось. Поэт...

жестко следит только компилятор с named modules

Qt реализует вашу идею. Соответственно наружу не экспортируем никакие символы из сторонних либ. Также внутри оборачиваем в неймспесы плюсовые либы, а сишные обмазываем дефайнами. Готово, наш исполняемый файл может использовать две копии одной библиотеки

Такое реализуемо, но это однозначно UB, если вдруг client.exe тоже захочет прилинковать libthirdparty.a Ну и к сожалению, 'но не хочет знать про используемую у нас libthirdparty.a' - это тоже какая-то утопия, он должен, обязан знать чтобы правильно собирать своё приложение. Технический момент: может быть даже в Linux так сделать вообще невозможно, потому что линкер реально проверяет всё при загрузке исполняемого модуля, в Win это точно возможно, потому что шинковка полностью выполняется только при сборке

Похожие вопросы

Обсуждают сегодня

А случайно нет ли в паскале штатной возможности передать указатель и количество туда где array of в качестве аргумента?
zamtmn
25
Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
58
Ну раз я пока тут, задам пару глупых вопросов. Зачем писать на ассемблере если компилятор довольно умный, а ассемблер много времени занимает? В каких прикладных задачах сейчас...
Максим Рябцев
20
Я тут за тем, чтобы задать вопрос, так как не знаю ассемблер, учу с/с++. Короче, насколько дорога операция перехода в функцию при ее вызове? Дело в том, что в с++ есть макросы...
Максим Рябцев
12
А какие чаты вообще в ходу? Auto aim? И что еше
do you think you're better off alone? А
13
Привет, нужен совет старших товарищей. Есть глобальная переменная var DefaultDataFolder:string; инициализируем DefaultDataFolder:='a:\_OUT\'; есть примитивная процедур...
Max Otto
14
hello friends. Do you know how can I learn getx? I have a software project that I should deliver it up to 5 weeks later and I need to learn firebase too. I will be thankfull
AmirHossein Razavi
15
Доброе время суток! у меня тут иноды закончились. и понял почему по сути кстит, я периодически очищаю постгрес и сентри контайнер: postgres=# DELETE FROM nodestore_node WHER...
Юсиф Насиров
9
Вопрос. Теоретический. Есть список команд. Команды отправляю в обработку некой функции, по очереди. Разные команды могут давать разные результаты после обработки. В зависимос...
Serjone
7
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
Карта сайта