#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’.
Итак, вы хотите иметь две библиотеки:
foo.a
содержащий толькоfoo.o
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
, если вам не нужно сохранять его в первоначальном виде.