Если кто-то строит статические библиотеки в своих скриптах сборки, и кто-то хочет использовать эти статические библиотеки для компоновки конечного исполняемого файла, важен порядок, в котором упоминаются файлы .a
:
g++ main.o hw.a gui.a -o executable
Если gui.a
использует что-то, определенное в hw.a
, ссылка потерпит неудачу, потому что во время обработки hw.a
компоновщик еще не знает, что определение понадобится позже, и не включает его в исполняемый файл.Вручную возиться с линией компоновщика нецелесообразно, поэтому решение состоит в том, чтобы использовать --start-group
и --end-group
, что заставляет компоновщик дважды проходить по библиотекам, пока не будут найдены неопределенные символы.
g++ main.o -Wl,--start-group hw.a gui.a -Wl,--end-group -o executable
Однако в руководстве GNU ld говорится:
Использование этой опции приводит к значительным потерям производительности.Лучше всего использовать его только тогда, когда между двумя или более архивами есть неизбежные циклические ссылки.
Поэтому я подумал, что может быть лучше взять все файлы .a
и собрать их в один .a
файл с индексом (опция -s
в GNU ar), который говорит, в каком порядке файлы должны быть связаны.Тогда каждый дает только один .a
файл g++
.
Но мне интересно, будет ли это быстрее или медленнее, чем использование групповых команд.И есть ли проблемы с этим подходом?Мне также интересно, есть ли лучший способ решить эти проблемы взаимозависимости?
РЕДАКТИРОВАТЬ: я написал программу, которая принимает список .a
файлов и создает объединенный файл .a
.Работает с общим форматом GNU ar
.Сборка всех статических библиотек LLVM работает следующим образом
$ ./arcat -o combined.a ~/usr/llvm/lib/libLLVM*.a
Я сравнил скорость с распаковкой всех файлов .a
вручную, а затем поместил их в новый файл .a
с помощью ar
, пересчитав индекс,Используя мой arcat
инструмент, я получаю постоянную продолжительность работы около 500 мс.Используя ручной способ, время сильно меняется, и занимает около 2 с.Поэтому я думаю, что оно того стоит.
Код здесь .Я положил это в общественное достояние:)