Статическое и динамическое / общее связывание с MinGW

Я хочу начать с простого использования ссылок, чтобы объяснить свою проблему. Предположим, что существует библиотека z, которую можно скомпилировать в общую библиотеку libz.dll (D: /libs/z/shared/libz.dll) или в статическую библиотеку libz.a (D: / libs / z / static / libz .a).

Позвольте мне дать ссылку на это, тогда я сделаю так:

gcc -o main.exe main.o -LD:/libs/z/static -lz

Согласно этой документации, gcc будет искать libz.a, который

архивные файлы, членами которых являются объектные файлы

Еще я умею:

gcc -o main.exe main.o -LD:/libs/z/shared -lz

В документации выше не упоминается, что флаг -l будет искать lib<name>.so.

Что будет, если у меня libz.a и libz.dll окажутся в одном каталоге? Как библиотека будет связана с программой? Зачем мне нужны флаги -Wl,-Bstatic и -Wl,-Bdynamic, если -l ищет как общие, так и статические библиотеки?

Почему некоторые разработчики предоставляют файлы .a с файлами .dll для одних и тех же модулей, если я компилирую дистрибутив разделяемой библиотеки?

Например, Qt предоставляет файлы .dll в каталоге bin с файлами .a в каталоге lib. Это одна и та же библиотека, но построенная как общая и статическая соответственно? Или файлы .a - это какие-то фиктивные библиотеки, которые обеспечивают связь с разделяемыми библиотеками, где есть реальные реализации библиотек?

Другой пример - библиотека OpenGL в Windows. Почему каждый компилятор должен предоставлять статическую библиотеку OpenGL, такую ​​как libopengl32.a в MingW?

Для чего используются файлы с расширениями .dll.a и .la?

P.S. Здесь много вопросов, но я думаю, что каждый зависит от предыдущего, и нет необходимости разбивать их на несколько вопросов.


person Yuki    schedule 06.04.2013    source источник
comment
Возьмем пример cygwin: насколько я понимаю, программы, скомпилированные с помощью cygwin, нуждаются в определенной dll для запуска. DLL привязана к определенной лицензии (одной из бесплатных) и должна присутствовать в хост-системе для программы. Если вы, как разработчик, забудете отправить его вместе с программой, программа не запустится. Другой пример - конфликтующие версии DLL (например, opengl). каждая система имеет разные возможности и, следовательно, разные реализации определенных DLL. Поэтому иногда разработчикам нравится использовать правильную версию библиотеки = ›статическая ссылка.   -  person scones    schedule 06.04.2013


Ответы (1)


Обратите внимание на ld и WIN32 (cygwin / mingw). В частности, раздел прямая ссылка на dll для получения дополнительной информации о поведении флага -l на портах Windows LD. Извлекать:

Например, когда ld вызывается с аргументом -lxxx, он попытается найти в первом каталоге своего пути поиска,

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll

перед переходом к следующему каталогу в пути поиска.

(*) На самом деле это не cygxxx.dll, а на самом деле <prefix>xxx.dll, где <prefix> устанавливается опцией ld -dll-search-prefix=<prefix>. В случае cygwin стандартный файл спецификации gcc включает -dll-search-prefix=cyg, поэтому фактически мы ищем cygxxx.dll.

ПРИМЕЧАНИЕ. Если вы когда-либо создавали Boost с помощью MinGW, вы, вероятно, помните, что именование библиотек Boost в точности подчиняется шаблону, описанному в приведенной выше ссылке.

Раньше в MinGW были проблемы с прямой ссылкой на *.dll, поэтому было рекомендовано создать статическую библиотеку lib*.a с экспортированными символами из *.dll и вместо этого связать ее. Ссылка на эту вики-страницу MinGW теперь мертва, поэтому я предполагаю, что теперь будет нормально ссылаться непосредственно на *.dll. Более того, я сам делал это несколько раз с последним дистрибутивом MinGW-w64, и пока никаких проблем не было.

Вам нужны флаги ссылок -Wl,-Bstatic и -Wl,-Bdynamic, потому что иногда вы хотите принудительно выполнить статическое связывание, например, когда динамическая библиотека с тем же именем также присутствует в пути поиска:

gcc object1.o object2.o -lMyLib2 -Wl,-Bstatic -lMyLib1 -Wl,-Bdynamic -o output

Приведенный выше фрагмент гарантирует, что приоритет связывания по умолчанию, установленный флагом -l, переопределен для MyLib1, т.е. даже если MyLib1.dll присутствует в пути поиска, LD выберет libMyLib1.a для связывания. Обратите внимание, что для MyLib2 LD снова предпочтет динамическую версию.

ПРИМЕЧАНИЕ. Если MyLib2 зависит от MyLib1, то MyLib1 также динамически связывается, независимо от -Wl,-Bstatic (т. е. в данном случае игнорируется). Чтобы этого не произошло, вам также придется связывать MyLib2 статически.

person Alexander Shukaev    schedule 06.04.2013
comment
Ссылка мертва ... у вас есть ссылка на это вы можете обновить для ответа. - person maple_shaft; 17.02.2021
comment
@maple_shaft, готово! - person Alexander Shukaev; 19.02.2021