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

Шрифт:

-
+

Интервал:

-
+

Закладка:

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

□ символ @ запрещает команде 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 указывается в качестве задания.

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

Задание install выполняет несколько команд одну за другой для установки приложения в указанное расположение. Оно не проверяет успешность выполнения предыдущей команды перед выполнением следующей. Если очень важно, чтобы последующие команды выполнялись только в случае успешного завершения предыдущей, можно написать команды, объединенные с помощью операции &&, как показано далее:

@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"; false ;

fi

Как вы, вероятно, помните из главы 2, у командной оболочки есть команда and, благодаря которой выполнение последующей команды возможно лишь при успешном завершении предыдущей. В данном примере вас не слишком заботит успешное завершение предыдущих команд, поэтому можно придерживаться более простой формы.

Если вы — обычный пользователь, то у вас может не быть прав на установку новых команд в каталог /usr/local/bin. Можно изменить в make-файле каталог установки, изменить права доступа к этому каталогу или заменить пользователя (с помощью команды su) на root перед запуском make install.

$ rm *.о myapp

$ make -f Makefile3

gcc -I. -g -Wall -ansi -c main.c

gcc -I. -g -Wall -ansi -c 2.c

gcc -I. -g -Wall -ansi -с 3.c

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

$ make -f Makefile3

make: Nothing to be done for 'all'.

$ rm myapp

$ make -f Makefile3 install

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

Installed in /usr/local/bin

make -f Makefile3 clean

rm main.о 2.о 3.о

$

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

Сначала вы удаляете файл myapp и все объектные файлы. Команда make самостоятельно выбирает задание all, которое приводит к сборке myapp. Затем вы снова запускаете команду make, но т.к. у файла myapp свежая версия, make не делает ничего. Далее вы удаляете файл myapp и выполняете make install. Эта команда создает заново двоичный файл и копирует его в каталог установки. В заключение выполняется команда make clean, удаляющая объектные файлы.

Встроенные правила

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

#include <stdlib.h>

#include <stdio.h>

int main() {

 printf("Hello Worldn");

 exit(EXIT_SUCCESS);

}

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

$ make foo

сс foo.с -о foo

$

Как видите, make знает, как запустить компилятор, хотя в данном случае она выбирает сс вместо gcc (в ОС Linux это нормально, потому что cc — обычно ссылка на gcc). Иногда эти встроенные правила называют подразумеваемыми правилами. Стандартные правила используют макросы, поэтому задавая некоторые новые значения для макросов, вы можете изменить стандартное поведение.

$ rm foo

$ make CC=gcc CFLAGS="-Wall -g" foo

gcc -Wall -g foo.с -o foo

$

С помощью опции -p можно попросить команду make вывести на экран встроенные правила. Их так много, что мы не можем привести в книге все встроенные правила, ограничимся коротким фрагментом вывода команды make -p версии GNU, демонстрирующим часть этих правил:

OUTPUT_OPTION = -o [email protected]

COMPILE.с = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -с

%.о: %.с

# commands to execute (built-in) :

 $(COMPILE.с) $(OUTPUT_OPTION) $<

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

main.о: main.c a.h

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

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

Эту версию можно найти в загружаемом из Интернета программном коде, в файле Makefile4.

Суффиксы и шаблоны правил

Встроенные правила, которые вы видели, действуют, используя суффиксы (подобные расширениям файлов в системах Windows и MS-DOS), поэтому команда make, получая файл с одним окончанием, знает, какое правило применять для создания файла с другим окончанием. Чаще всего используется правило для создания файла, заканчивающегося .о, из файла с окончанием .c. Это правило для применения компилятора, компилирующего исходный файл, но не компонующего.

Порой возникает потребность в создании новых правил. Авторы приучили себя работать с исходными файлами, которые необходимо компилировать несколькими разными компиляторами: двумя в среде MS-DOS и gcc в ОС Linux. Для того чтобы осчастливить один из компиляторов MS-DOS, исходные файлы на языке С++, а не С должны иметь расширение cpp. К сожалению, у версии команды make, применяемой в Linux, в то время не было встроенного правила для компиляции файлов с окончанием .cpp. (Существовало правило для суффикса .cc, более распространенного расширения файла на C++ в среде UNIX.)

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

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