Если кто-то создает статические библиотеки в своих сценариях сборки и хочет использовать эти статические библиотеки в При связывании последнего исполняемого файла важен порядок упоминания файлов .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 с. Думаю, оно того стоит.
Код здесь . Я поместил его в общественное достояние :)