ar в существующем файле .a?

#unix #gcc #makefile #archive

#unix #gcc #makefile #Архив

Вопрос:

По сути, то, что я хочу сделать, это:

 gcc foo.c -o foo.o
ar rcs foo.a foo.o
gcc bar.c -o boo.o
ar rcs bar.a bar.o foo.a
  

Я хочу заархивировать как объект, так и статическую библиотеку в другую статическую библиотеку. К сожалению, последняя команда в конечном итоге не содержит foo.o (она содержит bar.o и foo.a), поэтому, когда я перехожу к этапу компоновки, компоновщик не может найти символы из foo.o.

Есть ли способ сделать то, что я хочу здесь? Я делаю все это из make, поэтому я ищу решение, которое не включает извлечение и повторное архивирование объектов (что кажется довольно болезненным). Есть ли способ заставить работать такого рода настройку «архив из другого архива»?

Ответ №1:

На самом деле, вы не хотите архивировать один файл ‘.a’ целиком внутри другого. Возможно, вы захотите заархивировать элементы одного архива в другой — но это совершенно другая операция.

Программа ‘ar’ прекрасно способна хранить исходные файлы, архивированные tar-файлы, HTML-файлы, XML-файлы и практически любой другой тип файлов в формате ‘.a’ (а суффикс ‘.a’ является обычным, не обязательным) — попробуйте как-нибудь. Однако он обрабатывает объектные файлы (и только объектные файлы) особым образом и делает их доступными для использования компоновщиком (‘ld’), но компоновщик использует такие файлы, только если расширение ‘.a’.

Итак, вы хотите иметь две библиотеки:

  1. foo.a содержащий только foo.o
  2. bar.a содержащий bar.o и все объекты из foo.a

Если не делать, как вы предлагаете, и извлекать объекты из foo.a и встраивать их в bar.a , единственной альтернативой является перечисление членов foo.a также как членов bar.a :

 FOO_OBJS = foo.o
BAR_OBJS = bar.o $(FOO_OBJS)

foo.a: $(FOO_OBJS)
    $(AR) $(ARFLAGS) $@ $(FOO_OBJS)
bar.a: $(BAR_OBJS)
    $(AR) $(ARFLAGS) $@ $(BAR_OBJS)
  

Я предполагаю, что ваш пример свернут. Если это не так, то зачем беспокоиться о двух библиотеках. Все, что использует только код из foo.o, будет ссылаться только на foo.o, даже если задан bar.a, с которым нужно связать. (Было бы немного иначе, если бы это были общие объекты, но, вероятно, все равно было бы лучше использовать только один, а не два общих объекта.)

Ответ №2:

 ar rcs foo.a foo.o
cp foo.a foo2.a
gcc -c bar.c
ar rs foo2.a bar.o
  

И, возможно, используйте foo.a вместо foo2.a , если вам не нужно сохранять его в первоначальном виде.