Шрифт:
Программа make заменяет ссылки на макросы
$(CC)
, $(CFLAGS)
и $(INCLUDE)
соответствующими определениями так же, как компилятор С поступает с директивами #define
. Теперь, если вы захотите изменить команду компиляции, вам придется изменить только одну строку make-файла. У команды
make
есть несколько специальных внутренних макросов, которые можно применять для того, чтобы еще более сократить make-файлы. В табл. 9.1 мы перечислили наиболее часто используемые из них; в последующих примерах вы увидите их в действии. Подстановка каждого из этих макросов выполняется только перед его использованием, поэтому значение макроса может меняться по мере обработки make-файла. На самом деле в этих макросах было бы очень мало пользы, если бы они действовали иначе. Таблица 9.1
Макрос | Определение |
---|---|
$? | Список необходимых условий (файлов, от которых зависит выходной файл), измененных позже, чем текущий выходной файл |
$@ | Имя текущего задания |
$< | Имя текущего файла, от которого зависит выходной |
$* | Имя без суффикса текущего файла, от которого зависит выходной |
Есть еще два полезных специальных символа, которые можно увидеть перед командами в make-файле:
символ
–
заставляет команду make
игнорировать любые ошибки. Например, если вы хотели бы создать каталог и при этом игнорировать любые ошибки, скажем, потому что такой каталог уже существует, вы просто ставите знак "минус" перед командой mkdir
. Чуть позже в этой главе вы увидите применение символа –
; символ
@
запрещает команде make
выводить команду в стандартный файл вывода перед ее выполнением. Этот символ очень удобен, если вы хотите использовать команду echo
для вывода некоторых инструкций. Множественные задания
Часто бывает полезно создать вместо одного выходного файла несколько или собрать несколько групп команд в одном файле. Вы можете сделать это, расширив свой make-файл. В упражнении 9.3 вы добавите задание
clean
на удаление ненужных объектных файлов, и задание install
, перемещающее окончательное приложение в другой каталог. Далее приведена следующая версия make-файла с именем Makefile3:
all: myapp
# Какой компилятор
CC = gcc
# Куда установить
# INSTDIR=/usr/local/bin
# Где хранятся файлы include
INCLUDE = .
# Опции для разработки
CFLAGS = -g -Wall -ansi
# Опции для рабочей версии
# CFLAGS = -О -Wall -ansi
myapp: main.o 2.o 3.o
$(CC) -о myapp main.о 2.о 3.o
main.о: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.о: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
clean:
-rm main.o 2.o 3.o
install: myapp
@if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else \
echo "Sorry, $(INSTDIR) does not exist";\
fi
В этом make-файле есть несколько вещей, на которые следует обратить внимание. Во-первых, специальная цель
all
, которая задает только один выходной файл myapp. Следовательно, если вы выполняете make
без указания задания, поведение по умолчанию — сборка файла myapp.