Операционная система UNIX. Руководство программиста

       

Архивные библиотеки


Утилита make предоставляет интерфейс для работы с архивными библиотеками. В файле описаний пользователь может обратиться к элементу библиотеки следующим образом:

библиотека(файл.o)

или

библиотека(точка_входа)

Второй метод является в действительности ссылкой на точку входа в объектном файле, содержащемся в библиотеке. make просматривает библиотеку, обнаруживает точку входа и преобразует ее в корректное имя объектного файла.

Чтобы воспользоваться данной процедурой для поддержания архивной библиотеки, необходим make-файл следующего вида:

projlib:: projlib(pfile1.o) $(CC) -c -O pfile1.c $(AR) $(ARFLAGS) projlib pfile1.o rm pfile1.o projlib:: projlib(pfile2.o) $(CC) -c -O pfile2.c $(AR) $(ARFLAGS) projlib pfile2.o rm pfile2.o . . . и так далее для каждого элемента библиотеки

Это утомительно и чревато ошибками. Очевидно, последовательность команд для включения C-файла в библиотеку повторяется для каждого запуска; единственное отличие заключается в имени файла. (Данное утверждение истинно в большинстве случаев.)

Утилита make предоставляет пользователю правила для построения библиотек. Этим правилам соответствует суффикс .a. Так, правило .c.a - это правило компиляции исходного C-файла, включения его в библиотеку и удаления промежуточного .o-файла. Аналогично, правила .y.a, .s.a и .l.a заново обрабатывают, соответственно, файлы yacc'а, ассемблера и lex'а. Встроенными являются следущие правила для работы с архивами: .c.a, .c~.a, .f.a, .f~.a и .s~.a. (Назначение тильды, ~, будет ниже коротко описано.) В файле описаний пользователь может определить другие необходимые ему правила.

Поскольку встроенные правила для поддержания библиотеки уже определены, упомянутую выше библиотеку, состоящую из двух элементов, можно поддерживать при помощи следующего более короткого make-файла:

projlib: projlib(pfile1.o) projlib(pfile2.o) @echo projlib up-to-date

На самом деле правило .c.a выглядит так:

.c.a: $(CC) -c $(CFLAGS) $< $(AR) $(ARFLAGS) $@ $*.o rm -f $*.o



Здесь макрос $@ обозначает целевой файл (библиотеку projlib); макросы $< и $* устанавливаются равными, соответственно, имени изменившегося C-файла и имени файла без суффикса (pfile1.c и pfile1). Макрос $< (в приведенном выше правиле) можно заменить на $*.c.


Полезно в деталях рассмотреть, как make обрабатывает следующую конструкцию:

projlib: projlib(pfile1.o) @echo projlib up-to-date

Предположим, что объектный файл, содержащийся в библиотеке, по сравнению с pfile1.c устарел. Кроме того, файл pfile1.o отсутствует.

Выполняются следующие действия:

make projlib.

  • При выполнении make projlib сначала проверить все файлы, от которых зависит projlib.


  • Архив projlib зависит от элемента projlib(pfile1.o), который необходимо сгенерировать.


  • Перед тем как генерировать элемент projlib(pfile1.o), проверить все файлы, от которых он зависит. (Таких файлов нет.)


  • Использовать встроенные правила для того, чтобы попытаться создать projlib(pfile1.o). (Встроенного правила нет.) Отметим, что цепочка projlib(pfile1.o) содержит скобки для того, чтобы указать на суффикс целевого файла .a. В конце имени архива projlib суффикс .a явным образом не написан, но скобки его подразумевают. В этом смысле суффикс .a жестко запаян в make.


  • Разбить имя projlib(pfile1.o) на projlib и pfile1.o. Определить два макроса: $@(=projlib) и $*(=pfile1).


  • Попытаться найти правило .X.a и файл $*.X. Первый .X (в списке .SUFFIXES), который удовлетворяет этим условиям, это .c; поэтому выбирается правило .c.a и файл - pfile1.c. Установить $< равным pfile1.c и выполнить данное правило. В действительности make должен откомпилировать pfile1.c.


  • Обновить библиотеку. Выполнить команду, соответствующую projlib: зависимости, то есть

    @echo projlib up-to-date


  • Следует напомнить, что для того, чтобы pfile1.o зависел от каких-либо файлов, требуется поместить в файл описаний запись, подобную

    projlib(pfile1.o): $(INCDIR)/stdio.h pfile1.c

    На случай использования подобной конструкции предусмотрен макрос для ссылки на имя элемента архива. Всякий раз, когда вычисляется макрос $@, вычисляется и $%. Если текущего элемента архива нет, $% полагается равным пустой цепочке. Если элемент архива существует, то $% равно выражению в скобках.




    Содержание раздела