Подтвердить что ты не робот

Статическое и динамическое/совместное соединение с 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. Здесь много вопросов, но я думаю, что каждый из них зависит от предыдущего, и нет необходимости разделять их на несколько вопросов.

4b9b3361

Ответ 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 и вместо нее ссылаться на нее. Ссылка на эту wiki-страницу 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 статически тоже.