
- •Компиляторы, библиотеки и инструментальные средства программирования
- •Получение информации: info
- •Двоичные форматы elf и a.Out
- •Другие компиляторы: Паскаль, Ада, Лисп и Фортран
- •Создание и использование библиотек: статических, совместно используемых и динамических
- •Символический отладчик gbd
- •Программа xxgdb
- •Инструментальные средства программирования
- •Инструментальные средства разработки
- •Утилита make
- •Система контроля версий: rcs
- •Система параллельных версий: cvs
- •Интерактивные справочники по приложениям: оперативные руководства
- •Файлы документации утилиты man
Инструментальные средства разработки
Приложение — это исполняемая программа, созданная программистом с помощью одного из многих языков программирования. Система Linux предоставляет несколько утилит, с помощью которых программист может управлять разработкой приложения. Важнейшей из них является утилита make. Интерфейс утилиты make упрощает компиляцию программы. Утилита RCS позволяет обеспечить контроль за внесенными в программу изменениями. Она организует изменения в виде последовательных версий программы, которые могут быть сохранены, а затем загружены. При создании интерактивной документации для разрабатываемого программного обеспечения можно воспользоваться утилитой man. Все перечисленные выше утилиты являются мощными и довольно сложными в применении инструментальными средствами.
Утилита make
Очень часто приходится работать с программами, включающими несколько файлов исходного кода. При разработке и модификации исходного кода приходится вновь и вновь компилировать программу. Однако на самом деле в компиляции нуждаются лишь те файлы, которые были изменены. Затем редактор связей связывает только что созданные файлы объектного кода с ранее созданными и формирует новый исполняемый файл. Благодаря тому что компилируются заново только некоторые из файлов исходного кода, резко сокращается время выполнения компилятора. При создании очередной версии исполняемой программы не требуется заново компилировать все файлы исходного кода.
В большой программе, включающей множество файлов исходного кода, очень трудно отследить, какие файлы были изменены и нуждаются в компиляции, а какие достаточно обработать редактором связей. Утилита make выполняет эти операции автоматически. Она предназначена для среды разработки, в которой различные файлы исходного кода, составляющие программу, постоянно изменяются. Утилита make отслеживает, какие файлы исходного кода были изменены, а какие — нет. Затем она компилирует только те из них, в которые были внесены изменения, связывает их с остальными файлами, содержащими объектный код, и создает новый исполняемый файл. В следующем примере программист вводит команду make в командной строке для вызова утилиты make. После этого компилируются измененные файлы, затем создается новый исполняемый файл. При этом утилита make отображает все выполняемые команды Linux.
$ make
gcc -с main.с
gcc -с io.c
gcc main.о io.o
С целью лучшего понимания принципов функционирования утилиты make представьте себе, что она использует отметки времени, соответствующие каждому файлу исходного кода. При создании или обновлении файла исходного кода операционная система Linux устанавливает новое значение отметки времени. Если файл был создан в 1:00, то отметка времени имеет значение 1:00. Если затем файл был изменен в 6:00, то в отметке времени записывается новое значение, 6:00. При компиляции программы повторно нужно компилировать только те файлы, которые были изменены. Поскольку изменения в любом файле связаны с обновлением отметок времени, то значения этих отметок могут быть использованы для определения того, какие файлы должны быть откомпилированы. В результате утилита make может определить, какие файлы должны быть откомпилированы, и выбрать для компиляции только эти файлы.
Строка зависимостей указывает отношения между файлами (утилита make оперирует в терминах зависимостей). Файл исходного кода используется для создания файла объектного кода, который в дальнейшем применяется для создания выполняемой программы. Очевидно, что программа зависит от файла объектного кода, который, в свою очередь, зависит от файла исходного кода. В строке зависимостей необходимо указать отношения зависимости между файлом исходного кода и файлом объектного кода. В другой строке зависимостей необходимо указать отношения зависимостей между исполняемым файлом и всеми файлами объектных кодов, которые используются при его создании.
Строку зависимостей можно рассматривать как своего рода логический оператор. Отношение зависимости в этом случае является условным выражением. Если некоторый файл объектного кода зависит от файла исходного кода, а последний файл был недавно был изменен, то условие проверки истинно, и такой файл будет компилироваться. Но синтаксис строки зависимостей более сложен, чем обычное условное выражение. Строка зависимостей состоит из трех частей: целевой файл, список зависимых файлов и команда Linux. Если какой-то из файлов изменен раньше, чем целевой файл, то выполняется команда Linux. Целевой файл и файлы, от которых он зависит, записываются в одной строке и разделяются двоеточием. Команду Linux можно либо поместить в той же строке, отделив ее от перечня файлов с помощью точки с запятой, либо указать ее в следующей строке после символа табуляции. В одной строке может быть введено несколько команд Linux. В этом случае между ними нужно ставить точки с запятой. При вводе команды с новой строки в начале последней должен находиться символ табуляции. Об окончании строки зависимостей свидетельствует следующая за ней пустая строка. В указанных ниже примерах производится вызов компилятора gcc, выполняется компиляция файлов исходного кода или компоновка файлов объектного кода. Синтаксис строки зависимостей выглядит следующим образом:
целевой файл : зависимые файлы ; команда Linux пустая строка
целевой файл : зависимые файлы tab команда Linux пустая строка
В следующем файле makefile будут записаны строки зависимостей для программы на языке С, состоящей из двух файлов исходного кода, main.c и io.c. В подобной программе, состоящей из двух файлов, на самом деле нужно обрабатывать пять файлов. Для каждого файла .с существует соответствующий ему файл .о. Кроме того, существует исполняемый файл a.out. Строки зависимостей для файла makefile описывают зависимости для каждого из имеющихся файлов. Файлы объектного кода (.о) зависят от файлов исходного кода (.с). Исполняемый файл a.out зависит от нескольких файлов объектного кода (.о). В этом примере исполняемый файл a.out зависит от двух файлов объектного кода — main.о и io.o. Каждый файл с объектного кода зависит, в свою очередь, от соответствующего файла исходного кода: main.o — от main.c, a io.o — от io.c.
В файле makefile необходимо указать три строки зависимостей, для файлов a.out, main.o и io.o соответственно. Заметьте, что операции связывания и компиляции программы разнесены по разным строкам зависимостей. Команда Linux для целевого файла a.out связывает два файла объектного кода с целью создания нового исполняемого файла. В результате вызывается компилятор gcc совместно с файлами объектного кода (.о), а запускается исключительно редактор связей. Команды Linux для целевых файлов main.o и io.o выполняют только компиляцию, в результате чего создаются файлы исходного кода (.о). Параметр -с, используемый совместно с компилятором gcc, определяет, что компоновку выполнять не требуется. В этом случае достаточно ограничиться только компиляцией и созданием файлов объектного кода для указанных файлов исходного кода.
makefile
a.out : main.o io.o gcc main.o io.o
main.o : main.c gcc -c main.c
io.o : io.с
gcc -c io.c
Можно также создать строку зависимостей для выполнения специальных операций, таких как печать файлов или инсталляция, приложения. Многие из программных пакетов, создаваемых пользователем с помощью утилиты make, предназначаются для установки прикладных программ на компьютере пользователя.
$ make install