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

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

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

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

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

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

15 ответов

28 просмотров

а в чем хитрость линковки состоит? если вспомнить, что такое .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 это точно возможно, потому что шинковка полностью выполняется только при сборке

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

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

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
1
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Карта сайта