The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

Каталог документации / Раздел "Документация для Linux" / Оглавление документа
next up previous contents index
Next: Шаблонные правила Up: Средство управления проектом make Previous: Алгоритм работы make   Contents   Index

Переменные в make-файлах

GNU Make поддерживает два способа задания переменных, которые несколько различаются по смыслу. Первый способ - традиционный, с помощью оператора '=':

compile_flags = -O3 -funroll-loops -fomit-frame-pointer

Такой способ поддерживают все варианты утилиты make. Его можно сравнить, например, с заданием макроса в языке Си.

#define compile_flags "-O3 -funroll-loops -fomit-frame-pointer"

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

var1 = one
var2 = $(var1) two
var1 = three

all:
    @echo $(var2)

на экран будет выдана строка ``three two''. Значение переменной var2 будет вычислено непосредственно в момент выполнения команды echo, и будет представлять собой текущее значение переменной var1, к которому добавлена строка ``two''. Как следствие - одна и та же переменная не может одновременно фигурировать в левой и правой части выражения, так как это может привести к бесконечной рекурсии. GNU Make распознает подобные ситуации и прерывает обработку make-файла. Следующий пример вызовет ошибку:

compile_flags = -pipe $(compile_flags)

GNU Make поддерживает также и второй, новый способ задания переменной - с помощью оператора ':=':

compile_flags := -O3 -funroll-loops -fomit-frame-pointer

В этом случае переменная работает подобно ``обычным'' текстовым переменным в каком-нибудь из языков программирования. Вот приблизительный аналог этого выражения на языке C++:

string compile_flags = "-O3 -funroll-loops -fomit-frame-pointer";

Значение переменной вычисляется в момент обработки оператора присваивания. Если, например, записать

var1 := one
var2 := $(var1) two
var1 := three

all:
     @echo $(var2)

то при обработке такого make-файла на экран будет выдана строка ``one two''.

Переменная может ``менять'' свое поведение в зависимости от того, какой из операторов присваивания был к ней применен последним. Одна и та же переменная на протяжении своей жизни вполне может вести себя и как ``макрос'' и как ``текстовая переменная''.

Зависимости цели edit в примерах выше являлись аргументами для команд компоновки. Можно избежать их повторения, определив переменную, которая будет содержать имена всех объектных файлов.


# Makefile for simple editor

OBJS = edit.o kbd.o commands.o display.o $ \backslash$
insert.o search.o files.o utils.o
edit : $(OBJS)
gcc -g -o edit $(OBJS)

Строка, начинающаяся с ``OBJS ='' определяет переменную OBJS, на которую можно в дальнейшем сослаться через ``$(OBJS)'' или ``$OBJS''. Эти более поздние ссылки приводят к тому, что обозначение OBJ будет дословно заменяться, прежде чем правило будет обработано. Иногда неудобно, что и gmake и shell используют `$' как префикс для ссылок на переменные; gmake определяет `$$', такое же, как `$', позволяя Вам передавать `$' в shell, если это необходимо.

Иногда Вам может понадобиться величина, выглядящая как обычная переменная, но с некоторыми уточнениями. Например, задавая переменную со списком имен всех исходных файлов, Вы можете захотеть задать имена всех получающихся объектных файлов. Можно переопределить OBJS следующим образом.


SRCS = edit.cc kbd.cc commands.cc display.cc 
$ \backslash$

insert.cc search.cc files.cc utils.cc
OBJS = $(SRCS:.cc=.o)
Суффикс уточнения `:.cc=.o' определяет необходимые уточнения. Теперь у нас есть переменные для имен всех исходных и объектных файлов, при этом не пришлось повторять в определениях множество имен.

Переменные могут быть упомянуты и в командной строке при вызове gmake. Например, если make-файл содержит


edit.o: edit.cc

gcc $(DEBUG) -c -Wall edit.cc
то команда типа gmake DEBUG=-g ... приведет к использованию ключа -g (добавить символическую информацию отладчика) при компиляции, а отсутствие DEBUG=-g исключит использование этого ключа. Определения переменных в командной строке имеют преимущество перед определениями внутри make-файла, что позволяет задать в make-файле значения по умолчанию.

Переменные, не установленные любым из перечисленных методов, могут быть установлены как переменные среды. Поэтому, последовательность команд

setenv DEBUG -g gmake ...

для последнего примера также приведет к использованию ключа -g во время компиляции.



Alex Otwagin 2002-12-16


  Закладки на сайте
  Проследить за страницей
Created 1996-2017 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
Hosting by Ihor