Вперед Назад Содержание

11. Использование make для обновления архивных файлов

Архивные файлы представляют собой файлы, содержащие именованные подфайлы, называемые элементами; они обрабатываются с помощью программы ar и основное их использование - в качестве библиотек подпрограмм для компоновки.

11.1 Элементы архивов в качестве целей

Отдельный элемент архивированного файла может использоваться р программе 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)'.

11.2 Неявные правила для целей, являющихся элементами архивов

Напомним, что цель, представленная в виде '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' автоматически.

11.3 Опасности при использовании архивов

Важно быть внимательным при использовании параллельного выполнения (опция -j, смотрите раздел 5.3 [Параллельное выполнение]) и архивов. Если одновременно запускаются несколько команд ar, работающие с одним и тем же архивным файлом, они не будут знать друг о друге и могут повредить файл.

Возможно, будущая версия программы make обеспечит механизм, для обхода этой проблемы с помощью упорядочивания всех команд, которые работают с одними и теми же архивными файлами. Но в настоящее время вы должны либо писать ваши make-файлы так, чтобы каким-нибудь другим способом избежать этой проблемы, либо не использовать опцию '-j'.

11.4 Суффиксные правила для архивных файлов

Вы можете написать суффиксное правило специального вида, которое бы имело дело с архивными файлами. Смотрите раздел 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'.


Вперед Назад Содержание