$(CC) -о myapp main.о 2.o 3.o
main.о: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -с 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
Если удалить прошлую версию приложения и создать новую с помощью только что приведенного нового make-файла, вы получите следующее:
$ rm *.о myapp
$ make -f Makefile2
gcc -I. -g -Wall -ansi -c main.c
gcc -I. -g -Wall -ansi -c 2.c
gcc -I. -g -Wall -ansi -c 3.c
gcc -o myapp main.о 2.o 3.o
$
Как это работает
Программа 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.
Следующая важная особенность относится к двум дополнительным заданиям: cleanи install. В задании cleanдля удаления объектных файлов применяется команда rm. Команда начинается со знака -, тем самым сообщая команде makeо необходимости игнорировать результат команды, поэтому makeвыполнится успешно, даже если объектных файлов нет и команда rmвернет ошибку. Правила для задания cleanни от чего не зависят, остаток строки после clean:пуст. Таким образом, задание всегда считается измененным со времени последнего выполнения, и его правило всегда выполняется, если cleanуказывается в качестве задания.
Читать дальше