А.В. Столяров, И.Г. Головин, И.А. Волкова - Операционная система Unix (1115132), страница 11
Текст из файла (страница 11)
Так, строка параметров54компилятора “-g -Wall” встречается во всех трех целях. Помимо необходимости повторения одного и того же текста, мы можем столкнутьсяс проблемами при модификации. Предположим, нам понадобится задать компилятору режим оптимизации кода (флаг -O2). Для этого нампришлось бы внести совершенно одинаковые изменения в три разныйстроки файла. В более сложном случае таких строк может понадобиться несколько десятков и даже сотен.Аналогичная проблема встанет, например, если мы захотим произвести сборку другим компилятором.Решить проблему позволяет введение make-переменных. Обозначимимя компилятора C переменной CC, а общие параметры компиляции –переменной CFLAGS18 .Тогда наш Makefile можно переписать следующим образом:CC = gccCFLAGS = -g -Wall -ansi -pedanticmod1.o: mod1.c mod1.h$(CC) $(CFLAGS) -c mod1.c -o mod1.omod2.o: mod2.c mod2.h$(CC) $(CFLAGS) -c mod2.c -o mod2.oprog: main.c mod1.o mod2.o$(CC) $(CFLAGS) main.c mod1.o mod2.o -o prog4.3.3Предопределенные переменные и псевдопеременныеСуществуют определенные соглашения об именах переменных, причем некоторым переменным утилита make присваивает значения сама,если соответствующие значения не заданы явно.Вот некоторые традиционные имена переменных:• CC – команда вызова компилятора языка C;• CFLAGS – параметры для компилятора языка C;• CXX – команда вызова компилятора языка C++;• CXXFLAGS – параметры для компилятора языка C++;18 Причины выбора именно таких обозначений станут ясны из дальнейшего изложения.55• CPPFLAGS – параметры препроцессора (обычно сюда помещаютпредопределенные макропеременные);• LD – команда вызова системного линкера (редактора связей);• MAKE – команда вызова утилиты make со всеми параметрами.По умолчанию переменные CC, CXX, LD и MAKE имеют соответствующиезначения, справедливые для данной системы и в данной ситуации.
Значения остальных перечисленных переменных по умолчанию пусты.Таким образом, при написании Makefile из предыдущего параграфамы могли бы пропустить строку, в которой задается значение переменной CC, в надежде, что соответствующее значение переменная получитбез нашей помощи.Кроме таких переменных общего назначения, в каждой цели могутиспользоваться так называемые псевдопеременные.
Перечислим наиболее интересные из них:• $@ – имя текущей цели;• $< – имя первой цели из списка зависимостей;• $^ – весь список зависимостей.С использованием этих переменных мы можем переписать нашMakefile следующим образом:CFLAGS = -g -Wallmod1.o: mod1.c mod1.h$(CC) $(CFLAGS) -c $< -o $@mod2.o: mod2.c mod2.h$(CC) $(CFLAGS) -c $< -o $@prog: main.c mod1.o mod2.o$(CC) $(CFLAGS) $^ -o $@4.3.4Обобщенные целиКак можно заметить, в том варианте Makefile, который мы написали в конце предыдущего параграфа, правила для сборки обоих дополнительных модулей оказались совершенно одинаковыми. Можно пойти56дальше и задать одно обобщенное правило для построения объектного файла для любого модуля, написанного на языке C, исходный файлкоторого имеет имя с суффиксом .c, а заголовочный файл – имя с суффиксом .h:%.o: %.c %.h$(CC) $(CFLAGS) -c $< -o $@Если теперь задать список дополнительных модулей с помощью переменной, получим следующий вариант Makefile:OBJMODULES = mod1.o mod2.oCFLAGS = -g -Wall -ansi -pedantic%.o: %.c %.h$(CC) $(CFLAGS) -c $< -o $@prog: main.c $(OBJMODULES)$(CC) $(CFLAGS) $^ -o $@Теперь для добавления к программе нового модуля нам достаточно добавить имя его объектного файла к значению переменной OBJMODULES.Если перечисление модулей через имена объектных файлов представляется неестественным, можно заменить первую строку Makefileследующими двумя строками:SRCMODULES = mod1.c mod2.cOBJMODULES = $(SRCMODULES:.c=.o)Запись $(SRCMODULES:.c=.o) означает, что необходимо взять значение переменной SRCMODULES и в каждом входящем в это значение словезаменить суффикс .c на .o.4.3.5ПсевдоцелиУтилиту make можно использовать не только для построения файлов, но и для выполнения, вообще говоря, произвольных действий.
Добавим к нашему файлу две дополнительные цели:run: prog./progclean:rm -f *.o prog57Теперь по команде make run утилита make произведет, если необходимо, сборку нашей программы и запустит ее. С помощью же команды make clean мы можем очистить рабочую директорию от объектныхи исполняемых файлов (например, если нам понадобится произвестисборку программы с нуля).Такие цели обычно называют псевдоцелями, поскольку их имена необозначают имен создаваемых файлов.4.3.6Автоматическое отслеживание зависимостейВ более сложых проектах модули могут использовать заголовочныефайлы других модулей, что делает необходимой перекомпиляцию модуля при изменении заголовочного файла, не относящегося к этому модулю. Информацию о том, какой модуль от каких файлов зависит, можнозадать вручную, однако этот способ приведет к трудностям в большихпрограммах, поскольку программист при модификации исходных файлов может случайно забыть внести изменения в Makefile.Более правильным решением будет поручить отслеживание зависимостей компьютеру.
Утилита make позволяет наряду с обобщеннымправилом указать список зависимостей для построения конкретных модулей. Например:%.o: %.c$(CC) $(CFLAGS) -c $< -o $@mod1.o: mod1.c mod1.h mod2.h mod3.hВ этом случае для построения файла mod1.o будет использовано обобщенное правило (поскольку никаких команд в цели mod1.o мы не указали), но список зависимостей будет использован из цели mod1.o.Списки зависимостей можно построить с помощью компилятора.Чтобы получить строку, подобную последней строке вышеприведенногопримера, необходимо дать командуgcc -MM mod1.cЕсли результат выполнения такой команды перенаправить в файл, тоэтот файл можно будет включить в наш Makefile директивой include.Эта директива имеет специальную форму со знаком -, при использовании которой make не выдает ошибок, если файл не найден. Если использовать для файла зависимостей имя deps.mk, соответствующая директива будет выглядеть так:58-include deps.mkБолее того, если предусмотреть цель для генерации файла, включаемого такой директивой, например:deps.mk: $(SRCMODULES)$(CC) -MM $^ > $@утилита make, прежде чем начать построение любых других целей, будет пытаться построить включаемый файл.Отметим, что такое поведение нежелательно для псевдоцели clean,поскольку для очистки рабочей директории от мусора построение файлов зависимостей не нужно и только отнимает лишнее время.
Чтобы избежать этого, следует снабдить директиву -include условной конструкцией, исключающей эту строку из рассмотрения, если единстенной целью, заданной в командной строке, является цель clean. Это делается спомощью директивы ifneq и встроенной переменной MAKECMDGOALS:ifneq (clean, $(MAKECMDGOALS))-include deps.mkendifОкончательно Makefile будет выглядеть так:SRCMODULES = mod1.c mod2.cOBJMODULES = $(SRCMODULES:.c=.o)CFLAGS = -g -Wall -ansi -pedantic%.o: %.c %.h$(CC) $(CFLAGS) -c $< -o $@prog: main.c $(OBJMODULES)$(CC) $(CFLAGS) $^ -o $@ifneq (clean, $(MAKECMDGOALS))-include deps.mkendifdeps.mk: $(SRCMODULES)$(CC) -MM $^ > $@clean:rm -f *.o prog59Список литературы[1] С.
Баурн. Операционная система UNIX. М.:Мир, 1986.[2] А. М. Робачевский. Операционная система UNIX. Изд-во «BHV–Санкт-Петербург», Санкт-Петербург, 1997.60СодержаниеПредисловие . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Введение342 Пользовательские средства ОС Unix2.1 Первый сеанс . . . .
. . . . . . . . . . . . . . . . . . . . . . .2.2 Дерево каталогов. Работа с файлами . . . . . . . . . . . . .2.3 Редакторы текстов . . . . . . . . . . . . . . . . . . . . . . .2.3.1 Редактор vim . . . . . . . . . . . . . . . . . . . . . .2.3.2 Редактор joe . . . . . . . . . . . . . . . . . . . . . . .2.3.3 Встроенный редактор оболочки Midnight Commander2.4 Права доступа к файлам . . . . . . . . .
. . . . . . . . . . .2.5 Перенаправления ввода-вывода в интерпретаторе BourneShell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2.6 Процессы . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2.7 Выполнение в фоновом режиме . . . . . . .
. . . . . . . . .2.8 Электронная документация . . . . . . . . . . . . . . . . . .2.8.1 Команда man . . . . . . . . . . . . . . . . . . . . . . .2.8.2 Команда info . . . . . . . . . . . . . . . . . . . . . .2.9 Дополнительные возможности . . . . . . .
. . . . . . . . . .2.9.1 Командные файлы в Bourne Shell . . . . . . . . . . .2.9.2 Протоколирование сеанса работы (команда script) .2.9.3 Команды head и tail . . . . . . . . . . . . . . . . . . .2.9.4 Команда cat . . . . . . . . . . . . . . . . . . . . .
. .2.9.5 Команды wc и yes . . . . . . . . . . . . . . . . . . . .2.9.6 Команда grep . . . . . . . . . . . . . . . . . . . . . .2.9.7 Команда find . . . . . . . . . . . . . . . . . . . . . . .17192021222324242727293031333 Графическая оболочка X Window3.1 Основные понятия X Window .
. . . . . . . . . .3.2 Запуск X Window и выбор оконного менеджера3.3 Работа с классическими оконными менеджерами3.4 Работа в среде KDE . . . . . . . . . . . . . . . . .3838414346........................6679101314154 Инструментарий программиста484.1 Компилятор gcc/g++ . .
. . . . . . . . . . . . . . . . . . . . 484.2 Отладчик gdb . . . . . . . . . . . . . . . . . . . . . . . . . . 504.2.1 Пошаговое выполнение программы . . . . . . . . . . 50614.2.24.3Анализ причин аварийного завершения по coreфайлу . . . . . . . . . . .
. . . . . . . . . . . . . . . .4.2.3 Анализ причин зацикливания . . . . . . . . . . . . .Утилита make . . . . . . . . . . . . . . . . . . . . . . . . . .4.3.1 Простейший Makefile . . . . . . . . . . . . . . . . . .4.3.2 Переменные . . . . . .
. . . . . . . . . . . . . . . . .4.3.3 Предопределенные переменные и псевдопеременные4.3.4 Обобщенные цели . . . . . . . . . . . . . . . . . . . .4.3.5 Псевдоцели . . . . . . . . . . . . . . . . . . . . . . . .4.3.6 Автоматическое отслеживание зависимостей . . . .Список литературы52525353545556575859.