2009-03-20 4 views
13

Пусть я три C статические библиотеки говорят libColor.a, которая зависит от * libRGB. * А, в свою очередь, зависит от libPixel.a. Библиотека libColor.a называется зависит от библиотеки libRGB.a, так как есть некоторые ссылки в libColor.a некоторые из символов, определенных в libRGB.a. Как объединить все вышеупомянутые библиотеки с новым libNewColor.a, который является независимым?Комбинирование статические библиотеки

Независимый означает, что новая библиотека должна содержать все символы. Поэтому, пока я связываюсь, мне просто нужно дать -lNewColor. Размер новой библиотеки должен быть минимальным т.е. он не должен содержать любые символы в libRGB.a который не используется libColor.a и т.д. я попробовал свои удачи, используя различные варианты в ар команды (используется для создавать и обновлять статические библиотеки/архивы).

+0

в качестве альтернативы Вы можете посмотреть по адресу: // StackOverflow. com/questions/8170450/comb-static-libraries/8170851 # 8170851 и использовать libt ool – Bruce

+0

Обратите внимание, что шаг минимизации действительно не требуется. Со статическими библиотеками компоновщик будет захватывать только требуемые файлы объектов, в отличие от разделяемых библиотек, которые включают все. Существуют причины и преимущества каждого подхода; они просто разные. И вам действительно не нужно беспокоиться, пока вы работаете со статическими библиотеками. –

ответ

11

1/Извлечь ВСЕ файлы объектов из каждой библиотеки (используя ar) и попытаться скомпилировать ваш код без библиотек или любого из объектных файлов. Вероятно, вы получите абсолютную загрузку неопределенных символов. Если у вас нет неопределенных символов, перейдите к шагу 5.

2/Возьмите первый и выясните, какой файл объекта соответствует этому символу (с использованием nm).

3/Запишите этот объектный файл, затем скомпилируйте свой код, включая новый объектный файл. Вы получите новый список неопределенных символов или, если нет ни одного, переходите к шагу 5.

4/Перейдите к шагу 2.

5/Объединить все объектные файлы в списке (если таковые имеются) в одну библиотеку (опять же с ar).

Bang! Там у вас это есть. Попробуйте связать свой код без каких-либо объектов, но с новой библиотекой.

Все это может быть относительно легко автоматизировано с помощью сценария оболочки.

+2

Необязательно сложный, вы можете просто извлечь все файлы .o в большую .a, так как, когда он, наконец, подключен к исполняемому файлу, компоновщик будет отбрасывать любые неиспользуемые в любом случае – MarkR

+2

@MarkR, @AIB хотел размер * библиотеки * быть минимальным, а не размером исполняемого файла. – paxdiablo

+0

Принимая это, хотя я бы хотел, чтобы он сделал это. Как передача некоторых параметров ld для связи только с необходимыми символами и т. Д. ... – AIB

5

Статическая библиотека не намного больше, чем архив некоторых объектных файлов (.o). Вы можете извлечь все объекты из двух библиотек (используя «ar x»), а затем использовать «ar», чтобы связать их вместе в новой библиотеке.

15

малопроезжей особенностью архиватора GNU является сценарий архива, это простой, но мощный интерфейс, и он может делать то, что вы хотите, если следующий сценарий называется script.ar:

CREATE libNewColor.a 
ADDLIB libColor.a 
ADDLIB libRGB.a 
ADDLIB libPixel.a 
SAVE 
END 

Тогда вы могли бы вызвать ар следующим образом:

ar -M < script.ar 

и вы получите libNewColor.a, который содержит все .o файлы из libColor.a libRGB.a и libPixel.a.

Дополнительно вы также можете добавить обычный.о файлах, а также с команда ADDMOD:

CREATE libNewColor.a 
ADDLIB libColor.a 
ADDLIB libRGB.a 
ADDLIB libPixel.a 
ADDMOD someRandomCompiledFile.o 
SAVE 
END 

Кроме того, это очень легко сгенерировать эти скрипты в Makefiles, поэтому обычно я создаю несколько общие правила Makefile для создания архивов, которые на самом деле создает сценарий и вызывают ага на скрипт. Что-то вроде этого:

$(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) 

Хотя теперь, когда я смотрю на него, я предполагаю, что это не работает, если $ (ОБЪЕКТОВ) пусто (то есть, если вы просто хотите, чтобы объединить архивы без добавления дополнительных объектных файлов), но я буду оставить его в качестве упражнения для читателя, чтобы решить эту проблему, если это необходимо ...: D

Вот документы для этой функции:

https://sourceware.org/binutils/docs/binutils/ar-scripts.html#ar-scripts

+0

Это здорово! За исключением того, что любые пути/библиотеки, имеющие + в имени, нарушают сценарий. Например, openssl имеет libncurses ++. A – Gregory

+0

Neat! Это проще, проще, чем распаковка и переупаковка объектных файлов. – Thomas

+0

Обратите внимание, что по какой-либо причине -D не работает в комбинации с -M. Поэтому, если вы хотите получить детерминированные результаты, вам по-прежнему нужен маршрут extract-then-archive. –

Смежные вопросы