аспект, а не конкретные флажки компилятора.
Ситуация — есть libmycompany.a (в первую очередь важен линукс, но винда и мак тоже пригодятся) с каким-то нашим кодом.
Есть libthirdparty.a (именно статическая) с условным opencv/boost/чемугодно, которым наш код активно пользуется.
Наконец есть какой-то client.exe, который хочет пользоваться нашей libmycompany — но не хочет знать про используемую у нас libthirdparty; вместо этого хочет пользоваться своей версией оной, статической или динамической — и при этом не иметь конфликтов по символам
Бытует мнение, будто можно попробовать заменить статическую libmycompany.a на libmycompany.so, и каким-нибудь хитрым образом влинковать в неё libthirdparty.a так, чтобы её символы и наружу не торчали, и для нашего кода резолвились всегда однозначно.
Такое вообще реализуемо? Не влечёт за собой UB? Не порождает подводные камни в неожиданных местах? Платформоспецифично, или более-менее стандартизировано?
Или может вообще копать нужно в другую сторону?
а в чем хитрость линковки состоит? если вспомнить, что такое .a, то кажется никаких проблем сделать сошку нет, если там конечно с -fPic собрали
-fvisibility=hidden?
Могу порекомендовать один механизм: https://gcc.gnu.org/wiki/Visibility Попробуйте для начала свою версию libthirdparty.a собирать с -fvisibility=hidden
Хитрость состоит в отсутствии вот этого чёткого понимания "что такое .а" у всех участников процесса)) Вроде и кажется, что должно сработать, но грызут сомнения.
Я правильно понимаю, что на этапе линковки поменять видимость существующих .o/.a уже нельзя, и нужно именно пересобраться с новыми флагами именно у компилятора?
Видимость это понятие - для линкера. На этапе линковки можно использовать свои собственные линкерные скрипты и прятать символы по своему. Но это порядком сложнее перноса в namespace.
Вот заметил упоминание linker scripts в скинутой статье, но как-то очень беспросветно звучит в контексте плюсовых либ. Ничего в духе ld -la -lb --hide=on -lc -ld --hide=off -le не предусмотрено, как я понимаю?
Не предусмотренно, но возможно вы найдете подходящие вам примеры решений, это достаточно низкоуровневый механизм, требующий учета особенностей разных платформ: https://sourceware.org/binutils/docs-2.40/ld/Scripts.html
Линкер жёстко следит чтобы ОДР не нарушалось. Поэтому Ваша .либ никак не должна экспортировать симболы, которые могут оконфузить линкер .ехе. Прячьте их в неймспейс. Это самое правильное. Ещё можно через objectcopy переименовывать симболы перед отдачей .либ под .ехе. Я так делаю, но я извращенец.
не так уж и жестко он следит) пару inline там и сям (можно даже без inline) и ODR-violation прошел незамеченным
жестко следит только компилятор с named modules
Qt реализует вашу идею. Соответственно наружу не экспортируем никакие символы из сторонних либ. Также внутри оборачиваем в неймспесы плюсовые либы, а сишные обмазываем дефайнами. Готово, наш исполняемый файл может использовать две копии одной библиотеки
Такое реализуемо, но это однозначно UB, если вдруг client.exe тоже захочет прилинковать libthirdparty.a Ну и к сожалению, 'но не хочет знать про используемую у нас libthirdparty.a' - это тоже какая-то утопия, он должен, обязан знать чтобы правильно собирать своё приложение. Технический момент: может быть даже в Linux так сделать вообще невозможно, потому что линкер реально проверяет всё при загрузке исполняемого модуля, в Win это точно возможно, потому что шинковка полностью выполняется только при сборке
Можно, должно быть можно
Обсуждают сегодня