Правильный способ связать статическую библиотеку с помощью GCC - PullRequest
22 голосов
/ 31 марта 2012

Почему некоторые статические библиотеки (lib * .a) могут быть связаны так же, как общие библиотеки (lib * .so) связаны (переключатель ld -l), а некоторые нет?

Меня всегда учили, что все библиотеки, статические или нет, могут быть связаны с -l ..., однако я натолкнулся на одну библиотеку (GLFW), которая ничего не делает, кроме как выдает ошибки ссылки "неопределенная ссылка"если я попытаюсь связать его таким образом.

Согласно ответу на этот вопрос , "правильный" способ связать статические библиотеки - включить их напрямую вместе с моими собственными объектными файламивместо использования -l.И, в случае библиотеки GLFW, это, безусловно, решает проблему.Но любая другая статическая библиотека, которую я использую, прекрасно работает, когда она связана с -l.

Итак:

  • Что может привести к тому, что эта библиотека не будет работать, когда связана, а не включена напрямую?Если бы я знал причину, возможно, я мог бы отредактировать и перекомпилировать библиотеку, чтобы исправить проблему.
  • Правда ли, что вы не должны связывать статические библиотеки так же, как вы связываете общие библиотеки?(А если нет, то почему нет?)
  • Может ли компоновщик по-прежнему удалять неиспользуемые библиотечные функции из выходного исполняемого файла, когда библиотека напрямую включена таким способом?

Ответы [ 4 ]

25 голосов
/ 02 апреля 2012

Спасибо за ответы!Оказывается, проблема была связана с порядком ссылок.Очевидно, что если вы используете библиотеку, которая в свою очередь имеет другие библиотечные зависимости, эти другие зависимости должны быть перечислены после библиотеки, а не до того, как я делал.Узнал что-то новое!

6 голосов
/ 31 марта 2012

Правильный способ связать статическую библиотеку - использовать -l, но это работает только в том случае, если библиотеку можно найти в пути поиска.Если это не так, вы можете добавить каталог в список, используя -L или назвать файл по имени, как вы говорите.

То же самое верно для разделяемых библиотек, на самом деле, хотя они, вероятно, будут найдены.

5 голосов
/ 31 марта 2012

Вы хотели указать GCC путь вашей библиотеки (используя -L)? Используя только -l, GCC сможет связывать только библиотеки, доступные в стандартных каталогах.

-L[path] -l[lib]
1 голос
/ 31 марта 2012

Причина историческая.Инструмент "ar" был первоначально инструментом для архивирования файлов в PDP11 Unix, хотя позже он был полностью заменен на "tar" для этой цели.Он хранит файлы (в данном случае объектные файлы) в пакете.И есть отдельное расширение, содержащее таблицу символов для использования компоновщиком.Это возможно, если вы вручную управляете файлами в архиве, чтобы таблица символов могла устареть.

Краткий ответ заключается в том, что вы можете использовать инструмент ranlib в любом архиве для воссоздания таблицы символов.Попробуй это.В более широком смысле, попытайтесь выяснить, откуда берутся поврежденные библиотеки, и исправьте это.

...