Рейтинговые книги
Читем онлайн Основы программирования в Linux - Нейл Мэтью

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 99 100 101 102 103 104 105 106 107 ... 200

myapp: main.о 2.o 3.o

 gcc -о myapp main.о 2.o 3.o

main.о: main.c a.h

 gcc -с main.c

2.о: 2.с a.h b.h

 gcc -с 2.с

3.o: 3.c b.h c.h

 gcc -с 3.c

Запустите команду make с опцией -f, потому что ваш make-файл не назван одним из стандартных имен makefile или Makefile. Если запустить приведенный код в каталоге, не содержащем исходных файлов, будет получено следующее сообщение:

$ make -f Makefile1

make: *** No rule to make target 'main.c', needed by 'main.o'. Stop.

$

Команда make предположила, что первое задание в make-файле, myapp, — это файл, который вы хотите создать. Затем она просмотрела остальные зависимости и прежде всего определила, что нужен файл, названный main.c. Поскольку вы все еще не создали этот файл и в make-файле не сказано, как он может быть создан, команда make вывела сообщение об ошибке. Итак, создайте исходные файлы и попробуйте снова. Поскольку результат нас не интересует, эти файлы могут быть очень простыми. Заголовочные файлы на самом деле пустые, поэтому вы можете создать их командой touch:

$ touch a.h

$ touch b.h

$ touch c.h

Файл main.c содержит функцию main, вызывающую функции function_two и function_three. В других двух файлах определены функции function_two и function_three. В исходных файлах есть строки #include для соответствующих заголовочных файлов, поэтому они оказываются зависимыми от содержимого включенных файлов заголовков. Это приложение не назовешь выдающимся, но, тем не менее, далее приведены листинги программ:

/* main.c */

#include <stdlib.h>

#include "a.h"

extern void function_two();

extern void function_three();

int main() {

 function_two();

 function_three();

 exit(EXIT_SUCCESS);

}

/* 2.c */

#include "a.h"

#include "b.h"

void function_two() { }

/* 3.с */

#include "b.h"

#include "c.h"

void function_three() { }

Теперь попробуйте выполнить команду make еще раз:

$ make -f Makefile1

gcc -с main.с gcc -с 2.с

gcc -с 3.с

gcc -о myapp main.о 2.о 3.о

$

На этот раз сборка прошла успешно.

Как это работает

Команда make обработала секцию зависимостей make-файла и определила файлы, которые нужно создать, и порядок их создания. Хотя вы сначала описали, как создать файл myapp, команда make определила правильный порядок создания файлов. Затем она запустила соответствующие команды для создания этих файлов, приведенные вами в секции правил. Команда make выводит на экран выполняемые ею команды. Теперь вы можете протестировать ваш make-файл, чтобы увидеть, корректно ли он обрабатывает изменения в файле b.h:

$ touch b.h

$ make -f Makefile1

gcc -c 2.с gcc -с 3.c

gcc -o myapp main.о 2.о 3.o

$

Команда make прочла ваш make-файл, определивший минимальное количество команд, требуемых для повторного построения myapp, и выполнила их в правильной последовательности. Теперь посмотрите, что произойдет, если вы удалите объектный файл:

$ rm 2.o

$ make -f Makefile1

gcc -с 2.c

gcc -о myapp main.о 2.о 3.о

$

И снова команда make правильно определяет нужные действия.

Комментарии в make-файле

Комментарий в make-файле начинается со знака # и продолжается до конца строки. Как и в исходных файлах на языке С, комментарии в make-файлах могут помочь как автору, так и другим пользователям понять, что имелось в виду во время написания данного файла.Sta

Макросы в make-файле

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

Макросы в make-файле записываются в виде конструкции MAСRONAME=значение, затем ссылаться на значение можно, указав $(MACRONAME) или ${MACRONAME}. Некоторые версии make могут также принимать $MACRONAME. Вы можете задать пустое значение макроса, оставив пустой часть строки после знака =.

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

Еще одна проблема в файле Makefile1 — жестко заданное имя компилятора gcc. В других UNIX-системах вы, возможно, будете использовать cc или c89. Если когда-нибудь вы захотите перенести ваш make-файл в другую версию UNIX или получите другой компилятор для имеющейся у вас системы, придется изменить несколько строк в вашем make-файле, чтобы заставить его работать. Макросы — хороший способ собрать все эти системнозависимые части и легко изменить их.

Обычно макросы определяются в самом make-файле, но их можно задать и при вызове команды make, если добавить определение макроса, например, make CC=c89. Определения, подобные данному, приведенные в командной строке, переопределяют заданные в make-файле определения. Заданные вне make-файла определения макросов должны передаваться как один аргумент, поэтому исключите пробелы или применяйте кавычки следующим образом: "CC = с89".

Выполните упражнение 9.2.

Упражнение 9.2. Make-файл с макросом

Далее приведена переработанная версия make-файла с именем Makefile2, в которой применяются макросы:

all: myapp

# Какой компилятор

СС = gcc

# Где хранятся файлы include

INCLUDE = .

# Опции для процесса разработки

СFLAGS = -g -Wall -ansi

# Опции для окончательной версии

# СFLAGS = -О -Wall -ansi

myapp: main.о 2.o 3.o

 $(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

Макрос Определение $? Список необходимых условий (файлов, от которых зависит выходной файл), измененных позже, чем текущий выходной файл [email protected] Имя текущего задания $< Имя текущего файла, от которого зависит выходной $* Имя без суффикса текущего файла, от которого зависит выходной

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

□ символ - заставляет команду make игнорировать любые ошибки. Например, если вы хотели бы создать каталог и при этом игнорировать любые ошибки, скажем, потому что такой каталог уже существует, вы просто ставите знак "минус" перед командой mkdir. Чуть позже в этой главе вы увидите применение символа -;

1 ... 99 100 101 102 103 104 105 106 107 ... 200
На этой странице вы можете бесплатно читать книгу Основы программирования в Linux - Нейл Мэтью бесплатно.
Похожие на Основы программирования в Linux - Нейл Мэтью книги

Оставить комментарий