Объединение статических библиотек
Предположим, что у меня три статических библиотеки C, на которые ссылается libColor.a, которая зависит от * libRGB. * a, которая, в свою очередь, зависит от libPixel.a. Говорят, что библиотека libColor.a зависит от библиотеки libRGB.a, поскольку в libColor.a есть некоторые ссылки на некоторые из символов, определенных в libRGB.a. Как объединить все вышеупомянутые библиотеки с новым libNewColor.a, который является независимым?
Независимый означает, что новая библиотека должна содержать все символы. Поэтому при связывании мне просто нужно дать -lNewColor. Размер новой библиотеки должен быть минимальным, т.е. Он не должен содержать никаких символов в libRGB.a, который не используется libColor.a и т.д.
Я попробовал удачу с помощью различных опций в команде ar (используется для создания и обновления статических библиотек/архивов).
Ответы
Ответ 1
1/Извлеките ВСЕ объектные файлы из каждой библиотеки (используя ar
) и попытайтесь скомпилировать свой код без библиотек или любого из объектных файлов. Вероятно, вы получите абсолютную загрузку символов undefined. Если вы не получили символы undefined, перейдите к шагу 5.
2/Возьмите первый и узнайте, какой файл объекта удовлетворяет этому символу (используя nm
).
3/Запишите этот объектный файл, затем скомпилируйте свой код, включая новый объектный файл. Вы получите новый список символов undefined или, если они отсутствуют, перейдите к шагу 5.
4/Перейдите к шагу 2.
5/Объедините все объектные файлы в своем списке (если есть) в одну библиотеку (снова с помощью ar
).
Взрыв! Там у вас это есть. Попробуйте связать свой код без каких-либо объектов, но с новой библиотекой.
Все это можно было бы относительно легко автоматизировать с помощью оболочки script.
Ответ 2
Немного используемая функция архиватора GNU - это архив script, это простой, но мощный интерфейс, и он может делать именно то, что вы хотите, например, если вызывается script script.ar
CREATE libNewColor.a
ADDLIB libColor.a
ADDLIB libRGB.a
ADDLIB libPixel.a
SAVE
END
Затем вы можете вызвать ar следующим образом:
ar -M < script.ar
и вы получите libNewColor.a, который содержит все файлы .o из libColor.a libRGB.a и libPixel.a.
Кроме того, вы также можете добавить обычные файлы .o, а также команду ADDMOD:
CREATE libNewColor.a
ADDLIB libColor.a
ADDLIB libRGB.a
ADDLIB libPixel.a
ADDMOD someRandomCompiledFile.o
SAVE
END
Кроме того, очень просто создать эти скрипты в Make файлах, поэтому я обычно создаю несколько общее правило makefile для создания архивов, которые на самом деле генерируют script и вызывают ar на script. Что-то вроде этого:
$(OUTARC): $(OBJECTS)
$(SILENT)echo "CREATE [email protected]" > $(ODIR)/$(ARSCRIPT)
$(SILENT)for a in $(ARCHIVES); do (echo "ADDLIB $$a" >> $(ODIR)/$(ARSCRIPT)); done
$(SILENT)echo "ADDMOD $(OBJECTS)" >> $(ODIR)/$(ARSCRIPT)
$(SILENT)echo "SAVE" >> $(ODIR)/$(ARSCRIPT)
$(SILENT)echo "END" >> $(ODIR)/$(ARSCRIPT)
$(SILENT)$(AR) -M < $(ODIR)/$(ARSCRIPT)
Хотя теперь, когда я смотрю на него, я думаю, что это не сработает, если $(OBJECTS) пуст (т.е. если вы просто хотите объединить архивы без добавления дополнительных объектных файлов), но я оставлю это как упражнение для читателя при необходимости исправить эту проблему...: D
Вот документы для этой функции:
https://sourceware.org/binutils/docs/binutils/ar-scripts.html#ar-scripts
Ответ 3
Статическая библиотека не намного больше, чем архив некоторых объектных файлов (.o). Вы можете извлечь все объекты из двух библиотек (используя "ar x" ), а затем использовать "ar", чтобы связать их вместе в новой библиотеке.