Утилита MAKE
Утилита MAKE фирмы Borland (MAKE - для защищенного режима и
MAKER для реального режима) - это утилита управления проектами,
работающая в режиме командной строки. Она помогает вам создавать
выполняемую версию программы на основе самых последних версий исходных файлов. Многие программы состоят из значительного числа
исходных файлов, каждый из которых, возможно, должен пропускаться
через препроцессоры, ассемблеры, компиляторы и другие утилиты перед тем, как он будет объединяться с остальной частью программы.
Если вы забудете перекомпилировать какой-либо модуль, который был
модифицирован, или модуль, который зависит от какого-либо другого
модифицированного исходного текста, то это может привести к разрушительным логическим ошибкам. С другой стороны, перекомпиляция
всех исходных файлов лишь для того, чтобы обезопасить себя, может
привести к слишком большим затратам времени.
Эта задача разрешается утилитой MAKE. Утилите MAKE задается
описание того, как должны обрабатываться исходные и объектные
файлы вашей программы для того, чтобы получить результирующий
продукт. Утилита MAKE анализирует эти описания и маркеры даты ваших файлов, а затем выполняет действия, необходимые для создания
самой последней версии продукта. Во время выполнения этого процесса утилита MAKE может вызывать множество различных компиляторов, ассемблеров, компоновщиков и утилит, однако, для обновления
результирующей программы она никогда не сделает ничего, что превышало бы необходимый минимум.
Полезность утилиты MAKE выходит далеко за рамки чисто программных приложений. Вы можете воспользоваться утилитой MAKE для
управления любым процессом, который связан с выбором файлов по
имени и их обработкой для создания результирующего продукта. К
числу некоторых широко распространенных приложений относится обработка текстов, автоматическое создание дубликатных копий, сортировка файлов по расширению имени с занесением их в другие каталоги, а также уничтожение временных файлов в ваших каталогах.
Как работает утилита MAKE
Утилита MAKE создает самую последнюю версию вашей программы,
выполняя при этом следующие задачи:
- Считывает специальный файл (называемый файлом описания,
формирующим файлом или файлом сборки), который был предварительно вами создан. Этот файл указывает утилите MAKE,
какие объектные файлы и библиотечные файлы должны быть
скомпонованы для того, чтобы создать выполняемый файл, а
также указывает, какие исходные файлы и файлы заголовков
должны компилироваться для создания каждого объектного
файла.
- Проверяет время и дату создания каждого объектного файла
по отношению к времени и дате создания исходного файла и
файлов заголовков, от которых он зависит. Если какой-либо
из этих файлов является более новым, чем объектный файл,
утилита MAKE считает, что он был модифицирован, и что необходимо произвести перекомпиляцию исходного файла.
- Вызывает компилятор для перекомпиляции исходного файла.
- После того, как были проверены все зависимости объектных
файлов, дата и время создания каждого объектного файла
проверяется по отношению к дате и времени создания выполняемого файла.
- Если какой-либо из объектных файлов оказывается более новым по сравнению с выполняемым файлом, утилита вызывает
компоновщик для его перекомпоновки.
Утилита MAKE полностью полагается на дату и время, которые
DOS присваивает каждому файлу. Это означает, что для нормальной
работы утилиты MAKE необходимо корректно устанавливать системные
дату и время.
Ниже приводится синтаксис вызова команды MAKE:
MAKE [параметр...][результат...]
Здесь "параметр" является параметром утилиты MAKE (они описываются далее), а "результат" представляет собой имя результирующего файла, который должен быть создан.
Ниже описываются синтаксические правила вызова утилиты MAKE:
- За словом make должен следовать пробел, а затем список параметров утилиты make.
- Каждый параметр утилиты MAKE должен отделяться от соседних
параметров пробелом. Параметры могут располагаться в любой
последовательности; может быть введено произвольное число
этих параметров (ограничением является длина командной
строки). Все параметры, которые не задают строку (например, -s или -a) могут завершаться необязательным символом - или +. При помощи этих символов указывается выключение
(-) или включение (+) данного параметра.
- За списком параметров утилиты MAKE следует пробел, а затем
необязательный список результирующих файлов.
- Каждый результирующий файл также должен отделяться от соседних результирующих файлов пробелом. Утилита MAKE анализирует результирующие файлы в порядке их расположения, перекомпилируя по мере необходимости их компоненты.
Если в командной строке не содержатся имена результирующих
файлов, то утилита MAKE использует в качестве явно заданного результирующего файла имя первого обнаруженного результирующего
файла. Если в командной строке указан один или несколько результирующих файлов, то они будут создаваться по мере необходимости.
Файл BUILTINS.MAK
Вы быстро обнаружите, что существуют макрокоманды и правила
утилиты MAKE, которые требуется использовать снова и снова. Существует три способа их обработки:
- Во-первых, вы можете заносить их в каждый создаваемый вами
формирующий файл для утилиты MAKE;
- Во-вторых, вы можете занести все эти элементы в один файл
и воспользоваться директивой !include в каждом создаваемом
вами формирующем файле утилиты MAKE. (Другие директивы
описываются далее в этой главе.);
- В-третьих, вы можете занести все эти элементы в файл
BUILTINS.MAK.
Каждый раз, когда вы запускаете утилиту MAKE, она ищет файл
с именем BUILTINS.MAK. Однако, наличие файла BUILTINS.MAK не является обязательным. Если MAKE обнаруживает файл BUILTINS.MAK, то
сначала она интерпретирует этот файл. Если утилита MAKE не может
обнаружить файл BUILTINS.MAK, то она переходит непосредственно к
интерпретации файла MAKEFILE (или того формирующего файла утилиты
MAKE, который был вами задан с помощью параметра -f).
Утилита MAKE сначала ищет файл BUILTINS.MAK в текущем каталоге. Если он отсутствует, и вы работаете под управлением DOS
версии 3.0 или старше, то MAKE осуществляет поиск в том каталоге,
откуда была вызвана сама утилита MAKE. Вам следует заносить файл
BUILTINS.MAK в тот же каталог, где находится файл MAKE.EXE.
Утилита MAKE всегда осуществляет поиск формирующего файла
только в текущем каталоге. Этот файл содержит правила для конкретной создаваемой выполняемой программы. Как файл BUILTINS.MAK,
так и формирующий файл подчиняются одинаковым синтаксическим правилам.
Поиск файлов, задаваемых с помощью директивы !include, также
осуществляется в текущем каталоге. Если вы используете параметр
-I (файлы включения), то она будет также выполнять поиск в каталоге, заданном с помощью параметра -I.
BUILTINS.MAK содержит стандартные правила и макрокоманды,
которые MAKE применяет перед тем, как MAKE использует формирующий
файл (параметр -r позволяет MAKE игнорировать BUILTINS.MAK).
Использование TOUCH.EXE
Иногда требуется вызвать принудительную перекомпиляцию или
построение целевого файла, даже если он еще не изменялся. Это
можно сделать с помощью утилиты TOUCH, которая изменяет дату и
время одного или более файлов на текущие дату и время, делая его
(их) более новым, чем файлы, от которых он зависит.
Вы можете также вынудить MAKE перестроить целевой файл, изменив один из файлов, от которых он зависит. Для этого наберите в
командной строке:
TOUCH имя_файла [имя_файла]
После этого TOUCH обновляет дату и время создания файла.
Параметры командной строки
Параметры командной строки управляют поведением утилиты MAKE. Заметьте, что имеет значение регистр букв (верхний или нижний); параметр -d не является допустимой заменой параметру -D.
Кроме того, для указания параметров можно задавать либо косую
черту (/), либо дефис (-).
Параметр | Действие
|
---|
-? или -h | Выводит информационное сообщение. Отображаются стандартные параметры, за которыми следует
знак плюс.
|
-B | Осуществляет полную перекомпиляцию всех результирующих файлов вне зависимости от дат создания файлов.
|
-Dмакро | Определяет "макро" как один символ - выражение !ifdef макро будет возвращать True.
|
[-D]ид=[стр] | Определяет названный идентификатор "ид" как строку "стр", стоящую после знака равенства. Эта строка не может содержать ни пробелов, ни знаков табуляции.
|
-fимя_файла | Использует "имя_файла" в качестве формирующего файла для утилиты MAKE. Если "имя_файла" не существует и не задано расширение имени файла, то утилита MAKE пытается найти файл FILENAME.MAK.
|
-Iкаталог | Осуществляет поиск файлов включения в указанном каталоге (а также в текущем каталоге).
|
-K | Сохраняет (не стирает) временные файлы, созданные утилитой MAKE. Все временные файлы имеют формат MAKEnnnn.$$$, где nnnn лежит в диапазоне от 0000 до 9999.
|
-N | Выполняет MAKE как Microsoft NMAKE.
|
-Uидентиф | Отменяет все заданные ранее описания названного идентификатора.
|
-W | Заносит в файл MAKE.EXE заданные в настоящий момент нестроковые параметры (типа -s или -a).
|
-a | Проверяет зависимости включаемых файлов и вложенных включаемых файлов, связанных с файлами .OBJ, и обновляет файл .OBJ, если файл .H изменен.
|
-c | Кэширует информацию о зависимостях, что улучшает
производительность MAKE. Не используйте его с -a а также если MAKE изменяет включаемые файлы.
|
-dкаталог | Используется с -S для задания диска и каталога, который MAKE использует для свопинга (для MAKER не действует).
|
-e | Игнорирует макрокоманду, если ее имя совпадает с
именем переменной операционной среды.
|
-i | Игнорирует состояние завершения всех запускаемых
из MAKE программ и продолжает процесс построения.
|
-m | Выводит дату и время каждого файла при обработке
его MAKE.
|
-n | Выводит команды, но не выполняет их (полезно использовать при отладке).
|
-p | Перед выполнением формирующего файла выводит все макроопределения и неявные правила.
|
-q | Возвращает 0, если цель имеет новую дату и время
и не 0 в противном случае (используется в командных файлах).
|
-r | Игнорирует все правила, определенные в BUIL-
TINS.MAK.
|
-s | Подавляет вывод команд на экран.
|
-S | Выгружает MAKE из памяти при выполнении команд,
что уменьшает использование памяти и позволяет компилировать большие модули. Для MAKER не действует.
|
Установка параметров по умолчанию
Параметр -W позволяет вам установить некоторые параметры MAKE, которые будут использоваться по умолчанию. Чтобы задать такие
параметры, наберите:
make -параметр[-] [-параметр][-] ... -W
Нужно учитывать, что -W не работает, когда загружена программа DOS SHARE, а таке со следующими параметрами MAKE:
-Dмакро -fимя_файла
[-D]ид=[стр] -? или -h
-dкаталог -lкаталог
-Uидентификатор
Параметр совместимости -N
Параметр командной строки -N увеличивает совместимость с
утилитой фирмы Microsoft NMAKE. Его следует использовать только в
том случае, если вам требуется построить проект с использованием
формирующих файлов, созданных для утилиты NMAKE. Предпочтительнее
запускать утилиту MAKE без параметра -N, так как данный параметр
вносит в утилиту MAKE некоторые трудноуловимые отличия:
- $$ расширяется в один символ $, а $ расширяется в "пусто".
- Символ каре (^) приводит к литеральной обработке последующего символа, если это специальный символ. Например, макрокоманда:
TEST = this is ^
a test
приведет к тому, что TEST будет расширяться в this is \na
test, где \n - это символ языка Си перевода на новую строку. Это особенно полезно, когда вам нужно закончить строку символом продолжения строки:
SOURCEDIR = C:\BOB\OBJ^\
- Если за символом каре следует обычный символ (не имеющий
специального значения), то символ каре игнорируется.
- Макрокоманда $d не будет специально определяемой текстовой
макрокомандой. Используйте вместо нее директивы !ifdef и
!ifndef.
- Предопределенные макрокоманды, которые возвращают маршрут,
не будут заканчиваться обратной косой чертой. Например,
без параметра -N переключатель $(<D) может возвращать
C:\OBJS\, а с параметром -N переключатель $(<D) возвратил
бы C:\OBJS.
- Без соответствующей директивы .suffixes утилита MAKE будет
искать неявные правила от конца формирующего файла к его
началу.
- Макрокоманда $* всегда расширяется в имя целевого файла.
(В обычном режиме $* расширяется в имя файлов зависимостей
в неявном правиле.)
Использование формирующих файлов
Формирующий файл содержит описания и отношения, необходимые
программе MAKE для поддержания самых последних версий ваших программ. Вы можете создавать столько формирующих файлов, сколько вам
требуется и присваивать им произвольные имена; MAKEFILE представляет собой лишь имя, используемое по умолчанию, на которое ориентируется утилита MAKE, если при ее запуске имя формирующего файла
не задано.
Формирующий файл можно создать с помощью любого текстового
редактора, который поддерживает формат ASCII, например, встроенного редактора интегрированной среды, редакторов Sрrint,
MicroStar или SideKick. Все правила, описания и директивы завершаются концом строки. Если строка является слишком длинной, то вы
можете продолжить ее на следующей строке, поместив на текущей
строке в качестве последнего символа обратную косую черту (\).
Для разделения соседних идентификаторов (например, при задании последовательностей) и для задания структурного отступа команд внутри правила следует пользоваться пробельными символами
(пробелами и знаками табуляции). Формирующий файл может содержать комментарии, явные и неявные правила, макрокоманды и директивы.
Символические цели
Символическая цель вынуждает MAKE строить в формирующем файле несколько целей (вам не нужно будет полагаться на сцепленные
зависимости). В строке зависимости перечисляются все цели, которые вы хотите построить. Никаких команд для символических целей
указывать не нужно.
Например, в следующем формирующем файле символические цели
Files строятся из FILE1.EXE и FILE2.EXE.
Files: file1.exe file2.exe #Эта цель не имеет команд
file1.exe: file1.obj
bcc file1.obj
file2.exe: file2.obj
bcc file2.obj
Для символических целей действуют следующие правила:
- Символические цели не требуют командной строки.
- Символической цели нужно давать уникальное имя (оно не может быть именем файла в текущем каталоге).
- Именует символические цели согласно с правилами операционной системы.
Явные и неявные правила
Явные и неявные правила, инструктирующие MAKE, в общем случае определяются следующим образом:
- Явные правила дают MAKE инструкции для конкретных файлов.
- Неявные правила дают MAKE инструкции, которым она следует,
когда не может найти явное правило.
Правило имеет следующий общий формат:
Строка зависимости
Команды
.
.
.
Строка зависимости для явных и неявных правил отличается, но
команды одни и те же. MAKE поддерживает несколько правил на одну
цель. После первого явного правила вы можете добавить файл, от
которого зависит цель, например:
Target1: dependent1 dep2 dep3 dep4 dep5
Target2: dep6 del7 del8
bcc -c $**
Синтаксис явных правил
Явное правило - это правило, которое явным образом задает
полные имена файлов. Явные правила имеют следующий вид:
целевой_файл[целевой_файл]...:[{маршрут}][исходный_файл...]
[команда]
.
.
.
Здесь "целевой_файл" представляет собой файл, который должен
быть обновлен, "исходный_файл" представляет собой файл, от которой зависит файл "целевой_файл", а "команда" представляет собой
любую команду, допустимую в DOS (включая вызовы .BAT файлов и выполнение .EXE и .COM файлов).
Явные правила определяют одно или несколько имен результирующих файлов, ноль или более исходных файлов, а также необязательный перечень команд, которые должны быть выполнены. Имена результирующего (целевого) и исходного файлов, указываемые в явных правилах, могут содержать обычные спецификации дисковода и каталога,
допустимые в DOS, а также содержать трафаретные символы.
Обязательны для соблюдения следующие указанные ниже синтаксические правила:
- "Целевой_файл" должен начинаться с самого начала строки (в
столбце 1);
- Исходному файлу (файлам) "исходный_файл" должны предшествовать по меньшей мере один символ пробела или табуляции,
расположенные после двоеточия;
- Каждая "команда" должна начинаться со структурного отступа
(ей должен предшествовать по меньшей мере один символ пробела или табуляции). Как было отмечено ранее, если список
исходных файлов или заданная команда не могут уместиться
на одной строке, то в качестве символа продолжения строки
может использоваться обратная косая черта.
Наличие как имен исходных файлов, так и команд является необязательным; возможно существование явных правил, которые состоят
только из строки целевой_файл[целевой_файл...], за которой следует символ двоеточия.
Идея использования явного правила заключается в том, что команда или перечень команд будут осуществлять создание или обновление результирующего файла целевой_файл как правило на основе
исходного файла "исходный_файл". Когда утилита MAKE обнаруживает
явное правило, она сначала проверяет, не являются ли сами исходные файлы "исходный_файл" результирующим файлом "целевой_файл" в
каком-либо другом правиле формирующего файла. Если это так, то
сначала утилита MAKE анализирует это второе правило.
После того, как на основе других правил были созданы или обновлены все исходные файлы "исходный_файл", утилита MAKE проверяет наличие результирующего файла "целевой_файл". Если "целевой_файл" не существует, то все команды выполняются в том порядке, в котором они заданы. Если "целевой_файл" существует, то дата
и время его последней модификации сравниваются с датой и временем
каждого исходного файла "исходный_файл". Если какой-либо исходный
файл был модифицирован после того, как был модифицирован файл
"целевой_файл", то выполняется заданный перечень команд.
Имя файла может указываться в левой части явного правила
файла описания утилиты MAKE лишь один раз.
Каждая командная строка в явном правиле начинается с символа
пробела. Утилита MAKE рассматривает все строки, которые следуют
за явным правилом и продолжаются до очередной строки, начинающейся со столбца 1 (которой не предшествуют символы пробела) или до
конца файла, как часть списка команд для этого правила. Пустые
строки игнорируются.
Явное правило, за которым не следуют командные строки, интерпретируется несколько иначе, чем явное правило с командными
строками.
- Если в состав явного правила входят команды, то результирующий файл зависит только от тех файлов, которые перечислены в явном правиле.
- Если в явном правиле не заданы никакие команды, результирующий файл зависит от двух наборов файлов: тех файлов,
которые заданы в явном правиле, и от всех файлов, которые
подходят под определение неявного правила для результирующего файла (файлов). Это позволяет задавать зависимости,
которые будут обрабатываться неявным правилом. Например:
.c.obj
BCC -c $<
рrog.obj:
Файл рrog.obj зависит от файла рrog.c; если не совпадают даты этих файлов, то будет выполняться командная строка:
BCC -c рrog.c
Несколько явных правил для одного целевого файла
Для одного целевого файла можно задать несколько явных правил. Множественные явные правила вы можете использовать для создания с помощью TLIB библиотечного модуля. Например, поскольку
файлы объектных модулей .OBJ могут строиться по-разному (некоторые с помощью компилятора BCC, а другие, например, с помощью
TASM).
Здесь используется тот же формат, что и для обычных явных
правил, но за целевым файлом указывается два двоеточия. Второе
двоеточие сообщает утилите MAKE, что для данного целевого файла
ожидаются дополнительные явные правила.
В следующем примере MYLIB.LIB состоит из четырех объектных
модулей, два из которых являются модулями С++. Первое явное правило компилирует модули С++ и обновляет библиотеку. Второе явное
правило ассемблирует файлы ASM и также обновляет библиотеку.
mylib.lib:: f1.cpp f2.cpp
bcc -c f1.cpp f2.cpp
tlib mylib -+f1.obj -+f2.obj
mylib.lib:: f3.asm f4.asm
tasm /mx f3.asm f4.asm
tlib mylib -+f3.obj -+f4.obj
Примеры
Ниже приведены некоторые примеры явных правил:
1. рrog.exe: myрrog.obj рrog2.obj
BCC myрrog.obj рrog2.obj
2. myрrog.obj: myрrog.c include\stdio.h
BCC -c myрrog.c
3. рrog2.obj: рrog2.c include\stdio.h
BCC -c -K рrog2.c
Эти три примера взяты из одного и того же формирующего файла. Повторно будут обрабатываться только те модули, которые подвергались модификациям. Если был модифицирован файл PROG2.C, то будет перекомпилироваться только этот файл. То же самое справедливо для файла MYPROG.C. Но если был изменен файл включения stdio.h, то будут перекомпилированы оба файла. Перекомпоновка будет осуществляться в том случае, если был модифицирован хотя бы один из объектных файлов, указанных в списке зависимости. Это имеет место в том случае, если в результате изменения исходного файла была произведена перекомпиляция.
Автоматическая проверка зависимостей
Система Borland C++ ориентирована также на использование
утилиты MAKE в целях автоматической проверки зависимостей для
включаемых файлов. Компиляторы BCC и BCC32 создают объектные файлы, которые содержат используемую утилитой MAKE информацию о всех
файлах включения, необходимых для создания объектного файла. Параметр командной строки -a утилиты MAKE проверяет эту информацию,
чтобы удостовериться в "современности" всех используемых файлов.
Когда утилита MAKE осуществляет автоматическую проверку зависимостей, она считывает имена файлов включения, а также время и
дату создания объектных файлов. Если какой-либо включаемый файл
был модифицирован, утилита MAKE осуществляет перекомпиляцию для
обновления объектного файла.
Синтаксис неявных правил
Утилита MAKE позволяет на ряду с явными правилами задавать
неявные правила. Неявные правила представляют собой обобщение явных правил; они применяются ко всем файлам, которые имеют соответствующие расширения имен файлов.
Ниже приводится пример, который иллюстрирует отношение между
двумя правилами. Рассмотрим явное правило из предыдущего примера.
Данное правило является типичным, поскольку оно следует общему
принципу: объектный файл(с расширением имени .OBJ) зависит от
файла с тем же основным именем и расширением .C и создается путем
выполнения программы BCC. Фактически, можно создать формирующий
файл для утилиты MAKE, который будет содержать несколько(или
несколько десятков) явных правил, соответствующих одному и тому
же формату.
Переписывая явное правило в виде неявного правила, вы можете
убрать все явные правила, которые подчиняются одинаковому форма ту. Неявное правило будет иметь следующий вид:
.c.obj:
BCC -c $<
Это правило означает следующее: "Любой файл с расширением .C
может быть оттранслирован в файл с тем же основным именем и расширением .OBJ с помощью следующей последовательности команд".
Создание файла .OBJ происходит с помощью второй строки этого правила, где $< означает имя файла с расширением, присущим исходному
файлу (.C). (Символ $< представляет макрокоманду особого вида.
Объяснение макрокоманд приводится далее. Макрокоманда $< при каждом выполнении команды будет заменена полным именем соответствующего исходного файла .C).
Идентификатор $< представляет собой специальную макрокоманду. Макрокоманды обсуждаются ниже. Макрокоманда $< при каждом выполнении команды будет заменяться полными именем соответствующего
исходного файла .С.
Ниже приводится синтаксис неявного правила:
[{исходный_каталог}].исх_расшир.[{целевой_каталог}]цел_расшир:
[команда]
...
Как и ранее, использование команды является необязательным.
Если команда используется, то перед ней должны стоять один или
несколько символов пробелов.
"Исх_расшир" (расширение имени файла, которое должно начинаться точкой в столбце 1) представляет собой расширение имени
исходного файла; то есть, оно относится к любому файлу, который
имеет следующий формат:
имя_файла.исх_расшир
Аналогично, "цел_расшир" относится к файлу, который удовлетворяет спецификации:
имя_файла.цел_расшир
Здесь "имя_файла" является одинаковым для обоих файлов. Другими словами, данное неявное правило заменяет все явные правила,
которые соответствуют следующему формату:
имя_файла.исх_расшир:имя_файла.цел_расшир
[команда]
...
для любого имени файла.
Если утилита MAKE не может обнаружить явное правило для заданного результирующего файла, или если имя результирующего файла
появляется в явном правиле, у которого отсутствуют команды, то
она использует неявные правила.
Расширение имени интересующего утилиту MAKE файла используется для определения того неявного правила, которое должно использоваться. Это неявное правило применяется в том случае, если
обнаружен файл с тем же самым основным именем, что и у результирующего файла, но с заданным расширением исходного файла.
Предположим, например, что у вас имеется формирующий файл
утилиты MAKE (с именем MAKEFILE), который имеет следующее содержимое:
c.obj:
BCC -c $<
Если у вас имеется написанная на Си программа с именем
RATIO.C, которую вы хотите скомпилировать в файл RATIO.OBJ, то вы
можете воспользоваться командой:
make ratio.obj
Утилита MAKE будет рассматривать файл RATIO.OBJ в качестве
результирующего файла. Поскольку явное правило для создания файла
RATIO.OBJ не существует, утилита MAKE применяет неявное правило и
генерирует следующую команду:
BCC -c ratio.c
которая, естественно, выполняет компиляцию для создания файла
RATIO.OBJ.
Утилита MAKE использует неявные правила и в том случае, когда ей задаются явные правила, не сопровождающиеся никакими командами. Предположим, что в начале файла описания вы задали следующее неявное правило:
.c.obj:
BCC -c $<
Если это правило задано, вы можете удалить команду из приведенного ниже явного правила:
myрrog.obj: myрrog.c include\stdio.h
BCC -c myрrog.c
Процесс обработки будет прежним.
Если вы используете систему Borland C++ и разрешаете утилите
MAKE выполнять автоматическую проверку зависимостей, вы можете
удалить все явно заданные зависимости, в которых объектные файлы
указываются в качестве результирующих. Если задана автоматическая
проверка зависимостей, и используются неявные правила, то представленный в начале раздела по явным правилам пример с тремя правилами превращается в следующий:
c.obj:
BCC -c $<
рrog.exe: myрrog.obj рrog2.obj
tlink lib\c0s myрrog рrog2, рrog, ,lib\cs
Вы можете создать несколько неявных правил с одним и тем же
расширением имени результирующего файла. Если для заданного расширения имени результирующего файла имеется более одного неявного
правила, то правила проверяются в том порядке, в котором они появляются в файле описания, до тех пор, пока не найдется правило,
подходящее для расширения имени исходного файла, или до тех пор,
пока утилита MAKE не осуществит проверку всех применимых правил.
Утилита MAKE использует первое неявное правило, в котором
указан файл с расширением имени исходного файла. Даже если выполнение команды, заданной в этом правиле, заканчивается безуспешно,
никакие неявные правила больше не проверяются.
Все строки, следующие за неявным правилом вплоть до очередной строки, которая не начинается с символа пробела, или до конца
файла, считаются частью списка команд для этого правила.
Цель в явном правиле получает свою командную строку из явного правила. Следующий пример показывает неявное правили и явное
правило без командной строки:
.c.obj
bcc -c $< #использует макрокоманду $<
myprog.obj: #явное правило, использующее команду
# bcc -c myprog.c
Синтаксис команд
Как явные, так и неявные правила (описываемые ниже) могут
содержать списки команд. Команды в списке команд подчиняются следующим синтаксическим правилам:
[префикс...]тело_команды
Каждая команда в списке команд состоит из (необязательного)
списка префиксов, за которым следует тело единственной команды.
Префиксы команд
Префиксы, допустимые в команде, модифицирует интерпретацию
этих команд утилитой MAKE. Префиксом является либо символ @, либо
дефис (-), за которым непосредственно следует какое-либо число.
Префикс | Действие
|
---|
@ | Указывает утилите MAKE, что не нужно отображать
команды перед их выполнением. Отображение не осуществляется даже в том случае, если в командной строке утилиты MAKE не задается параметр -s. Этот
префикс применяется только к тем командам, перед
которыми он указывается.
|
-num | Оказывает влияние на то, как утилита MAKE интерпретирует коды выхода. Если задается какое-либо число num, то утилита MAKE прекращает обработку
только в том случае, если полученный код выхода превышает заданное число. В приведенном ниже примере утилита MAKE прекращает работу только в том случае, если код выхода превышает 4:
-4myрrog samрle.x
Если префикс -num не задается, а код выхода является ненулевым, то утилита MAKE прекращает работу и удаляет текущий результирующий файл.
Примечание: Коды выхода являются значениями, которые возвращаются выполняемыми командами (внутри программы).
|
- | Если задается дефис, но не задается никакого числа, то утилита MAKE совсем не будет проверять код выхода. Независимо от кода выхода выполнение утилиты MAKE будет продолжено.
|
Операции в команде
В дополнение к операциям переназначения <, > и >>, утилита
MAKE добавляет операции << и &&. Эти операции для создания подаваемых на вход команды данных создают в оперативном порядке файл.
Операция << создает временный файл и переназначает поток стандартного ввода команды таким образом, что он поступает из созданного файла. Если у вас имеется программа, которая допускает ввод
данных из потока stdin, то команда:
MYPROG <<!
Это лишь тест
!
будет создавать временный файл, содержащий строку "Это лишь тест
\n", переопределяя ее как единственный поток входной информации
для программы myрrog. Восклицательный знак (!) представляет собой
в данном примере разделитель; в качестве разделителя для этого
файла можно использовать любой символ за исключением символов #
или \. Первая строка, начальным символом которой является символ
разделителя, завершает файл. Остальная часть строки, следующая за
символом разделителя (в данном примере, восклицательным знаком)
считается часть предшествующей команды.
Операция && аналогична операции <<. Он создает временный
файл, но вместо того, чтобы сделать этот файл стандартным потоком
ввода для указанной команды, операция && заменяется именем временного файла. Это оказывается полезным в том случае, если вы хотите, чтобы утилита MAKE создала файл, который должен быть использован в качестве источника входных данных команды. В
приведенном ниже примере показывается, как создать "файл подсказки" для утилиты TLINK.
MYPROG.EXE: $(MYOBJS)
tlink /c @&&!
COS $(MYOBJS)
$*
$*
$(MYLIBS) EMU.LIB MATHS.LIB CS.LIB
Заметьте, что макрокоманда (которая обозначается с помощью
знака $) расширяется при создании файла. $* заменяется именем
создаваемого файла без расширения, а $(MYOBJS) и $(MYLIBS) заме-
няются значениями макрокоманд MYOBJS и MYLIBS. Таким образом, для
TLINK файл будет выглядеть следующим образом:
COS a.obj b.obj c.obj d.obj
MYPROG
MYPROG
w.lib x.lib y.lib z.lib EMU.LIB MATHS.LIB CS.LIB
Если не используется параметр командной строки -K, то все
временные файлы удаляются. Параметром -K следует пользоваться для
"отладки" временных файлов, если возникает впечатление, что эти
файлы работают неверно.
Макрокоманды MAKE
Макрокоманда MAKE - это строка, которая расширяется при вызове макрокоманды в формирующем файле. Макрокоманды позволяют
создавать шаблоны формирующих файлов и изменять их для конкретных
проектов.
Определение макрокоманд
Макроопределение имеет следующую форму:
имя_макрокоманды = текст_макрорасширения
Здесь "имя_макрокоманды" представляет имя данной макрокоманды. "Имя_макрокоманды" должно являться строкой из букв и цифр, не
содержащей символов пробела, хотя пробелы между "именем_макрокомандЫ" и знаком равенства (=) допустимы. "Текст_макрорасширения"
представляет собой произвольную строку, содержащую буквы, цифры,
символы пробела и знаки пунктуации. Эта строка завершается символом перехода на новую строку.
Если "имя_макрокоманды" уже было определено ранее (либо с
помощью макроопределения в формирующем файле, либо с помощью параметра -D командной строки утилиты MAKE), то новое описание макрокоманды заменяет старое.
При задании макрокоманд регистр букв учитывается; то есть,
model, Model и MODEL определяют разные макрокоманды.
Использование макрокоманд
При вызове макрокоманды в формирующем файле должен соблюдаться следующий формат:
$(имя_макрокоманды)
Круглые скобки должны использоваться во всех случаях вызова
макрокоманд, даже в том случае, если имя макрокоманда состоит из
единственной буквы (за исключением предопределенных макрокоманд).
Данная конструкция - $(имя_макрокоманды) - называется вызовом
макрокоманда.
Когда утилита MAKE обнаруживает вызов макрокоманды, она заменяет ее на текст, раскрывающий макрокоманду (текст макрорасширения). Если текст макрорасширения не определен, то MAKE заменяет
ее пустой (нулевой) строкой.
Использование в качестве макрокоманд переменных среды
Если вы вызываете макрокоманду, для которой "имя_макрокоманды" еще не определено в формирующем файле или в командной строке,
утилита MAKE будет пытаться найти "имя_макрокоманды", как переменную операционной среды DOS. Если MAKE находит ее в операционной среде, то текстом макрорасширения будет значение этой переменной операционной среды.
Если не был задан параметр -e, то макрокоманды, определенные
в формирующем файле или в командной строке, переопределяют переменные операционной среды с тем же именем.
Подстановки с помощью макрокоманд
Используя специальный формат вызова макрокоманды, вы можете
вызвать макрокоманду, изменив ее текст. Вместо стандартной формы
вызова используйте следующую:
$(имя_макрокоманды:текст_1=текст_2)
При использовании такой формы вызова каждое вхождение в макрокоманду "текста_1" будет заменяться "текстом_2". "Имя_макрокоманды'" может быть одной из предопределенных макрокоманд. Это полезно использовать, если вы предпочитаете использовать в
макрокоманде один список файлов.В приведенном ниже примере макрокоманда SOURCE содержит список файлов C++, от которых зависит целевой файл. Командная строка TLINK изменяет все расширения .CPP
на соответствующие расширения .OBJ объектных файлов и компонует
их.
SOURCE = f1.cpp f2.cpp f3.cpp
myapp.exe: $(SOURCE)
bcc -c $(SOURCE)
tlink c0s $(SOURCE:.cpp=.obj),myapp,,cs
Между : и = не нужно включать лишних пробелов. Если после
двоеточия указывается пробел, MAKE будет пытаться найти строку,
включающую предшествующий пробел.
Особые ситуации
Макрокоманда в макрокоманде
Макрокоманда не может вызываться в левой части ("имя_макрокоманды") макроопределения. Макрокоманды могут использоваться в
правой части ("текст_макрорасширения"), но их раскрытие не будет
осуществляться до тех пор, пока описанный макрокоманд не будет
вызван. Другими словами, когда осуществляется раскрытие макроопределения, будет также осуществляться расширение всех макрокоманд, вложенных в раскрывающий текст.
Макрокоманда в правилах
Вызов макрокоманд в строках правил раскрывается немедленно.
Макрокоманды в директивах
Вызовы макрокоманд в директивах !if и !elif раскрываются немедленно. Если вызываемая в директивах !if или !elif макрокоманда
в данный момент не определена, то она расширяется в значение 0
(ложно).
Макрокоманды в командах
Вызовы макрокоманд в командах раскрываются при выполнении
команд.
Предопределенные макрокоманды
Утилита MAKE содержит в себе несколько специальных встроенных макрокоманд: $d, $*, $<, $:, $. и $&. Первая из них осуществляет проверку на существование макрокоманды с заданным именем.
Он используется в директивах !if и !elif. Остальные представляют
собой макрокоманды имен файлов, используемые в явных и неявных
правилах. В дополнение к этому, в качестве макрокоманд автоматически загружаются строки установленной к настоящему моменту среды
DOS (строки, которые можно просматривать и задавать в DOS с помощью команды SET). Наконец, в MAKE определяются несколько предопределенных макрокоманд, показанных ниже:
Предопределенные макрокоманды утилиты MAKE
Макрокоманда | Описание
|
---|
__MSDOS__ | Имеет значение 1, если MAKE выполняется в DOS.
|
__MAKE__ | Номер версии MAKE в шестнадцатиричном виде (для
данной версии "Ox0370").
|
MAKE | Имя выполняемого файла MAKE (обычно MAKE или MAKER.
|
MAKEFLAG | Все параметры, используемые в командной строке
утилиты MAKE.
|
MAKEDIR | Каталог, из которого запущена утилита MAKE.
|
Макрокоманды утилиты MAKE, используемые по умолчанию
Макро- команда | Расширение в неявных файлах | Расширение в явных файлах
|
---|
$* | маршрут\исходный_файл | маршрут\целевой_файл
|
$< | маршрут\исходный_файл+расш | маршрут\целевой_файл+расш
|
$: | маршрут исходных файлов | маршрут целевых файлов
|
$. | исходный файл+расширение | целевой файл+расширение
|
$& | исходный файл | целевой файл
|
$@ | маршрут\целевой_файл+расш | маршрут\целевой_файл+расш
|
$** | маршрут\исходный_файл+расш | все исходные файлы+расш
|
$? | маршрут\исходный_файл+расш | старые исходные файлы
|
Модификаторы макрокоманд
Если нет предопределенной макрокоманды имени файла, которая
позволяет вам задавать части нужного имени файла, для выделения
частей имени файла вы можете использовать модификаторы макрокоманд. Они имеют следующий формат:
$(макрокоманда[D F B R])
где "макрокоманда" - одна из предопределенных макрокоманд имени
файла (показанных выше), а R, B, D и F - модификаторы. Заметим,
что поскольку макрокоманда теперь имеет длину более одного символа, необходимы круглые скобки. Каждый из модификаторов описывается в следующей таблице. В примерах предполагается, что $< возвращает C:\OBJS\BOB.OBJ.
Модификаторы макрокоманд утилиты MAKE
Модификатор | Какую часть имени файла он определяет | Пример
|
---|
D | Диск и каталог. | $(<D)=C:\OBJS\
|
F | Базовое имя файла и расширение. | $(<F)=BOB.OBJ
|
B | Только базовое имя файла. | $(<B)=BOB
|
R | Диск, каталог и расширение. | $(<R)=C:\OBJS\BOB
|
Директивы MAKE
Утилита MAKE фирмы Borland позволяет выполнять операции, которые не допускаются в других версиях MAKE: задавать директивы,
подобные тем, которые имеются в языках Си, ассемблере и Паскале.
Эти директивы могут использоваться для реализации значительного
числа полезных и мощных операций. Некоторые директивы начинаются
в файле описания с восклицательного знака (!), который должен являться первым символом строки. Другие начинаются с точки. Ниже
приводится полный перечень директив утилиты MAKE:
Директивы утилиты MAKE
Директива | Описание
|
---|
.autodeрend | Включает проверку автоматических зависимостей.
|
!elif | Условное выполнение.
|
!else | Условное выполнение.
|
!endif | Условное выполнение.
|
!error | Указывает, что утилита MAKE должна остановиться и
выдать сообщение об ошибке.
|
!if | Условное выполнение
|
.ignore | Указывает, что утилита MAKE должна игнорировать
возвращаемое командой значение
|
!include | Задает файл, который должен быть включен в формирующий файл.
|
.noautodepend | Выключает автоматическую проверку зависимостей.
|
.noignore | Выключает действие директивы .ignore.
|
.nosilent | Указывает утилите MAKE, что нужно отображать команды перед их выполнением.
|
.noswaр | Указывает утилите MAKE, что не нужно осуществлять
выгрузку самой себя из памяти и подкачку в память.
|
.рath.ext | Задает утилите MAKE маршрут для поиска файлов
с расширением ."EXT".
|
.precious | Указывает утилите MAKE, что целевой файл удалять
не нужно, даже при неудачном выполнении команд
построения целевого файла.
|
.silent | Указывает утилите MAKE, что не нужно отображать
команды перед их выполнением.
|
.swaр | Указывает утилите MAKE, что нужно осуществлять
выгрузку самой себя из памяти и подкачку в память.
|
.suffixes | Указывает MAKE, что при неоднозначности целевого
файла нужно использовать неявное правило.
|
!undef | Задает отмену описания заданной макрокоманды.
|
Директивы с точкой
Каждая из представленных ниже директив имеет соответствующий
ей параметр командной строки, но при этом обладает приоритетом по
сравнению с этим параметром. Например, если утилита MAKE вызывается следующей командной строкой:
make -a
но в формирующем файле содержится директива .noautodeрend, то автоматическая проверка зависимостей будет отменена.
Директива | Параметр
|
---|
.autodepend | -a
|
.ignore | -i
|
.noautodepend | -a-
|
.noignore | -i-
|
.nosilent | -s-
|
.noswap | -S-
|
.silent | -s
|
.swap | -S
|
Директивы .AUTODEPEND и .NOAUTODEPEND включают (задают) и
выключают (отменяют) автоматическую проверку зависимостей. Они
соответствуют параметру -a командной строки.
Директивы .IGNORE и .NOIGNORE указывают утилите MAKE, что
нужно игнорировать возвращаемое программой значение, примерно так
же, как это делает префикс - перед командой вызова программы (он
описан ранее). Эти директивы соответствуют параметру -l командной
строки.
Директивы .SILENT и .NOSILENT указывают утилите MAKE, следует ли отображать команды перед их выполнением. Они соответствуют
параметру -s командной строки.
Директивы .SWAP и .NOSWAP указывают утилите MAKE, нужно выгружать себя из памяти или нет. Они соответствуют параметру -S командной строки.
Директива .precious