Архивные файлы представляют собой файлы, содержащие именованные подфайлы, называемые элементами; они обрабатываются с помощью программы ar и основное их использование - в качестве библиотек подпрограмм для компоновки.
Отдельный элемент архивированного файла может использоваться р программе make в качестве цели или зависимости. Вы указываете элемент с именем ЭЛЕМЕНТ в архивном файле с именем АРХИВ следующим образом:
АРХИВ(ЭЛЕМЕНТ)
Эта структура доступна только в целях и зависимостях, но не в
командах! Большинство программ, которые вы можете использовать в
командах не поддерживают этот синтаксис и не могут работать
непосредственно с элементами архивов. Только программа ar и другие
программы, специально созданные для работы с архивами, могут это
сделать. Следовательно, корректные команды для обновления цели,
являющейся элементом архива, вероятно, должны использовать программу ar.
Например, приведенное ниже правило указывает создать в архиве 'foolib'
элемент 'hack.o' путем копирования файла 'hack.o':
foolib(hack.o) : hack.o ar
cr foolib hack.o
Фактически, почти все цели, являющиеся элементами архивов,
обновляются только таким способом и существует неявное правило,
которое делает это за вас. Примечание: программе ar требуется опция 'c',
если архивный файл еще не существует.
Для того, чтобы указать на несколько элементов одного и того же архива, вы написать вместе внутри скобок все имена элементов. Например, следующий фрагмент make-файла:
foolib(hack.o kludge.o)
эквивалентен такому фрагменту:
foolib(hack.o) foolib(kludge.o)
Вы можете также при ссылке на элемент архива использовать шаблоны в
стиле командной оболочки. Смотрите раздел 4.2 [Использование шаблонных
символов в именах файлов]. Например, 'foolib(*.o)' преобразуется в
список всех существующих элементов архива 'foolib', имена которых
заканчиваются на '.o', возможно, это будет такой список: 'foolib(hack.o)
foolib(kludge.o)'.
Напомним, что цель, представленная в виде 'a(m)', означает элемент архивного файла a с именем m.
Когда программа make ищет неявное правило для такой цели, в качестве специальной возможности, он рассматривает неявные правила, с которыми сопоставляется '(m)', наравне с теми правилами, с которыми сопоставляется настоящая цель 'a()'.
Это приводит к сопоставлению с одним специальным правилом, целью которого является '(%)'. Это правило обновляет цель 'a()' с помощью копирования в архив файла m. Например, он обновит цель 'foo.a(bar.o)', являющуюся элементом архива с помощью копирования в архив 'foo.a', в качестве элемента с именем 'bar.o', файла 'bar.o'.
Когда это правило, объединяется в цепочку с другими, это приводит к очень мощному результату. Так, команды 'make "foo.a(bar.o)"' (кавычки необходимы для того, чтобы защитить символы '(' и ')' от специальной интерпретации со стороны командной оболочки), при наличии файла 'bar.c', достаточно для того, чтобы, даже без make-файла, привести к выполнению следующих команд:
cc -c bar.c -o bar.o ar
r foo.a bar.o rm -f
bar.o
В данном случае программа make увидела в файле 'bar.o' промежуточный
файл. Смотрите раздел 10.4 [Цепочки неявных правил].
Неявные правила, как, например, рассмотренное, пишутся с использованием автоматической переменной '$%'. Смотрите раздел 10.5.3 [Автоматические Переменные].
В архиве имя элемента архива не может содержать имени каталога, но в make-файле может быть полезным сделать вид, что оно может это делать. Если вы указываете элемент 'foo.a(dir/file.o)' , являющийся элементом архива, то программа make выполнит автоматическое обновление с помощью такой команды:
ar r foo.a dir/file.o
действия которой состоят в копировании файла 'dir/file.o' элемент архива
с именем 'file.o'. При таком использовании, могут быть полезными
автоматические переменные '%D' и 'F'.
Архивный файл, используемый в качестве библиотеки, обычно содержит специальный элемент с именем '__.SYMDEF', который содержит каталог внешних имен символов, определенных всеми другими элементами архива. После того, как вы обновите любые другие элементы архива, вам потребуется обновить '__.SYMDEF', для того, чтобы он содержал корректную суммарную информацию о других элементах архива. Это делается посредством запуска программы ranlib:
ranlib АРХИВНЫЙ_ФАЙЛ
Обычно вам следует установить эту команду в правило для архивного
файла и сделать все элементы архивного файла зависимостями этого
правила. Например,
libfoo.a: libfoo.a(x.o) libfoo.a(y.o)...
ranlib libfoo.a
Действие этого правила заключается в обновлении элементов архива 'x.o',
'y.o', и т.п., и последующем обновлении элемента '__.SYMDEF',
являющегося символьным каталогом, посредством запуска программы ranlib.
Правила для обновления элементов здесь не показаны - вероятнее всего, вы
можете опустить их и использовать неявное правило, которое копирует
файлы в архив, как описано в предыдущем разделе.
Это не является необходимым при использовании GNU-версии программы ar, которая обновляет элемент '__.SYMDEF' автоматически.
Важно быть внимательным при использовании параллельного выполнения (опция -j, смотрите раздел 5.3 [Параллельное выполнение]) и архивов. Если одновременно запускаются несколько команд ar, работающие с одним и тем же архивным файлом, они не будут знать друг о друге и могут повредить файл.
Возможно, будущая версия программы make обеспечит механизм, для обхода этой проблемы с помощью упорядочивания всех команд, которые работают с одними и теми же архивными файлами. Но в настоящее время вы должны либо писать ваши make-файлы так, чтобы каким-нибудь другим способом избежать этой проблемы, либо не использовать опцию '-j'.
Вы можете написать суффиксное правило специального вида, которое бы имело дело с архивными файлами. Смотрите раздел 10.7 [Суффиксные правила], где в полной мере объясняются суффиксные правила. Архивные суффиксные правила являются устаревшими GNU-версии программы make, поскольку шаблонные правила для архивов представляют собой более общий механизм (смотрите раздел 11.2 [Обновление архивов]). Тем не менее, они сохранены для совместимости с другими версиями программы make.
Для того, чтобы написать суффиксное правило для архивов, вы просто пишете суффиксное правило с использованием суффикса цели '.a' (обычный суффикс для архивных файлов). Например, ниже привкдкно устаревшее суффиксное правило для обновления библиотечного архива из исходных C-файлов:
.c.a:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $*.o $(AR)
r $@ $*.o $(RM) $*.o
Этот фрагмент make-файла работает точно так же, как если бы вы написали
такое шаблонное правило:
(%.o): %.c $(CC)
$(CFLAGS) $(CPPFLAGS) -c $< -o $*.o $(AR) r
$@ $*.o $(RM) $*.o
Фактически, здесь просто показано то, что делает программа make,
когда она видит суффиксное правило с '.a' в качестве суффикса цели.
Любое правило двойного суффикса '.x.a' преобразуется в шаблонное правило
с шаблоном цели '(%.o)' и шаблоном зависимости '%.x'.
Поскольку вы могли бы захотеть использовать '.a' в качестве для какого-нибудь другого типа файла, программа make также преобразует архивные суффиксные правила в шаблонные правила и обычным способом (смотрите раздел 10.7 [Суффиксные правила]). Таким образом, правило двойного суффикса '.x.a' порождает два шаблонных правила: '(%.o): %.x' и '%.a: %.x'.