Объединение статических библиотек

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